\n * @license http:\/\/www.gnu.org\/copyleft\/gpl.html GNU GPL v3 or later\n *\/\ndefine(['jquery'], function($) {\n\n \/\/ Matches trailing non-space characters.\n var chop = \/(\\s*\\S+|\\s)$\/;\n\n \/\/ Matches the first word in the string.\n var start = \/^(\\S*)\/;\n\n \/\/ Matches any space characters.\n var space = \/\\s\/;\n\n \/\/ Special thanks to Mathias Bynens for the multi-byte char\n \/\/ implementation. Much love.\n \/\/ see: https:\/\/github.com\/mathiasbynens\/String.prototype.at\/blob\/master\/at.js\n var charLengthAt = function(text, position) {\n var string = String(text);\n var size = string.length;\n \/\/ `ToInteger`\n var index = position ? Number(position) : 0;\n if (index != index) { \/\/ better `isNaN`\n index = 0;\n }\n \/\/ Account for out-of-bounds indices\n \/\/ The odd lower bound is because the ToInteger operation is\n \/\/ going to round `n` to `0` for `-1 < n <= 0`.\n if (index <= -1 || index >= size) {\n return '';\n }\n \/\/ Second half of `ToInteger`\n index = index | 0;\n \/\/ Get the first code unit and code unit value\n var cuFirst = string.charCodeAt(index);\n var cuSecond;\n var nextIndex = index + 1;\n var len = 1;\n if ( \/\/ Check if it\u2019s the start of a surrogate pair.\n cuFirst >= 0xD800 && cuFirst <= 0xDBFF && \/\/ high surrogate\n size > nextIndex \/\/ there is a next code unit\n ) {\n cuSecond = string.charCodeAt(nextIndex);\n if (cuSecond >= 0xDC00 && cuSecond <= 0xDFFF) { \/\/ low surrogate\n len = 2;\n }\n }\n return len;\n };\n\n var lengthMultiByte = function(text) {\n var count = 0;\n\n for (var i = 0; i < text.length; i += charLengthAt(text, i)) {\n count++;\n }\n\n return count;\n };\n\n var getSliceLength = function(text, amount) {\n if (!text.length) {\n return 0;\n }\n\n var length = 0;\n var count = 0;\n\n do {\n length += charLengthAt(text, length);\n count++;\n } while (length < text.length && count < amount);\n\n return length;\n };\n\n \/\/ Return a truncated html string. Delegates to $.fn.truncate.\n $.truncate = function(html, options) {\n return $('<\/div>').append(html).truncate(options).html();\n };\n\n \/\/ Truncate the contents of an element in place.\n $.fn.truncate = function(options) {\n if (!isNaN(parseFloat(options))) options = {length: options};\n var o = $.extend({}, $.truncate.defaults, options);\n\n return this.each(function() {\n var self = $(this);\n\n if (o.noBreaks) self.find('br').replaceWith(' ');\n\n var ellipsisLength = o.ellipsis.length;\n var text = self.text();\n var textLength = lengthMultiByte(text);\n var excess = textLength - o.length + ellipsisLength;\n\n if (textLength < o.length) return;\n if (o.stripTags) self.text(text);\n\n \/\/ Chop off any partial words if appropriate.\n if (o.words && excess > 0) {\n var sliced = text.slice(0, getSliceLength(text, o.length - ellipsisLength) + 1);\n var replaced = sliced.replace(chop, '');\n var truncated = lengthMultiByte(replaced);\n var oneWord = sliced.match(space) ? false : true;\n\n if (o.keepFirstWord && truncated === 0) {\n excess = textLength - lengthMultiByte(start.exec(text)[0]) - ellipsisLength;\n } else if (oneWord && truncated === 0) {\n excess = textLength - o.length + ellipsisLength;\n } else {\n excess = textLength - truncated - 1;\n }\n }\n\n \/\/ The requested length is larger than the text. No need for ellipsis.\n if (excess > textLength) {\n excess = textLength - o.length;\n }\n\n if (excess < 0 || !excess && !o.truncated) return;\n\n \/\/ Iterate over each child node in reverse, removing excess text.\n $.each(self.contents().get().reverse(), function(i, el) {\n var $el = $(el);\n var text = $el.text();\n var length = lengthMultiByte(text);\n\n \/\/ If the text is longer than the excess, remove the node and continue.\n if (length <= excess) {\n o.truncated = true;\n excess -= length;\n $el.remove();\n return;\n }\n\n \/\/ Remove the excess text and append the ellipsis.\n if (el.nodeType === 3) {\n var splitAmount = length - excess;\n splitAmount = splitAmount >= 0 ? getSliceLength(text, splitAmount) : 0;\n $(el.splitText(splitAmount)).replaceWith(o.ellipsis);\n return false;\n }\n\n \/\/ Recursively truncate child nodes.\n $el.truncate($.extend(o, {length: length - excess + ellipsisLength}));\n return false;\n });\n });\n };\n\n $.truncate.defaults = {\n\n \/\/ Strip all html elements, leaving only plain text.\n stripTags: false,\n\n \/\/ Only truncate at word boundaries.\n words: false,\n\n \/\/ When 'words' is active, keeps the first word in the string\n \/\/ even if it's longer than a target length.\n keepFirstWord: false,\n\n \/\/ Replace instances of
with a single space.\n noBreaks: false,\n\n \/\/ The maximum length of the truncated html.\n length: Infinity,\n\n \/\/ The character to use as the ellipsis. The word joiner (U+2060) can be\n \/\/ used to prevent a hanging ellipsis, but displays incorrectly in Chrome\n \/\/ on Windows 7.\n \/\/ http:\/\/code.google.com\/p\/chromium\/issues\/detail?id=68323\n \/\/ellipsis: '\\u2026' \/\/ '\\u2060\\u2026'\n ellipsis: '\\u2026' \/\/ '\\u2060\\u2026'\n\n };\n\n return {\n truncate: $.truncate,\n };\n});\n"],"file":"truncate.min.js"}