(function() { // Baseline setup // -------------- // Establish the root object, `window` in the browser, or `global` on the server. var root = this; // Save the previous value of the `humanize` variable. var previousHumanize = root.humanize; var humanize = {}; if (typeof exports !== 'undefined') { if (typeof module !== 'undefined' && module.exports) { exports = module.exports = humanize; } exports.humanize = humanize; } else { if (typeof define === 'function' && define.amd) { define('humanize', function() { return humanize; }); } root.humanize = humanize; } humanize.noConflict = function() { root.humanize = previousHumanize; return this; }; humanize.pad = function(str, count, padChar, type) { str += ''; if (!padChar) { padChar = ' '; } else if (padChar.length > 1) { padChar = padChar.charAt(0); } type = (type === undefined) ? 'left' : 'right'; if (type === 'right') { while (str.length < count) { str = str + padChar; } } else { // default to left while (str.length < count) { str = padChar + str; } } return str; }; // gets current unix time humanize.time = function() { return new Date().getTime() / 1000; }; /** * PHP-inspired date */ /* jan feb mar apr may jun jul aug sep oct nov dec */ var dayTableCommon = [ 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 ]; var dayTableLeap = [ 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ]; // var mtable_common[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // static int ml_table_leap[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; humanize.date = function(format, timestamp) { var jsdate = ((timestamp === undefined) ? new Date() : // Not provided (timestamp instanceof Date) ? new Date(timestamp) : // JS Date() new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int) ); var formatChr = /\\?([a-z])/gi; var formatChrCb = function (t, s) { return f[t] ? f[t]() : s; }; var shortDayTxt = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var monthTxt = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; var f = { /* Day */ // Day of month w/leading 0; 01..31 d: function () { return humanize.pad(f.j(), 2, '0'); }, // Shorthand day name; Mon..Sun D: function () { return f.l().slice(0, 3); }, // Day of month; 1..31 j: function () { return jsdate.getDate(); }, // Full day name; Monday..Sunday l: function () { return shortDayTxt[f.w()]; }, // ISO-8601 day of week; 1[Mon]..7[Sun] N: function () { return f.w() || 7; }, // Ordinal suffix for day of month; st, nd, rd, th S: function () { var j = f.j(); return j > 4 && j < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[j % 10] || 'th'; }, // Day of week; 0[Sun]..6[Sat] w: function () { return jsdate.getDay(); }, // Day of year; 0..365 z: function () { return (f.L() ? dayTableLeap[f.n()] : dayTableCommon[f.n()]) + f.j() - 1; }, /* Week */ // ISO-8601 week number W: function () { // days between midweek of this week and jan 4 // (f.z() - f.N() + 1 + 3.5) - 3 var midWeekDaysFromJan4 = f.z() - f.N() + 1.5; // 1 + number of weeks + rounded week return humanize.pad(1 + Math.floor(Math.abs(midWeekDaysFromJan4) / 7) + (midWeekDaysFromJan4 % 7 > 3.5 ? 1 : 0), 2, '0'); }, /* Month */ // Full month name; January..December F: function () { return monthTxt[jsdate.getMonth()]; }, // Month w/leading 0; 01..12 m: function () { return humanize.pad(f.n(), 2, '0'); }, // Shorthand month name; Jan..Dec M: function () { return f.F().slice(0, 3); }, // Month; 1..12 n: function () { return jsdate.getMonth() + 1; }, // Days in month; 28..31 t: function () { return (new Date(f.Y(), f.n(), 0)).getDate(); }, /* Year */ // Is leap year?; 0 or 1 L: function () { return new Date(f.Y(), 1, 29).getMonth() === 1 ? 1 : 0; }, // ISO-8601 year o: function () { var n = f.n(); var W = f.W(); return f.Y() + (n === 12 && W < 9 ? -1 : n === 1 && W > 9); }, // Full year; e.g. 1980..2010 Y: function () { return jsdate.getFullYear(); }, // Last two digits of year; 00..99 y: function () { return (String(f.Y())).slice(-2); }, /* Time */ // am or pm a: function () { return jsdate.getHours() > 11 ? 'pm' : 'am'; }, // AM or PM A: function () { return f.a().toUpperCase(); }, // Swatch Internet time; 000..999 B: function () { var unixTime = jsdate.getTime() / 1000; var secondsPassedToday = unixTime % 86400 + 3600; // since it's based off of UTC+1 if (secondsPassedToday < 0) { secondsPassedToday += 86400; } var beats = ((secondsPassedToday) / 86.4) % 1000; if (unixTime < 0) { return Math.ceil(beats); } return Math.floor(beats); }, // 12-Hours; 1..12 g: function () { return f.G() % 12 || 12; }, // 24-Hours; 0..23 G: function () { return jsdate.getHours(); }, // 12-Hours w/leading 0; 01..12 h: function () { return humanize.pad(f.g(), 2, '0'); }, // 24-Hours w/leading 0; 00..23 H: function () { return humanize.pad(f.G(), 2, '0'); }, // Minutes w/leading 0; 00..59 i: function () { return humanize.pad(jsdate.getMinutes(), 2, '0'); }, // Seconds w/leading 0; 00..59 s: function () { return humanize.pad(jsdate.getSeconds(), 2, '0'); }, // Microseconds; 000000-999000 u: function () { return humanize.pad(jsdate.getMilliseconds() * 1000, 6, '0'); }, // Whether or not the date is in daylight savings time /* I: function () { // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC. // If they are not equal, then DST is observed. var Y = f.Y(); return 0 + ((new Date(Y, 0) - Date.UTC(Y, 0)) !== (new Date(Y, 6) - Date.UTC(Y, 6))); }, */ // Difference to GMT in hour format; e.g. +0200 O: function () { var tzo = jsdate.getTimezoneOffset(); var tzoNum = Math.abs(tzo); return (tzo > 0 ? '-' : '+') + humanize.pad(Math.floor(tzoNum / 60) * 100 + tzoNum % 60, 4, '0'); }, // Difference to GMT w/colon; e.g. +02:00 P: function () { var O = f.O(); return (O.substr(0, 3) + ':' + O.substr(3, 2)); }, // Timezone offset in seconds (-43200..50400) Z: function () { return -jsdate.getTimezoneOffset() * 60; }, // Full Date/Time, ISO-8601 date c: function () { return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb); }, // RFC 2822 r: function () { return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb); }, // Seconds since UNIX epoch U: function () { return jsdate.getTime() / 1000 || 0; } }; return format.replace(formatChr, formatChrCb); }; /** * format number by adding thousands separaters and significant digits while rounding */ humanize.numberFormat = function(number, decimals, decPoint, thousandsSep) { decimals = isNaN(decimals) ? 2 : Math.abs(decimals); decPoint = (decPoint === undefined) ? '.' : decPoint; thousandsSep = (thousandsSep === undefined) ? ',' : thousandsSep; var sign = number < 0 ? '-' : ''; number = Math.abs(+number || 0); var intPart = parseInt(number.toFixed(decimals), 10) + ''; var j = intPart.length > 3 ? intPart.length % 3 : 0; return sign + (j ? intPart.substr(0, j) + thousandsSep : '') + intPart.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousandsSep) + (decimals ? decPoint + Math.abs(number - intPart).toFixed(decimals).slice(2) : ''); }; /** * For dates that are the current day or within one day, return 'today', 'tomorrow' or 'yesterday', as appropriate. * Otherwise, format the date using the passed in format string. * * Examples (when 'today' is 17 Feb 2007): * 16 Feb 2007 becomes yesterday. * 17 Feb 2007 becomes today. * 18 Feb 2007 becomes tomorrow. * Any other day is formatted according to given argument or the DATE_FORMAT setting if no argument is given. */ humanize.naturalDay = function(timestamp, format) { timestamp = (timestamp === undefined) ? humanize.time() : timestamp; format = (format === undefined) ? 'Y-m-d' : format; var oneDay = 86400; var d = new Date(); var today = (new Date(d.getFullYear(), d.getMonth(), d.getDate())).getTime() / 1000; if (timestamp < today && timestamp >= today - oneDay) { return 'yesterday'; } else if (timestamp >= today && timestamp < today + oneDay) { return 'today'; } else if (timestamp >= today + oneDay && timestamp < today + 2 * oneDay) { return 'tomorrow'; } return humanize.date(format, timestamp); }; /** * returns a string representing how many seconds, minutes or hours ago it was or will be in the future * Will always return a relative time, most granular of seconds to least granular of years. See unit tests for more details */ humanize.relativeTime = function(timestamp) { timestamp = (timestamp === undefined) ? humanize.time() : timestamp; var currTime = humanize.time(); var timeDiff = currTime - timestamp; // within 2 seconds if (timeDiff < 2 && timeDiff > -2) { return (timeDiff >= 0 ? 'just ' : '') + 'now'; } // within a minute if (timeDiff < 60 && timeDiff > -60) { return (timeDiff >= 0 ? Math.floor(timeDiff) + ' seconds ago' : 'in ' + Math.floor(-timeDiff) + ' seconds'); } // within 2 minutes if (timeDiff < 120 && timeDiff > -120) { return (timeDiff >= 0 ? 'about a minute ago' : 'in about a minute'); } // within an hour if (timeDiff < 3600 && timeDiff > -3600) { return (timeDiff >= 0 ? Math.floor(timeDiff / 60) + ' minutes ago' : 'in ' + Math.floor(-timeDiff / 60) + ' minutes'); } // within 2 hours if (timeDiff < 7200 && timeDiff > -7200) { return (timeDiff >= 0 ? 'about an hour ago' : 'in about an hour'); } // within 24 hours if (timeDiff < 86400 && timeDiff > -86400) { return (timeDiff >= 0 ? Math.floor(timeDiff / 3600) + ' hours ago' : 'in ' + Math.floor(-timeDiff / 3600) + ' hours'); } // within 2 days var days2 = 2 * 86400; if (timeDiff < days2 && timeDiff > -days2) { return (timeDiff >= 0 ? '1 day ago' : 'in 1 day'); } // within 29 days var days29 = 29 * 86400; if (timeDiff < days29 && timeDiff > -days29) { return (timeDiff >= 0 ? Math.floor(timeDiff / 86400) + ' days ago' : 'in ' + Math.floor(-timeDiff / 86400) + ' days'); } // within 60 days var days60 = 60 * 86400; if (timeDiff < days60 && timeDiff > -days60) { return (timeDiff >= 0 ? 'about a month ago' : 'in about a month'); } var currTimeYears = parseInt(humanize.date('Y', currTime), 10); var timestampYears = parseInt(humanize.date('Y', timestamp), 10); var currTimeMonths = currTimeYears * 12 + parseInt(humanize.date('n', currTime), 10); var timestampMonths = timestampYears * 12 + parseInt(humanize.date('n', timestamp), 10); // within a year var monthDiff = currTimeMonths - timestampMonths; if (monthDiff < 12 && monthDiff > -12) { return (monthDiff >= 0 ? monthDiff + ' months ago' : 'in ' + (-monthDiff) + ' months'); } var yearDiff = currTimeYears - timestampYears; if (yearDiff < 2 && yearDiff > -2) { return (yearDiff >= 0 ? 'a year ago' : 'in a year'); } return (yearDiff >= 0 ? yearDiff + ' years ago' : 'in ' + (-yearDiff) + ' years'); }; /** * Converts an integer to its ordinal as a string. * * 1 becomes 1st * 2 becomes 2nd * 3 becomes 3rd etc */ humanize.ordinal = function(number) { number = parseInt(number, 10); number = isNaN(number) ? 0 : number; var sign = number < 0 ? '-' : ''; number = Math.abs(number); var tens = number % 100; return sign + number + (tens > 4 && tens < 21 ? 'th' : {1: 'st', 2: 'nd', 3: 'rd'}[number % 10] || 'th'); }; /** * Formats the value like a 'human-readable' file size (i.e. '13 KB', '4.1 MB', '102 bytes', etc). * * For example: * If value is 123456789, the output would be 117.7 MB. */ humanize.filesize = function(filesize, kilo, decimals, decPoint, thousandsSep, suffixSep) { kilo = (kilo === undefined) ? 1024 : kilo; if (filesize <= 0) { return '0 bytes'; } if (filesize < kilo && decimals === undefined) { decimals = 0; } if (suffixSep === undefined) { suffixSep = ' '; } return humanize.intword(filesize, ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'], kilo, decimals, decPoint, thousandsSep, suffixSep); }; /** * Formats the value like a 'human-readable' number (i.e. '13 K', '4.1 M', '102', etc). * * For example: * If value is 123456789, the output would be 117.7 M. */ humanize.intword = function(number, units, kilo, decimals, decPoint, thousandsSep, suffixSep) { var humanized, unit; units = units || ['', 'K', 'M', 'B', 'T'], unit = units.length - 1, kilo = kilo || 1000, decimals = isNaN(decimals) ? 2 : Math.abs(decimals), decPoint = decPoint || '.', thousandsSep = thousandsSep || ',', suffixSep = suffixSep || ''; for (var i=0; i < units.length; i++) { if (number < Math.pow(kilo, i+1)) { unit = i; break; } } humanized = number / Math.pow(kilo, unit); var suffix = units[unit] ? suffixSep + units[unit] : ''; return humanize.numberFormat(humanized, decimals, decPoint, thousandsSep) + suffix; }; /** * Replaces line breaks in plain text with appropriate HTML * A single newline becomes an HTML line break (
) and a new line followed by a blank line becomes a paragraph break (

). * * For example: * If value is Joel\nis a\n\nslug, the output will be

Joel
is a

slug

*/ humanize.linebreaks = function(str) { // remove beginning and ending newlines str = str.replace(/^([\n|\r]*)/, ''); str = str.replace(/([\n|\r]*)$/, ''); // normalize all to \n str = str.replace(/(\r\n|\n|\r)/g, "\n"); // any consecutive new lines more than 2 gets turned into p tags str = str.replace(/(\n{2,})/g, '

'); // any that are singletons get turned into br str = str.replace(/\n/g, '
'); return '

' + str + '

'; }; /** * Converts all newlines in a piece of plain text to HTML line breaks (
). */ humanize.nl2br = function(str) { return str.replace(/(\r\n|\n|\r)/g, '
'); }; /** * Truncates a string if it is longer than the specified number of characters. * Truncated strings will end with a translatable ellipsis sequence ('…'). */ humanize.truncatechars = function(string, length) { if (string.length <= length) { return string; } return string.substr(0, length) + '…'; }; /** * Truncates a string after a certain number of words. * Newlines within the string will be removed. */ humanize.truncatewords = function(string, numWords) { var words = string.split(' '); if (words.length < numWords) { return string; } return words.slice(0, numWords).join(' ') + '…'; }; }).call(this); ////////////////// // WEBPACK FOOTER // ./~/humanize/humanize.js // module id = 475 // module chunks = 4