A PHP Error was encountered

Severity: Warning

Message: Undefined array key 1

Filename: geshi/geshi.php

Line Number: 3424

Backtrace:

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3424
Function: _error_handler

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3081
Function: parse_non_string_part

File: /var/www/clients/client2/web23/web/paste/application/libraries/Process.php
Line: 45
Function: parse_code

File: /var/www/clients/client2/web23/web/paste/application/models/Pastes.php
Line: 591
Function: syntax

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 493
Function: getReplies

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Undefined array key 1

Filename: geshi/geshi.php

Line Number: 3424

Backtrace:

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3424
Function: _error_handler

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3081
Function: parse_non_string_part

File: /var/www/clients/client2/web23/web/paste/application/libraries/Process.php
Line: 45
Function: parse_code

File: /var/www/clients/client2/web23/web/paste/application/models/Pastes.php
Line: 591
Function: syntax

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 493
Function: getReplies

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Undefined array key 1

Filename: geshi/geshi.php

Line Number: 3424

Backtrace:

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3424
Function: _error_handler

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3081
Function: parse_non_string_part

File: /var/www/clients/client2/web23/web/paste/application/libraries/Process.php
Line: 45
Function: parse_code

File: /var/www/clients/client2/web23/web/paste/application/models/Pastes.php
Line: 591
Function: syntax

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 493
Function: getReplies

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Undefined array key 1

Filename: geshi/geshi.php

Line Number: 3424

Backtrace:

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3424
Function: _error_handler

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3081
Function: parse_non_string_part

File: /var/www/clients/client2/web23/web/paste/application/libraries/Process.php
Line: 45
Function: parse_code

File: /var/www/clients/client2/web23/web/paste/application/models/Pastes.php
Line: 591
Function: syntax

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 493
Function: getReplies

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Undefined array key 1

Filename: geshi/geshi.php

Line Number: 3424

Backtrace:

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3424
Function: _error_handler

File: /var/www/clients/client2/web23/web/paste/application/libraries/geshi/geshi.php
Line: 3081
Function: parse_non_string_part

File: /var/www/clients/client2/web23/web/paste/application/libraries/Process.php
Line: 45
Function: parse_code

File: /var/www/clients/client2/web23/web/paste/application/models/Pastes.php
Line: 591
Function: syntax

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 493
Function: getReplies

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Cannot modify header information - headers already sent by (output started at /var/www/clients/client2/web23/web/paste/system/core/Exceptions.php:284)

Filename: view/rss.php

Line Number: 2

Backtrace:

File: /var/www/clients/client2/web23/web/paste/themes/bootstrap/views/view/rss.php
Line: 2
Function: header

File: /var/www/clients/client2/web23/web/paste/application/core/MY_Loader.php
Line: 147
Function: include

File: /var/www/clients/client2/web23/web/paste/application/core/MY_Loader.php
Line: 33
Function: _ci_load

File: /var/www/clients/client2/web23/web/paste/application/controllers/Main.php
Line: 496
Function: view

File: /var/www/clients/client2/web23/web/paste/index.php
Line: 315
Function: require_once

Untitled - MLX Paste Untitled - MLX Paste https://mlx.su/paste/ en Untitled https://mlx.su/paste/view/639c4ae8 Sun, 26 Oct 2025 23:07:10 +0300 vtk88com https://mlx.su/paste/view/639c4ae8
  1. define('core/models/Post',[
  2.     'jquery',
  3.     'underscore',
  4.     'backbone',
  5.     'moment',
  6.  
  7.     'core/config/urls',
  8.  
  9.     'core/api',
  10.     'core/strings',
  11.     'core/time',
  12.     'core/utils',
  13.     'core/utils/html',
  14.     'core/advice',
  15.     'remote/config',
  16.  
  17.     'core/models/mixins',
  18.  
  19.     'core/collections/VotersUserCollection',
  20.     'core/collections/VoteCollection',
  21. ], function (
  22.     $,
  23.     _,
  24.     Backbone,
  25.     moment,
  26.  
  27.     urls,
  28.  
  29.     api,
  30.     strings,
  31.     time,
  32.     utils,
  33.     htmlUtils,
  34.     advice,
  35.     config,
  36.  
  37.     modelMixins,
  38.  
  39.     VotersUserCollection,
  40.     VoteCollection
  41. ) {
  42.     'use strict';
  43.  
  44.     var VOTE_RATE_LIMIT = 1000; // 1s rate limit on voting
  45.     var LAST_VOTE = 0;
  46.     var MAX_POST_LENGTH = 25000;
  47.  
  48.     var acquireVoteLock = function () {
  49.         var now = $.now();
  50.         if (now - LAST_VOTE < VOTE_RATE_LIMIT) {
  51.             return false;
  52.         }
  53.         LAST_VOTE = now;
  54.         return true;
  55.     };
  56.  
  57.     var gettext = strings.get;
  58.  
  59.     var Post = Backbone.Model.extend({
  60.         votersCollectionClass: VotersUserCollection,
  61.  
  62.         defaults: function () {
  63.             return {
  64.                 createdAt: moment().format(time.ISO_8601),
  65.                 editableUntil: moment().add(config.max_post_edit_days, 'days').format(time.ISO_8601),
  66.                 dislikes: 0,
  67.                 isApproved: true, // Assume approved
  68.                 isDeleted: false,
  69.                 isEdited: false,
  70.                 isFlagged: false,
  71.                 isFlaggedByUser: false,
  72.                 isHighlighted: false,
  73.                 isRealtime: false,
  74.                 isImmediateReply: false,
  75.                 isMinimized: null,
  76.                 hasMedia: false,
  77.                 message: null,
  78.                 raw_message: null,
  79.                 likes: 0,
  80.                 media: [],
  81.                 parent: null,
  82.                 points: 0,
  83.                 depth: 0,
  84.                 userScore: 0,
  85.                 rating: null,
  86.             };
  87.         },
  88.  
  89.         initialize: function () {
  90.             this.votes = new VoteCollection();
  91.         },
  92.  
  93.         messageText: function () {
  94.             var msg = this.get('message');
  95.             return msg && htmlUtils.stripTags(msg);
  96.         },
  97.  
  98.         permalink: function (thread, useCurrentPage) {
  99.             var id = this.id;
  100.             if (!(id && thread)) {
  101.                 return '';
  102.             }
  103.             // Favor currentUrl if useCurrentPage is not false and always fallback to permalink
  104.             var baseUrl = useCurrentPage !== false &&  // default to true
  105.                           thread.currentUrl || thread.permalink();
  106.             var urlTool = window.document.createElement('a');
  107.             urlTool.href = baseUrl;
  108.             urlTool.hash = '#comment-' + id;
  109.  
  110.             return urlTool.href;
  111.         },
  112.  
  113.         shortLink: function () {
  114.             return urls.shortener + '/p/' + Number(this.id).toString(36);
  115.         },
  116.  
  117.         twitterText: function (permalink) {
  118.             var charsRemaining = 140;
  119.  
  120.             var author = this.author.get('name') || this.author.get('username');
  121.             charsRemaining -= author.length + 3;  // +3 for space dash space before author
  122.             charsRemaining -= permalink.length + 1;  // +1 for space before url
  123.             charsRemaining -= 2;  // For the quotation marks
  124.  
  125.             var text = utils.niceTruncate(this.messageText(), charsRemaining);
  126.  
  127.             return '"' + text + '" \u2014 ' + author;
  128.         },
  129.  
  130.         toJSON: function (options) {
  131.             var json = Backbone.Model.prototype.toJSON.call(this);
  132.             if (options) {
  133.                 var session = options.session;
  134.                 var thread = options.thread;
  135.  
  136.                 json.canBeEdited = this.canBeEdited(session, thread);
  137.                 json.canBeRepliedTo = this.canBeRepliedTo(session, thread);
  138.                 json.canBeShared = this.canBeShared();
  139.                 json.permalink = this.permalink(thread);
  140.             }
  141.  
  142.             json.shortLink = this.shortLink();
  143.             json.isMinimized = this.isMinimized();
  144.             json.plaintext = this.messageText();
  145.  
  146.             // Add relativeCreatedAt for display in the UI (e.g., "Comment created 1 hour ago")
  147.             json.relativeCreatedAt = this.getRelativeCreatedAt();
  148.             // formattedCreatedAt is nice absolute time (e.g. "Jan 1, 2008, 12:00 pm")
  149.             json.formattedCreatedAt = this.getFormattedCreatedAt();
  150.             // expose cid to make it easier to find the model in collections later
  151.             json.cid = this.cid;
  152.  
  153.             return json;
  154.         },
  155.  
  156.         /**
  157.          * Is this post visible to all users?
  158.          * @returns {boolean}
  159.          */
  160.         isPublic: function () {
  161.  
  162.             // Posts that are highlighted or sponsored are always public.
  163.             if (this.get('isHighlighted') || this.get('isSponsored')) {
  164.                 return true;
  165.             }
  166.             // Otherwise, if they are deleted they are definitely *not* public.
  167.             if (this.get('isDeleted')) {
  168.                 return false;
  169.             }
  170.             // Finally, if they are approved then they are public.
  171.             return this.get('isApproved');
  172.         },
  173.  
  174.         isMinimized: function () {
  175.             // If comment has been highlighted by a moderator, it is NOT minimized
  176.             // (highlighting is implicit approval by the moderator)
  177.             if (this.get('isHighlighted')) {
  178.                 return false;
  179.             }
  180.             // If the comment has been explicitly expanded (unminimized) by
  181.             // the user, it is NOT minimized
  182.             if (this.get('isMinimized') === false) {
  183.                 return false;
  184.             }
  185.             return !this.get('isApproved');
  186.         },
  187.  
  188.         // These methods are stubbed out because they rely on the Session object,
  189.         // which hasn't been ported to next-core yet. They still exist, and return
  190.         // sensible default values, because they're called from Post.prototype.toJSON.
  191.         //
  192.         // NOTE: Until Session is ported to next-core, any applications using Post w/
  193.         //       sessions will need to override these prototype methods
  194.  
  195.         isAuthorSessionUser: function () { return false; },
  196.  
  197.         canBeEdited: function () { return false; },
  198.  
  199.         canBeRepliedTo: function () { return false; },
  200.  
  201.         canBeShared: function () { return false; },
  202.  
  203.         validateMessage: function (attrs) {
  204.             if (_.isString(attrs.raw_message)) {
  205.                 if (attrs.raw_message === '') {
  206.                     return gettext('Comments can\'t be blank.');
  207.                 }
  208.                 // eslint-disable-next-line no-magic-numbers
  209.                 if (attrs.raw_message.length < 2) {
  210.                     return gettext('Comments must have at least 2 characters.');
  211.                 }
  212.                 if (attrs.raw_message.length > MAX_POST_LENGTH) {
  213.                     return strings.interpolate(gettext('Comments can\'t be longer than %(maxLength)s characters (currently %(currentLength)s characters).'), {
  214.                         maxLength: MAX_POST_LENGTH,
  215.                         currentLength: attrs.raw_message.length,
  216.                     });
  217.                 }
  218.             }
  219.         },
  220.  
  221.         validate: function (attrs) {
  222.             if (this.id || attrs.id) {
  223.                 return;
  224.             }
  225.             var messageError = this.validateMessage(attrs);
  226.             if (messageError) {
  227.                 return messageError;
  228.             }
  229.             if (attrs.author_email) {
  230.                 attrs.author_email = $.trim(attrs.author_email);
  231.             }
  232.             if (attrs.author_name) {
  233.                 attrs.author_name = $.trim(attrs.author_name);
  234.             }
  235.             if (attrs.author_email === '' && attrs.author_name === '') {
  236.                 return gettext('Please sign in or enter a name and email address.');
  237.             }
  238.             else if (attrs.author_email === '' || attrs.author_name === '') {
  239.                 return gettext('Please enter both a name and email address.');
  240.             }
  241.             else if (attrs.author_name && attrs.author_name.length && !attrs.age_declaration) {
  242.                 return gettext('Please confirm that you are 18 years of age or older.');
  243.             }
  244.  
  245.             // Simple client-side email validation. This is obviously not a complete
  246.             // regex, but it should catch 90+% of errors. We can catch the rest on
  247.             // the server.
  248.             if (_.isString(attrs.author_email) && !this.validateEmail(attrs.author_email)) {
  249.                 return gettext('Invalid email address format.');
  250.             }
  251.         },
  252.  
  253.         validateEmail: function (email) {
  254.             return utils.validateEmail(email);
  255.         },
  256.  
  257.         report: function (reason) {
  258.             this.set('isFlagged', true);
  259.  
  260.             var data = {
  261.                 post: this.id,
  262.             };
  263.  
  264.             if (reason) {
  265.                 data.reason = reason;
  266.             }
  267.             api.call('posts/report.json', {
  268.                 data: data,
  269.                 method: 'POST',
  270.             });
  271.         },
  272.  
  273.         _highlight: function (shouldBeHighlighted) {
  274.             this.set('isHighlighted', shouldBeHighlighted);
  275.             api.call('posts/' + (shouldBeHighlighted ? 'highlight' : 'unhighlight') + '.json', {
  276.                 data: {
  277.                     post: this.id,
  278.                 },
  279.                 method: 'POST',
  280.             });
  281.         },
  282.  
  283.         highlight: function () {
  284.             this._highlight(true);
  285.         },
  286.  
  287.         unhighlight: function () {
  288.             this._highlight(false);
  289.         },
  290.  
  291.         /**
  292.          * Override for post models that don't store the thread id
  293.          * in the thread attr
  294.          *
  295.          * @returns {string} id of thread.
  296.          */
  297.         getThreadId: function () {
  298.             return this.get('thread');
  299.         },
  300.  
  301.         getUpvotersUserCollection: _.memoize(function () {
  302.             var CollectionClass = this.votersCollectionClass;
  303.  
  304.             return new CollectionClass(undefined, {
  305.                 postId: this.id,
  306.                 threadId: this.getThreadId(),
  307.             });
  308.         }, function () {
  309.             return [this.id, '1'].join('');
  310.         }),
  311.  
  312.         getDownvotersUserCollection: _.memoize(function () {
  313.             var CollectionClass = this.votersCollectionClass;
  314.  
  315.             return new CollectionClass(undefined, {
  316.                 postId: this.id,
  317.                 threadId: this.getThreadId(),
  318.             });
  319.         }, function () {
  320.             return [this.id, '-1'].join('');
  321.         }),
  322.  
  323.         // This function does score calculations and increments/decrements
  324.         // counters. We can't just bind it to the 'add' event because
  325.         // we want to call _vote before making a network request and adding
  326.         // a freshly created vote to a collection. (sad face)
  327.  
  328.         _vote: function (vote, score, voter) {
  329.             var delta = vote - score;
  330.             var updates = {
  331.                 likes: this.get('likes'),
  332.                 dislikes: this.get('dislikes'),
  333.                 points: this.get('points'),
  334.             };
  335.  
  336.             // If the vote is unchanged from the user's previous vote,
  337.             // so ignore - there's nothing to do
  338.  
  339.             if (delta === 0) {
  340.                 return delta;
  341.             }
  342.             // Update likes and dislikes. This is tricky because a
  343.             // switched vote requires updating *both* attributes, whereas
  344.             // a new vote only touches one.
  345.  
  346.             if (vote > 0) {
  347.                 updates.likes += vote;
  348.                 updates.dislikes += score;
  349.             } else if (vote < 0) {
  350.                 updates.dislikes -= vote;
  351.                 updates.likes -= score;
  352.             } else if (score > 0) {
  353.                 updates.likes -= score;
  354.             } else {
  355.                 updates.dislikes += score;
  356.             }
  357.  
  358.             updates.points += delta;
  359.  
  360.             // add user into correct collection and remove from the other one
  361.             if (voter) {
  362.                 if (vote === 1) {
  363.                     this.getUpvotersUserCollection().add(voter);
  364.                     this.getDownvotersUserCollection().remove(voter);
  365.                 } else {
  366.                     this.getDownvotersUserCollection().add(voter);
  367.                     this.getUpvotersUserCollection().remove(voter);
  368.                 }
  369.             }
  370.  
  371.  
  372.             // All these values should be updated at once to prevent any "half-baked"
  373.             // data to trigger the view or any other thing that listens on change
  374.             // events of these properties.
  375.             this.set(updates);
  376.  
  377.             return delta;
  378.         },
  379.  
  380.         // Vote on a post, taking into account any earlier votes
  381.         // made by the current user (via the userScore attribute).
  382.         //
  383.         // @params vote {Integer} Can be one of -1, 0, or 1
  384.  
  385.         vote: function (vote) {
  386.             // Rate limit voting on the Post's public vote interface.
  387.             // We don't rate limit on the private interface because that
  388.             // is used for realtime votes which could come in faster than
  389.             // the rate limit.
  390.             if (!acquireVoteLock()) {
  391.                 return 0;
  392.             }
  393.             var self = this;
  394.             var delta = self._vote(vote, self.get('userScore'));
  395.  
  396.             if (delta === 0) {
  397.                 return;
  398.             }
  399.  
  400.             var newNumLikesReceived = self.author ? self.author.get('numLikesReceived') : 0;
  401.             if (self.get('userScore') === 1) {
  402.                 newNumLikesReceived -= 1;
  403.             } else if (vote === 1) {
  404.                 newNumLikesReceived += 1;
  405.             }
  406.  
  407.             self.set('userScore', vote);
  408.             api.call('posts/vote.json', {
  409.                 data: {
  410.                     post: self.id,
  411.                     vote: vote,
  412.                 },
  413.                 method: 'POST',
  414.                 success: function (data) {
  415.                     // We have merge:true in order to update existing vote instances,
  416.                     // so when the same vote will come from realtime it won't be recognized
  417.                     // as a change.
  418.                     self.votes.add({ id: data.response.id, score: vote }, { merge: true });
  419.  
  420.                     if (self.author) {
  421.                         self.author.set('numLikesReceived', newNumLikesReceived);
  422.                     }
  423.                 },
  424.             });
  425.         },
  426.  
  427.         _delete: function () {
  428.             this.set({
  429.                 isApproved: false,
  430.                 isDeleted: true,
  431.             });
  432.  
  433.             return api.call('posts/remove.json', {
  434.                 data: { post: this.id },
  435.                 method: 'POST',
  436.             });
  437.         },
  438.  
  439.         spam: function () {
  440.             this.set({
  441.                 isApproved: false,
  442.                 isDeleted: true,
  443.                 isSpam: true,
  444.             });
  445.  
  446.             this.trigger('spam');
  447.  
  448.             api.call('posts/spam.json', {
  449.                 data: { post: this.id },
  450.                 method: 'POST',
  451.             });
  452.         },
  453.  
  454.         _create: function (model, options) {
  455.             var self = this;
  456.             var attrs = model.attributes;
  457.             var params = {
  458.                 thread: attrs.thread,
  459.                 message: attrs.raw_message,
  460.                 rating: attrs.rating,
  461.             };
  462.  
  463.             if (attrs.parent) {
  464.                 params.parent = attrs.parent;
  465.             }
  466.             // Anon posting
  467.             if (attrs.author_name) {
  468.                 params.author_name = attrs.author_name;
  469.                 params.author_email = attrs.author_email;
  470.                 params.age_declaration = attrs.age_declaration;
  471.             }
  472.  
  473.             return api.call('posts/create.json', {
  474.                 data: params,
  475.                 method: 'POST',
  476.                 success: function (data) {
  477.                     self.set(data.response);
  478.                     if (options.success) {
  479.                         options.success();
  480.                     }
  481.                 },
  482.                 error: options.error,
  483.             });
  484.         },
  485.  
  486.         _update: function (model, options) {
  487.             var self = this;
  488.             var attrs = model.attributes;
  489.  
  490.             var params = {
  491.                 post: attrs.id,
  492.                 message: attrs.raw_message,
  493.                 rating: attrs.rating,
  494.             };
  495.  
  496.  
  497.             return api.call('posts/update.json', {
  498.                 data: params,
  499.                 method: 'POST',
  500.                 success: function (data) {
  501.                     self.set(data.response);
  502.                     if (options.success) {
  503.                         options.success();
  504.                     }
  505.                 },
  506.                 error: options.error,
  507.             });
  508.         },
  509.  
  510.         _read: function (_model, options) {
  511.             var self = this;
  512.             options = options || {};
  513.  
  514.             return api.call('posts/details.json', {
  515.                 data: { post: self.id },
  516.                 method: 'GET',
  517.                 success: function (data) {
  518.                     // When highlighting and unhighlighting posts in quick succession,
  519.                     // sometimes we send a cached version of the model that is unhighlighted.
  520.                     // If that happens, we fix that here in the response
  521.                     if (options.isHighlighted && !data.response.isHighlighted) {
  522.                         data.response.isHighlighted = true;
  523.                     }
  524.                     self.set(data.response);
  525.                     if (options.success) {
  526.                         options.success();
  527.                     }
  528.                 },
  529.                 error: options.error,
  530.             });
  531.         },
  532.  
  533.         sync: function (method, model, options) {
  534.             options = options || {};
  535.  
  536.             var error = options.error;
  537.             if (error) {
  538.                 options.error = function (xhr) {
  539.                     var response = {};
  540.                     try {
  541.                         response = JSON.parse(xhr.responseText);
  542.                     } catch (err) {
  543.                         // ignore
  544.                     }
  545.  
  546.                     error(response);
  547.                 };
  548.             }
  549.  
  550.             switch (method) {
  551.             case 'create':
  552.                 return this._create(model, options);
  553.             case 'update':
  554.                 return this._update(model, options);
  555.             case 'delete':
  556.                 return this._delete();
  557.             case 'read':
  558.                 return this._read(model, options);
  559.             default:
  560.                 return null;
  561.             }
  562.         },
  563.  
  564.         /**
  565.          * Generate key for storing draft posts in local storage.
  566.          * A draft post is one that has not yet been saved on the back
  567.          * end.
  568.          *
  569.          * Example: drafts:thread:1:parent:0
  570.          *
  571.          * @returns {string} key name
  572.          */
  573.         storageKey: function () {
  574.             // Only allow draft posts to be stored in local storage
  575.             if (!this.isNew()) {
  576.                 return;
  577.             }
  578.             if (!this.getThreadId()) {
  579.                 return;
  580.             }
  581.             return ['drafts', 'thread', this.getThreadId(), 'parent', this.get('parent') || 0].join(':');
  582.         },
  583.     }, {
  584.         /**
  585.          * Get an escaped approximation of how a raw message
  586.          * will be formatted by our API.
  587.          *
  588.          * This method currently _only_ formats newlines into
  589.          * <p> and <br> tags.
  590.          *     TODO: make this method handle mentions and various
  591.          *           supported tags.
  592.          *
  593.          * @params {string} text Text to format.
  594.          * @returns {string} Escaped and <p> <br> message.
  595.          */
  596.         formatMessage: (function () {
  597.  
  598.             var paragraphReg = /(?:\r\n|\r|\n){2,}/;
  599.             var lineReg = /\r\n|\r|\n/;
  600.  
  601.             return function (text) {
  602.  
  603.                 // Any series of two or more newlines is a paragraph.
  604.                 // Use `compact()` to filter empty values.
  605.                 var paragraphs = _.chain(text.split(paragraphReg))
  606.                     .compact()
  607.                     .value();
  608.  
  609.                 var html = _.map(paragraphs, function (paragraph) {
  610.  
  611.                     // Single newlines are spaced with <br> tags.
  612.                     // Use `compact()` to filter empty values.
  613.                     return _.chain(paragraph.split(lineReg))
  614.                         .compact()
  615.  
  616.                         // Escape text to prevent users from
  617.                         // accidentally XXSing themselves.
  618.                         .map(_.escape)
  619.                         .join('<br>')
  620.                         .value();
  621.  
  622.                 }).join('</p><p>');
  623.  
  624.                 return '<p>' + html + '</p>';
  625.             };
  626.  
  627.         })(),
  628.     });
  629.  
  630.     //
  631.     // Applied mixins
  632.     //
  633.  
  634.     modelMixins.withCreatedAt.call(Post.prototype);
  635.     advice.withAdvice.call(Post.prototype);
  636.  
  637.     //
  638.     // Optional mixins
  639.     //
  640.  
  641.     /**
  642.      * Adds `author` as a sub-model of Post
  643.      */
  644.  
  645.     Post.withAuthor = function (UserModel) {
  646.         this.around('set', function (set, key, val, options) {
  647.             var attrs;
  648.  
  649.             // eslint-disable-next-line eqeqeq, no-eq-null
  650.             if (key == null) {
  651.                 return this;
  652.             }
  653.             // Handle both `"key", value` and `{key: value}` -style arguments.
  654.             if (typeof key === 'object') {
  655.                 attrs = key;
  656.                 options = val;
  657.             } else {
  658.                 attrs = {};
  659.                 attrs[key] = val;
  660.             }
  661.  
  662.             var author = attrs.author;
  663.  
  664.             if (author) {
  665.                 // Convert 'author' attributes to a model instance. Attributes
  666.                 // should never contain nested properties, but that's what the API
  667.                 // returns, so we convert it here.
  668.                 //
  669.                 // NOTE: This kind of stuff is made easier with a Backbone plugin
  670.                 //       called Backbone-Relational, but I'm not sure we need it
  671.                 //       just yet. (https://github.com/PaulUithol/Backbone-relational)
  672.  
  673.                 if (_.isString(author) || _.isNumber(author)) {
  674.                     var id = author;
  675.                     author = {};
  676.                     author[UserModel.prototype.idAttribute || 'id'] = id;
  677.                 }
  678.  
  679.                 // Usually the Post will have access to the PostCollection,
  680.                 // but when the sort-order changes we need to grab the collection from the author
  681.                 var collection = this.collection || (this.author && this.author.collection);
  682.  
  683.                 // Convert the forum badge IDs on the post author to forum badge objects
  684.                 var forum = collection && collection.thread && collection.thread.forum;
  685.                 if (this.author && this.author.get('badges').length && this.author.get('badges')[0].id) {
  686.                     // If the author already has the forum badge objects
  687.                     author.badges = this.author.get('badges');
  688.                 } else if (forum && forum.get('badges') && author.badges) {
  689.                     var badges = [];
  690.                     var badgeIds = author.badges || [];
  691.                     var forumBadges = forum.get('badges');
  692.                     badgeIds.forEach(function (badgeId) {
  693.                         if (forumBadges[badgeId]) {
  694.                             badges.push(forumBadges[badgeId]);
  695.                         }
  696.                     });
  697.                     author.badges = badges;
  698.                 }
  699.  
  700.                 this.author = new UserModel(author);
  701.  
  702.                 // This is the standard event structure for when a related model is
  703.                 // set (used in home).
  704.                 this.trigger('changeRelated:author');
  705.  
  706.                 delete attrs.author;
  707.             }
  708.  
  709.             return set.call(this, attrs, options);
  710.         });
  711.  
  712.         this.around('toJSON', function (toJSON) {
  713.             var json = toJSON.apply(this, _.rest(arguments));
  714.  
  715.             if (this.author) {
  716.                 json.author = this.author.toJSON();
  717.             }
  718.             return json;
  719.         });
  720.     };
  721.  
  722.     /**
  723.      * Adds `media` as a sub-collection of Post
  724.      *
  725.      * @param {Object} MediaCollection - a MediaCollection class that encapsulates media attributes
  726.      * @returns {undefined}
  727.      */
  728.     Post.withMediaCollection = function (MediaCollection) {
  729.         this.after('set', function (attrs) {
  730.             if (attrs && typeof attrs !== 'string') {
  731.  
  732.                 // Convert 'media' attribute into collection
  733.                 if (!_.isUndefined(attrs.media)) {
  734.                     // Populate media collection
  735.                     if (this.media) {
  736.                         this.media.reset(attrs.media);
  737.                     } else {
  738.                         this.media = new MediaCollection(attrs.media);
  739.                     }
  740.                     delete attrs.media;
  741.                 }
  742.             }
  743.         });
  744.  
  745.         this.around('toJSON', function (toJSON) {
  746.             var json = toJSON.apply(this, _.rest(arguments));
  747.  
  748.             if (this.media) {
  749.                 json.media = this.media.toJSON();
  750.             }
  751.             return json;
  752.         });
  753.     };
  754.  
  755.     return Post;
  756. });
  757. // https://c.disquscdn.com/next/next-core/core/models/Post.js
  758.  
]]>
Re: Untitled https://mlx.su/paste/view/ca8c9a89 Sun, 22 Jun 2025 00:33:57 +0300 memoforce review https://mlx.su/paste/view/ca8c9a89
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/2ad98502 Fri, 16 May 2025 14:50:22 +0300 the brain song reviews and compl https://mlx.su/paste/view/2ad98502
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/246ff470 Tue, 13 May 2025 12:22:10 +0300 win88 https://mlx.su/paste/view/246ff470
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/19355554 Sun, 11 May 2025 23:57:38 +0300 free sugar pro scam https://mlx.su/paste/view/19355554
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/a0293061 Sat, 10 May 2025 20:50:46 +0300 mitolyn vs lipozem 2025 https://mlx.su/paste/view/a0293061
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/e6ddc01a Fri, 09 May 2025 21:17:12 +0300 Perl Macaw https://mlx.su/paste/view/e6ddc01a
  1.  là nhà cái trực tuyến uy tín hàng đầu Việt Nam, hoạt động từ năm 2012 với sự hỗ trợ độc quyền từ CLB Manchester United. Được ủy quyền bởi Công ty Giải trí First Cagayan, TK88 cung cấp danh mục trò chơi phong phú, bao gồm cá cược thể thao, casino trực tuyến, xổ số, game bài và slot games hấp dẫn.
  2. Đội ngũ hỗ trợ chuyên nghiệp hoạt động 24/7, đảm bảo giải đáp mọi thắc mắc nhanh chóng và tận tâm. Với công nghệ tiên tiến và môi trường cá cược hiện đại, vtk88 mang đến trải nghiệm giải trí chất lượng cao, an toàn và đáng tin cậy.
  3. Tham gia  để tận hưởng những khoảnh khắc thư giãn đỉnh cao cùng các dịch vụ hàng đầu!
  4. #vtk88 #TK88
  5. Địa chỉ : 59 Đường D1, Mỹ Phước, Bến Cát, Bình Dương 825530, Vietnam
  6. Hotline : 0912694050
  7. Website TK88:  
  8.  
  9. SOCIAL
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
]]>
Re: Untitled https://mlx.su/paste/view/030c63d3 Wed, 07 May 2025 03:34:31 +0300 herpafend ingredients https://mlx.su/paste/view/030c63d3
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/703f2351 Wed, 07 May 2025 02:16:24 +0300 gut health https://mlx.su/paste/view/703f2351
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/3d1e02b1 Mon, 05 May 2025 16:44:58 +0300 phim sex không che https://mlx.su/paste/view/3d1e02b1
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/41836bac Thu, 01 May 2025 07:14:22 +0300 primal grow pro review https://mlx.su/paste/view/41836bac
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/e80a3fdb Thu, 01 May 2025 05:54:39 +0300 the brain song reviews and compl https://mlx.su/paste/view/e80a3fdb
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/428471cb Tue, 29 Apr 2025 20:06:39 +0300 prodentim real https://mlx.su/paste/view/428471cb
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/ad732a75 Tue, 29 Apr 2025 18:00:43 +0300 does primal grow pro actually wo https://mlx.su/paste/view/ad732a75
  1. Your paste - Paste your paste here
]]>
Re: Untitled https://mlx.su/paste/view/5d077010 Tue, 29 Apr 2025 15:09:24 +0300 tonic greens https://mlx.su/paste/view/5d077010
  1. Your paste - Paste your paste here
]]>