--- /dev/null
+/* underscore.string 3.2.2 | MIT licensed | http://epeli.github.com/underscore.string/ */
+
+!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.s=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+var decap = _dereq_('./decapitalize');
+
+module.exports = function camelize(str, decapitalize) {
+ str = trim(str).replace(/[-_\s]+(.)?/g, function(match, c) {
+ return c ? c.toUpperCase() : "";
+ });
+
+ if (decapitalize === true) {
+ return decap(str);
+ } else {
+ return str;
+ }
+};
+
+},{"./decapitalize":10,"./trim":63}],2:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function capitalize(str, lowercaseRest) {
+ str = makeString(str);
+ var remainingChars = !lowercaseRest ? str.slice(1) : str.slice(1).toLowerCase();
+
+ return str.charAt(0).toUpperCase() + remainingChars;
+};
+
+},{"./helper/makeString":21}],3:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function chars(str) {
+ return makeString(str).split('');
+};
+
+},{"./helper/makeString":21}],4:[function(_dereq_,module,exports){
+module.exports = function chop(str, step) {
+ if (str == null) return [];
+ str = String(str);
+ step = ~~step;
+ return step > 0 ? str.match(new RegExp('.{1,' + step + '}', 'g')) : [str];
+};
+
+},{}],5:[function(_dereq_,module,exports){
+var capitalize = _dereq_('./capitalize');
+var camelize = _dereq_('./camelize');
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function classify(str) {
+ str = makeString(str);
+ return capitalize(camelize(str.replace(/[\W_]/g, ' ')).replace(/\s/g, ''));
+};
+
+},{"./camelize":1,"./capitalize":2,"./helper/makeString":21}],6:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+
+module.exports = function clean(str) {
+ return trim(str).replace(/\s\s+/g, ' ');
+};
+
+},{"./trim":63}],7:[function(_dereq_,module,exports){
+
+var makeString = _dereq_('./helper/makeString');
+
+var from = "ąàáäâãåæăćčĉęèéëêĝĥìíïîĵłľńňòóöőôõðøśșşšŝťțţŭùúüűûñÿýçżźž",
+ to = "aaaaaaaaaccceeeeeghiiiijllnnoooooooossssstttuuuuuunyyczzz";
+
+from += from.toUpperCase();
+to += to.toUpperCase();
+
+to = to.split("");
+
+// for tokens requireing multitoken output
+from += "ß";
+to.push('ss');
+
+
+module.exports = function cleanDiacritics(str) {
+ return makeString(str).replace(/.{1}/g, function(c){
+ var index = from.indexOf(c);
+ return index === -1 ? c : to[index];
+ });
+};
+
+},{"./helper/makeString":21}],8:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function(str, substr) {
+ str = makeString(str);
+ substr = makeString(substr);
+
+ if (str.length === 0 || substr.length === 0) return 0;
+
+ return str.split(substr).length - 1;
+};
+
+},{"./helper/makeString":21}],9:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+
+module.exports = function dasherize(str) {
+ return trim(str).replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
+};
+
+},{"./trim":63}],10:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function decapitalize(str) {
+ str = makeString(str);
+ return str.charAt(0).toLowerCase() + str.slice(1);
+};
+
+},{"./helper/makeString":21}],11:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+function getIndent(str) {
+ var matches = str.match(/^[\s\\t]*/gm);
+ var indent = matches[0].length;
+
+ for (var i = 1; i < matches.length; i++) {
+ indent = Math.min(matches[i].length, indent);
+ }
+
+ return indent;
+}
+
+module.exports = function dedent(str, pattern) {
+ str = makeString(str);
+ var indent = getIndent(str);
+ var reg;
+
+ if (indent === 0) return str;
+
+ if (typeof pattern === 'string') {
+ reg = new RegExp('^' + pattern, 'gm');
+ } else {
+ reg = new RegExp('^[ \\t]{' + indent + '}', 'gm');
+ }
+
+ return str.replace(reg, '');
+};
+
+},{"./helper/makeString":21}],12:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var toPositive = _dereq_('./helper/toPositive');
+
+module.exports = function endsWith(str, ends, position) {
+ str = makeString(str);
+ ends = '' + ends;
+ if (typeof position == 'undefined') {
+ position = str.length - ends.length;
+ } else {
+ position = Math.min(toPositive(position), str.length) - ends.length;
+ }
+ return position >= 0 && str.indexOf(ends, position) === position;
+};
+
+},{"./helper/makeString":21,"./helper/toPositive":23}],13:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var escapeChars = _dereq_('./helper/escapeChars');
+
+var regexString = "[";
+for(var key in escapeChars) {
+ regexString += key;
+}
+regexString += "]";
+
+var regex = new RegExp( regexString, 'g');
+
+module.exports = function escapeHTML(str) {
+
+ return makeString(str).replace(regex, function(m) {
+ return '&' + escapeChars[m] + ';';
+ });
+};
+
+},{"./helper/escapeChars":18,"./helper/makeString":21}],14:[function(_dereq_,module,exports){
+module.exports = function() {
+ var result = {};
+
+ for (var prop in this) {
+ if (!this.hasOwnProperty(prop) || prop.match(/^(?:include|contains|reverse|join|map)$/)) continue;
+ result[prop] = this[prop];
+ }
+
+ return result;
+};
+
+},{}],15:[function(_dereq_,module,exports){
+// Underscore.string
+// (c) 2010 Esa-Matti Suuronen <esa-matti aet suuronen dot org>
+// Underscore.string is freely distributable under the terms of the MIT license.
+// Documentation: https://github.com/epeli/underscore.string
+// Some code is borrowed from MooTools and Alexandru Marasteanu.
+// Version '3.2.2'
+
+'use strict';
+
+function s(value) {
+ /* jshint validthis: true */
+ if (!(this instanceof s)) return new s(value);
+ this._wrapped = value;
+}
+
+s.VERSION = '3.2.2';
+
+s.isBlank = _dereq_('./isBlank');
+s.stripTags = _dereq_('./stripTags');
+s.capitalize = _dereq_('./capitalize');
+s.decapitalize = _dereq_('./decapitalize');
+s.chop = _dereq_('./chop');
+s.trim = _dereq_('./trim');
+s.clean = _dereq_('./clean');
+s.cleanDiacritics = _dereq_('./cleanDiacritics');
+s.count = _dereq_('./count');
+s.chars = _dereq_('./chars');
+s.swapCase = _dereq_('./swapCase');
+s.escapeHTML = _dereq_('./escapeHTML');
+s.unescapeHTML = _dereq_('./unescapeHTML');
+s.splice = _dereq_('./splice');
+s.insert = _dereq_('./insert');
+s.replaceAll = _dereq_('./replaceAll');
+s.include = _dereq_('./include');
+s.join = _dereq_('./join');
+s.lines = _dereq_('./lines');
+s.dedent = _dereq_('./dedent');
+s.reverse = _dereq_('./reverse');
+s.startsWith = _dereq_('./startsWith');
+s.endsWith = _dereq_('./endsWith');
+s.pred = _dereq_('./pred');
+s.succ = _dereq_('./succ');
+s.titleize = _dereq_('./titleize');
+s.camelize = _dereq_('./camelize');
+s.underscored = _dereq_('./underscored');
+s.dasherize = _dereq_('./dasherize');
+s.classify = _dereq_('./classify');
+s.humanize = _dereq_('./humanize');
+s.ltrim = _dereq_('./ltrim');
+s.rtrim = _dereq_('./rtrim');
+s.truncate = _dereq_('./truncate');
+s.prune = _dereq_('./prune');
+s.words = _dereq_('./words');
+s.pad = _dereq_('./pad');
+s.lpad = _dereq_('./lpad');
+s.rpad = _dereq_('./rpad');
+s.lrpad = _dereq_('./lrpad');
+s.sprintf = _dereq_('./sprintf');
+s.vsprintf = _dereq_('./vsprintf');
+s.toNumber = _dereq_('./toNumber');
+s.numberFormat = _dereq_('./numberFormat');
+s.strRight = _dereq_('./strRight');
+s.strRightBack = _dereq_('./strRightBack');
+s.strLeft = _dereq_('./strLeft');
+s.strLeftBack = _dereq_('./strLeftBack');
+s.toSentence = _dereq_('./toSentence');
+s.toSentenceSerial = _dereq_('./toSentenceSerial');
+s.slugify = _dereq_('./slugify');
+s.surround = _dereq_('./surround');
+s.quote = _dereq_('./quote');
+s.unquote = _dereq_('./unquote');
+s.repeat = _dereq_('./repeat');
+s.naturalCmp = _dereq_('./naturalCmp');
+s.levenshtein = _dereq_('./levenshtein');
+s.toBoolean = _dereq_('./toBoolean');
+s.exports = _dereq_('./exports');
+s.escapeRegExp = _dereq_('./helper/escapeRegExp');
+s.wrap = _dereq_('./wrap');
+s.map = _dereq_('./map');
+
+// Aliases
+s.strip = s.trim;
+s.lstrip = s.ltrim;
+s.rstrip = s.rtrim;
+s.center = s.lrpad;
+s.rjust = s.lpad;
+s.ljust = s.rpad;
+s.contains = s.include;
+s.q = s.quote;
+s.toBool = s.toBoolean;
+s.camelcase = s.camelize;
+s.mapChars = s.map;
+
+
+// Implement chaining
+s.prototype = {
+ value: function value() {
+ return this._wrapped;
+ }
+};
+
+function fn2method(key, fn) {
+ if (typeof fn !== "function") return;
+ s.prototype[key] = function() {
+ var args = [this._wrapped].concat(Array.prototype.slice.call(arguments));
+ var res = fn.apply(null, args);
+ // if the result is non-string stop the chain and return the value
+ return typeof res === 'string' ? new s(res) : res;
+ };
+}
+
+// Copy functions to instance methods for chaining
+for (var key in s) fn2method(key, s[key]);
+
+fn2method("tap", function tap(string, fn) {
+ return fn(string);
+});
+
+function prototype2method(methodName) {
+ fn2method(methodName, function(context) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return String.prototype[methodName].apply(context, args);
+ });
+}
+
+var prototypeMethods = [
+ "toUpperCase",
+ "toLowerCase",
+ "split",
+ "replace",
+ "slice",
+ "substring",
+ "substr",
+ "concat"
+];
+
+for (var method in prototypeMethods) prototype2method(prototypeMethods[method]);
+
+
+module.exports = s;
+
+},{"./camelize":1,"./capitalize":2,"./chars":3,"./chop":4,"./classify":5,"./clean":6,"./cleanDiacritics":7,"./count":8,"./dasherize":9,"./decapitalize":10,"./dedent":11,"./endsWith":12,"./escapeHTML":13,"./exports":14,"./helper/escapeRegExp":19,"./humanize":24,"./include":25,"./insert":26,"./isBlank":27,"./join":28,"./levenshtein":29,"./lines":30,"./lpad":31,"./lrpad":32,"./ltrim":33,"./map":34,"./naturalCmp":35,"./numberFormat":36,"./pad":37,"./pred":38,"./prune":39,"./quote":40,"./repeat":41,"./replaceAll":42,"./reverse":43,"./rpad":44,"./rtrim":45,"./slugify":46,"./splice":47,"./sprintf":48,"./startsWith":49,"./strLeft":50,"./strLeftBack":51,"./strRight":52,"./strRightBack":53,"./stripTags":54,"./succ":55,"./surround":56,"./swapCase":57,"./titleize":58,"./toBoolean":59,"./toNumber":60,"./toSentence":61,"./toSentenceSerial":62,"./trim":63,"./truncate":64,"./underscored":65,"./unescapeHTML":66,"./unquote":67,"./vsprintf":68,"./words":69,"./wrap":70}],16:[function(_dereq_,module,exports){
+var makeString = _dereq_('./makeString');
+
+module.exports = function adjacent(str, direction) {
+ str = makeString(str);
+ if (str.length === 0) {
+ return '';
+ }
+ return str.slice(0, -1) + String.fromCharCode(str.charCodeAt(str.length - 1) + direction);
+};
+
+},{"./makeString":21}],17:[function(_dereq_,module,exports){
+var escapeRegExp = _dereq_('./escapeRegExp');
+
+module.exports = function defaultToWhiteSpace(characters) {
+ if (characters == null)
+ return '\\s';
+ else if (characters.source)
+ return characters.source;
+ else
+ return '[' + escapeRegExp(characters) + ']';
+};
+
+},{"./escapeRegExp":19}],18:[function(_dereq_,module,exports){
+/* We're explicitly defining the list of entities we want to escape.
+nbsp is an HTML entity, but we don't want to escape all space characters in a string, hence its omission in this map.
+
+*/
+var escapeChars = {
+ '¢' : 'cent',
+ '£' : 'pound',
+ '¥' : 'yen',
+ '€': 'euro',
+ '©' :'copy',
+ '®' : 'reg',
+ '<' : 'lt',
+ '>' : 'gt',
+ '"' : 'quot',
+ '&' : 'amp',
+ "'" : '#39'
+};
+
+module.exports = escapeChars;
+
+},{}],19:[function(_dereq_,module,exports){
+var makeString = _dereq_('./makeString');
+
+module.exports = function escapeRegExp(str) {
+ return makeString(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
+};
+
+},{"./makeString":21}],20:[function(_dereq_,module,exports){
+/*
+We're explicitly defining the list of entities that might see in escape HTML strings
+*/
+var htmlEntities = {
+ nbsp: ' ',
+ cent: '¢',
+ pound: '£',
+ yen: '¥',
+ euro: '€',
+ copy: '©',
+ reg: '®',
+ lt: '<',
+ gt: '>',
+ quot: '"',
+ amp: '&',
+ apos: "'"
+};
+
+module.exports = htmlEntities;
+
+},{}],21:[function(_dereq_,module,exports){
+/**
+ * Ensure some object is a coerced to a string
+ **/
+module.exports = function makeString(object) {
+ if (object == null) return '';
+ return '' + object;
+};
+
+},{}],22:[function(_dereq_,module,exports){
+module.exports = function strRepeat(str, qty){
+ if (qty < 1) return '';
+ var result = '';
+ while (qty > 0) {
+ if (qty & 1) result += str;
+ qty >>= 1, str += str;
+ }
+ return result;
+};
+
+},{}],23:[function(_dereq_,module,exports){
+module.exports = function toPositive(number) {
+ return number < 0 ? 0 : (+number || 0);
+};
+
+},{}],24:[function(_dereq_,module,exports){
+var capitalize = _dereq_('./capitalize');
+var underscored = _dereq_('./underscored');
+var trim = _dereq_('./trim');
+
+module.exports = function humanize(str) {
+ return capitalize(trim(underscored(str).replace(/_id$/, '').replace(/_/g, ' ')));
+};
+
+},{"./capitalize":2,"./trim":63,"./underscored":65}],25:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function include(str, needle) {
+ if (needle === '') return true;
+ return makeString(str).indexOf(needle) !== -1;
+};
+
+},{"./helper/makeString":21}],26:[function(_dereq_,module,exports){
+var splice = _dereq_('./splice');
+
+module.exports = function insert(str, i, substr) {
+ return splice(str, i, 0, substr);
+};
+
+},{"./splice":47}],27:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function isBlank(str) {
+ return (/^\s*$/).test(makeString(str));
+};
+
+},{"./helper/makeString":21}],28:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var slice = [].slice;
+
+module.exports = function join() {
+ var args = slice.call(arguments),
+ separator = args.shift();
+
+ return args.join(makeString(separator));
+};
+
+},{"./helper/makeString":21}],29:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+/**
+ * Based on the implementation here: https://github.com/hiddentao/fast-levenshtein
+ */
+module.exports = function levenshtein(str1, str2) {
+ 'use strict';
+ str1 = makeString(str1);
+ str2 = makeString(str2);
+
+ // Short cut cases
+ if (str1 === str2) return 0;
+ if (!str1 || !str2) return Math.max(str1.length, str2.length);
+
+ // two rows
+ var prevRow = new Array(str2.length + 1);
+
+ // initialise previous row
+ for (var i = 0; i < prevRow.length; ++i) {
+ prevRow[i] = i;
+ }
+
+ // calculate current row distance from previous row
+ for (i = 0; i < str1.length; ++i) {
+ var nextCol = i + 1;
+
+ for (var j = 0; j < str2.length; ++j) {
+ var curCol = nextCol;
+
+ // substution
+ nextCol = prevRow[j] + ( (str1.charAt(i) === str2.charAt(j)) ? 0 : 1 );
+ // insertion
+ var tmp = curCol + 1;
+ if (nextCol > tmp) {
+ nextCol = tmp;
+ }
+ // deletion
+ tmp = prevRow[j + 1] + 1;
+ if (nextCol > tmp) {
+ nextCol = tmp;
+ }
+
+ // copy current col value into previous (in preparation for next iteration)
+ prevRow[j] = curCol;
+ }
+
+ // copy last col value into previous (in preparation for next iteration)
+ prevRow[j] = nextCol;
+ }
+
+ return nextCol;
+};
+
+},{"./helper/makeString":21}],30:[function(_dereq_,module,exports){
+module.exports = function lines(str) {
+ if (str == null) return [];
+ return String(str).split(/\r\n?|\n/);
+};
+
+},{}],31:[function(_dereq_,module,exports){
+var pad = _dereq_('./pad');
+
+module.exports = function lpad(str, length, padStr) {
+ return pad(str, length, padStr);
+};
+
+},{"./pad":37}],32:[function(_dereq_,module,exports){
+var pad = _dereq_('./pad');
+
+module.exports = function lrpad(str, length, padStr) {
+ return pad(str, length, padStr, 'both');
+};
+
+},{"./pad":37}],33:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
+var nativeTrimLeft = String.prototype.trimLeft;
+
+module.exports = function ltrim(str, characters) {
+ str = makeString(str);
+ if (!characters && nativeTrimLeft) return nativeTrimLeft.call(str);
+ characters = defaultToWhiteSpace(characters);
+ return str.replace(new RegExp('^' + characters + '+'), '');
+};
+
+},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],34:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function(str, callback) {
+ str = makeString(str);
+
+ if (str.length === 0 || typeof callback !== 'function') return str;
+
+ return str.replace(/./g, callback);
+};
+
+},{"./helper/makeString":21}],35:[function(_dereq_,module,exports){
+module.exports = function naturalCmp(str1, str2) {
+ if (str1 == str2) return 0;
+ if (!str1) return -1;
+ if (!str2) return 1;
+
+ var cmpRegex = /(\.\d+|\d+|\D+)/g,
+ tokens1 = String(str1).match(cmpRegex),
+ tokens2 = String(str2).match(cmpRegex),
+ count = Math.min(tokens1.length, tokens2.length);
+
+ for (var i = 0; i < count; i++) {
+ var a = tokens1[i],
+ b = tokens2[i];
+
+ if (a !== b) {
+ var num1 = +a;
+ var num2 = +b;
+ if (num1 === num1 && num2 === num2) {
+ return num1 > num2 ? 1 : -1;
+ }
+ return a < b ? -1 : 1;
+ }
+ }
+
+ if (tokens1.length != tokens2.length)
+ return tokens1.length - tokens2.length;
+
+ return str1 < str2 ? -1 : 1;
+};
+
+},{}],36:[function(_dereq_,module,exports){
+module.exports = function numberFormat(number, dec, dsep, tsep) {
+ if (isNaN(number) || number == null) return '';
+
+ number = number.toFixed(~~dec);
+ tsep = typeof tsep == 'string' ? tsep : ',';
+
+ var parts = number.split('.'),
+ fnums = parts[0],
+ decimals = parts[1] ? (dsep || '.') + parts[1] : '';
+
+ return fnums.replace(/(\d)(?=(?:\d{3})+$)/g, '$1' + tsep) + decimals;
+};
+
+},{}],37:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var strRepeat = _dereq_('./helper/strRepeat');
+
+module.exports = function pad(str, length, padStr, type) {
+ str = makeString(str);
+ length = ~~length;
+
+ var padlen = 0;
+
+ if (!padStr)
+ padStr = ' ';
+ else if (padStr.length > 1)
+ padStr = padStr.charAt(0);
+
+ switch (type) {
+ case 'right':
+ padlen = length - str.length;
+ return str + strRepeat(padStr, padlen);
+ case 'both':
+ padlen = length - str.length;
+ return strRepeat(padStr, Math.ceil(padlen / 2)) + str + strRepeat(padStr, Math.floor(padlen / 2));
+ default: // 'left'
+ padlen = length - str.length;
+ return strRepeat(padStr, padlen) + str;
+ }
+};
+
+},{"./helper/makeString":21,"./helper/strRepeat":22}],38:[function(_dereq_,module,exports){
+var adjacent = _dereq_('./helper/adjacent');
+
+module.exports = function succ(str) {
+ return adjacent(str, -1);
+};
+
+},{"./helper/adjacent":16}],39:[function(_dereq_,module,exports){
+/**
+ * _s.prune: a more elegant version of truncate
+ * prune extra chars, never leaving a half-chopped word.
+ * @author github.com/rwz
+ */
+var makeString = _dereq_('./helper/makeString');
+var rtrim = _dereq_('./rtrim');
+
+module.exports = function prune(str, length, pruneStr) {
+ str = makeString(str);
+ length = ~~length;
+ pruneStr = pruneStr != null ? String(pruneStr) : '...';
+
+ if (str.length <= length) return str;
+
+ var tmpl = function(c) {
+ return c.toUpperCase() !== c.toLowerCase() ? 'A' : ' ';
+ },
+ template = str.slice(0, length + 1).replace(/.(?=\W*\w*$)/g, tmpl); // 'Hello, world' -> 'HellAA AAAAA'
+
+ if (template.slice(template.length - 2).match(/\w\w/))
+ template = template.replace(/\s*\S+$/, '');
+ else
+ template = rtrim(template.slice(0, template.length - 1));
+
+ return (template + pruneStr).length > str.length ? str : str.slice(0, template.length) + pruneStr;
+};
+
+},{"./helper/makeString":21,"./rtrim":45}],40:[function(_dereq_,module,exports){
+var surround = _dereq_('./surround');
+
+module.exports = function quote(str, quoteChar) {
+ return surround(str, quoteChar || '"');
+};
+
+},{"./surround":56}],41:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var strRepeat = _dereq_('./helper/strRepeat');
+
+module.exports = function repeat(str, qty, separator) {
+ str = makeString(str);
+
+ qty = ~~qty;
+
+ // using faster implementation if separator is not needed;
+ if (separator == null) return strRepeat(str, qty);
+
+ // this one is about 300x slower in Google Chrome
+ /*eslint no-empty: 0*/
+ for (var repeat = []; qty > 0; repeat[--qty] = str) {}
+ return repeat.join(separator);
+};
+
+},{"./helper/makeString":21,"./helper/strRepeat":22}],42:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function replaceAll(str, find, replace, ignorecase) {
+ var flags = (ignorecase === true)?'gi':'g';
+ var reg = new RegExp(find, flags);
+
+ return makeString(str).replace(reg, replace);
+};
+
+},{"./helper/makeString":21}],43:[function(_dereq_,module,exports){
+var chars = _dereq_('./chars');
+
+module.exports = function reverse(str) {
+ return chars(str).reverse().join('');
+};
+
+},{"./chars":3}],44:[function(_dereq_,module,exports){
+var pad = _dereq_('./pad');
+
+module.exports = function rpad(str, length, padStr) {
+ return pad(str, length, padStr, 'right');
+};
+
+},{"./pad":37}],45:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
+var nativeTrimRight = String.prototype.trimRight;
+
+module.exports = function rtrim(str, characters) {
+ str = makeString(str);
+ if (!characters && nativeTrimRight) return nativeTrimRight.call(str);
+ characters = defaultToWhiteSpace(characters);
+ return str.replace(new RegExp(characters + '+$'), '');
+};
+
+},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],46:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+var dasherize = _dereq_('./dasherize');
+var cleanDiacritics = _dereq_("./cleanDiacritics");
+
+module.exports = function slugify(str) {
+ return trim(dasherize(cleanDiacritics(str).replace(/[^\w\s-]/g, '-').toLowerCase()), '-');
+};
+
+},{"./cleanDiacritics":7,"./dasherize":9,"./trim":63}],47:[function(_dereq_,module,exports){
+var chars = _dereq_('./chars');
+
+module.exports = function splice(str, i, howmany, substr) {
+ var arr = chars(str);
+ arr.splice(~~i, ~~howmany, substr);
+ return arr.join('');
+};
+
+},{"./chars":3}],48:[function(_dereq_,module,exports){
+// sprintf() for JavaScript 0.7-beta1
+// http://www.diveintojavascript.com/projects/javascript-sprintf
+//
+// Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
+// All rights reserved.
+var strRepeat = _dereq_('./helper/strRepeat');
+var toString = Object.prototype.toString;
+var sprintf = (function() {
+ function get_type(variable) {
+ return toString.call(variable).slice(8, -1).toLowerCase();
+ }
+
+ var str_repeat = strRepeat;
+
+ var str_format = function() {
+ if (!str_format.cache.hasOwnProperty(arguments[0])) {
+ str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
+ }
+ return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
+ };
+
+ str_format.format = function(parse_tree, argv) {
+ var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
+ for (i = 0; i < tree_length; i++) {
+ node_type = get_type(parse_tree[i]);
+ if (node_type === 'string') {
+ output.push(parse_tree[i]);
+ }
+ else if (node_type === 'array') {
+ match = parse_tree[i]; // convenience purposes only
+ if (match[2]) { // keyword argument
+ arg = argv[cursor];
+ for (k = 0; k < match[2].length; k++) {
+ if (!arg.hasOwnProperty(match[2][k])) {
+ throw new Error(sprintf('[_.sprintf] property "%s" does not exist', match[2][k]));
+ }
+ arg = arg[match[2][k]];
+ }
+ } else if (match[1]) { // positional argument (explicit)
+ arg = argv[match[1]];
+ }
+ else { // positional argument (implicit)
+ arg = argv[cursor++];
+ }
+
+ if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
+ throw new Error(sprintf('[_.sprintf] expecting number but found %s', get_type(arg)));
+ }
+ switch (match[8]) {
+ case 'b': arg = arg.toString(2); break;
+ case 'c': arg = String.fromCharCode(arg); break;
+ case 'd': arg = parseInt(arg, 10); break;
+ case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
+ case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
+ case 'o': arg = arg.toString(8); break;
+ case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
+ case 'u': arg = Math.abs(arg); break;
+ case 'x': arg = arg.toString(16); break;
+ case 'X': arg = arg.toString(16).toUpperCase(); break;
+ }
+ arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
+ pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
+ pad_length = match[6] - String(arg).length;
+ pad = match[6] ? str_repeat(pad_character, pad_length) : '';
+ output.push(match[5] ? arg + pad : pad + arg);
+ }
+ }
+ return output.join('');
+ };
+
+ str_format.cache = {};
+
+ str_format.parse = function(fmt) {
+ var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
+ while (_fmt) {
+ if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
+ parse_tree.push(match[0]);
+ }
+ else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
+ parse_tree.push('%');
+ }
+ else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
+ if (match[2]) {
+ arg_names |= 1;
+ var field_list = [], replacement_field = match[2], field_match = [];
+ if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
+ if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ }
+ else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
+ field_list.push(field_match[1]);
+ }
+ else {
+ throw new Error('[_.sprintf] huh?');
+ }
+ }
+ }
+ else {
+ throw new Error('[_.sprintf] huh?');
+ }
+ match[2] = field_list;
+ }
+ else {
+ arg_names |= 2;
+ }
+ if (arg_names === 3) {
+ throw new Error('[_.sprintf] mixing positional and named placeholders is not (yet) supported');
+ }
+ parse_tree.push(match);
+ }
+ else {
+ throw new Error('[_.sprintf] huh?');
+ }
+ _fmt = _fmt.substring(match[0].length);
+ }
+ return parse_tree;
+ };
+
+ return str_format;
+})();
+
+module.exports = sprintf;
+
+},{"./helper/strRepeat":22}],49:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var toPositive = _dereq_('./helper/toPositive');
+
+module.exports = function startsWith(str, starts, position) {
+ str = makeString(str);
+ starts = '' + starts;
+ position = position == null ? 0 : Math.min(toPositive(position), str.length);
+ return str.lastIndexOf(starts, position) === position;
+};
+
+},{"./helper/makeString":21,"./helper/toPositive":23}],50:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function strLeft(str, sep) {
+ str = makeString(str);
+ sep = makeString(sep);
+ var pos = !sep ? -1 : str.indexOf(sep);
+ return~ pos ? str.slice(0, pos) : str;
+};
+
+},{"./helper/makeString":21}],51:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function strLeftBack(str, sep) {
+ str = makeString(str);
+ sep = makeString(sep);
+ var pos = str.lastIndexOf(sep);
+ return~ pos ? str.slice(0, pos) : str;
+};
+
+},{"./helper/makeString":21}],52:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function strRight(str, sep) {
+ str = makeString(str);
+ sep = makeString(sep);
+ var pos = !sep ? -1 : str.indexOf(sep);
+ return~ pos ? str.slice(pos + sep.length, str.length) : str;
+};
+
+},{"./helper/makeString":21}],53:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function strRightBack(str, sep) {
+ str = makeString(str);
+ sep = makeString(sep);
+ var pos = !sep ? -1 : str.lastIndexOf(sep);
+ return~ pos ? str.slice(pos + sep.length, str.length) : str;
+};
+
+},{"./helper/makeString":21}],54:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function stripTags(str) {
+ return makeString(str).replace(/<\/?[^>]+>/g, '');
+};
+
+},{"./helper/makeString":21}],55:[function(_dereq_,module,exports){
+var adjacent = _dereq_('./helper/adjacent');
+
+module.exports = function succ(str) {
+ return adjacent(str, 1);
+};
+
+},{"./helper/adjacent":16}],56:[function(_dereq_,module,exports){
+module.exports = function surround(str, wrapper) {
+ return [wrapper, str, wrapper].join('');
+};
+
+},{}],57:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function swapCase(str) {
+ return makeString(str).replace(/\S/g, function(c) {
+ return c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase();
+ });
+};
+
+},{"./helper/makeString":21}],58:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function titleize(str) {
+ return makeString(str).toLowerCase().replace(/(?:^|\s|-)\S/g, function(c) {
+ return c.toUpperCase();
+ });
+};
+
+},{"./helper/makeString":21}],59:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+
+function boolMatch(s, matchers) {
+ var i, matcher, down = s.toLowerCase();
+ matchers = [].concat(matchers);
+ for (i = 0; i < matchers.length; i += 1) {
+ matcher = matchers[i];
+ if (!matcher) continue;
+ if (matcher.test && matcher.test(s)) return true;
+ if (matcher.toLowerCase() === down) return true;
+ }
+}
+
+module.exports = function toBoolean(str, trueValues, falseValues) {
+ if (typeof str === "number") str = "" + str;
+ if (typeof str !== "string") return !!str;
+ str = trim(str);
+ if (boolMatch(str, trueValues || ["true", "1"])) return true;
+ if (boolMatch(str, falseValues || ["false", "0"])) return false;
+};
+
+},{"./trim":63}],60:[function(_dereq_,module,exports){
+module.exports = function toNumber(num, precision) {
+ if (num == null) return 0;
+ var factor = Math.pow(10, isFinite(precision) ? precision : 0);
+ return Math.round(num * factor) / factor;
+};
+
+},{}],61:[function(_dereq_,module,exports){
+var rtrim = _dereq_('./rtrim');
+
+module.exports = function toSentence(array, separator, lastSeparator, serial) {
+ separator = separator || ', ';
+ lastSeparator = lastSeparator || ' and ';
+ var a = array.slice(),
+ lastMember = a.pop();
+
+ if (array.length > 2 && serial) lastSeparator = rtrim(separator) + lastSeparator;
+
+ return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
+};
+
+},{"./rtrim":45}],62:[function(_dereq_,module,exports){
+var toSentence = _dereq_('./toSentence');
+
+module.exports = function toSentenceSerial(array, sep, lastSep) {
+ return toSentence(array, sep, lastSep, true);
+};
+
+},{"./toSentence":61}],63:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var defaultToWhiteSpace = _dereq_('./helper/defaultToWhiteSpace');
+var nativeTrim = String.prototype.trim;
+
+module.exports = function trim(str, characters) {
+ str = makeString(str);
+ if (!characters && nativeTrim) return nativeTrim.call(str);
+ characters = defaultToWhiteSpace(characters);
+ return str.replace(new RegExp('^' + characters + '+|' + characters + '+$', 'g'), '');
+};
+
+},{"./helper/defaultToWhiteSpace":17,"./helper/makeString":21}],64:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function truncate(str, length, truncateStr) {
+ str = makeString(str);
+ truncateStr = truncateStr || '...';
+ length = ~~length;
+ return str.length > length ? str.slice(0, length) + truncateStr : str;
+};
+
+},{"./helper/makeString":21}],65:[function(_dereq_,module,exports){
+var trim = _dereq_('./trim');
+
+module.exports = function underscored(str) {
+ return trim(str).replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase();
+};
+
+},{"./trim":63}],66:[function(_dereq_,module,exports){
+var makeString = _dereq_('./helper/makeString');
+var htmlEntities = _dereq_('./helper/htmlEntities');
+
+module.exports = function unescapeHTML(str) {
+ return makeString(str).replace(/\&([^;]+);/g, function(entity, entityCode) {
+ var match;
+
+ if (entityCode in htmlEntities) {
+ return htmlEntities[entityCode];
+ /*eslint no-cond-assign: 0*/
+ } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) {
+ return String.fromCharCode(parseInt(match[1], 16));
+ /*eslint no-cond-assign: 0*/
+ } else if (match = entityCode.match(/^#(\d+)$/)) {
+ return String.fromCharCode(~~match[1]);
+ } else {
+ return entity;
+ }
+ });
+};
+
+},{"./helper/htmlEntities":20,"./helper/makeString":21}],67:[function(_dereq_,module,exports){
+module.exports = function unquote(str, quoteChar) {
+ quoteChar = quoteChar || '"';
+ if (str[0] === quoteChar && str[str.length - 1] === quoteChar)
+ return str.slice(1, str.length - 1);
+ else return str;
+};
+
+},{}],68:[function(_dereq_,module,exports){
+var sprintf = _dereq_('./sprintf');
+
+module.exports = function vsprintf(fmt, argv) {
+ argv.unshift(fmt);
+ return sprintf.apply(null, argv);
+};
+
+},{"./sprintf":48}],69:[function(_dereq_,module,exports){
+var isBlank = _dereq_('./isBlank');
+var trim = _dereq_('./trim');
+
+module.exports = function words(str, delimiter) {
+ if (isBlank(str)) return [];
+ return trim(str, delimiter).split(delimiter || /\s+/);
+};
+
+},{"./isBlank":27,"./trim":63}],70:[function(_dereq_,module,exports){
+// Wrap
+// wraps a string by a certain width
+
+var makeString = _dereq_('./helper/makeString');
+
+module.exports = function wrap(str, options){
+ str = makeString(str);
+
+ options = options || {};
+
+ var width = options.width || 75;
+ var seperator = options.seperator || '\n';
+ var cut = options.cut || false;
+ var preserveSpaces = options.preserveSpaces || false;
+ var trailingSpaces = options.trailingSpaces || false;
+
+ var result;
+
+ if(width <= 0){
+ return str;
+ }
+
+ else if(!cut){
+
+ var words = str.split(" ");
+ var current_column = 0;
+ result = "";
+
+ while(words.length > 0){
+
+ // if adding a space and the next word would cause this line to be longer than width...
+ if(1 + words[0].length + current_column > width){
+ //start a new line if this line is not already empty
+ if(current_column > 0){
+ // add a space at the end of the line is preserveSpaces is true
+ if (preserveSpaces){
+ result += ' ';
+ current_column++;
+ }
+ // fill the rest of the line with spaces if trailingSpaces option is true
+ else if(trailingSpaces){
+ while(current_column < width){
+ result += ' ';
+ current_column++;
+ }
+ }
+ //start new line
+ result += seperator;
+ current_column = 0;
+ }
+ }
+
+ // if not at the begining of the line, add a space in front of the word
+ if(current_column > 0){
+ result += " ";
+ current_column++;
+ }
+
+ // tack on the next word, update current column, a pop words array
+ result += words[0];
+ current_column += words[0].length;
+ words.shift();
+
+ }
+
+ // fill the rest of the line with spaces if trailingSpaces option is true
+ if(trailingSpaces){
+ while(current_column < width){
+ result += ' ';
+ current_column++;
+ }
+ }
+
+ return result;
+
+ }
+
+ else {
+
+ var index = 0;
+ result = "";
+
+ // walk through each character and add seperators where appropriate
+ while(index < str.length){
+ if(index % width == 0 && index > 0){
+ result += seperator;
+ }
+ result += str.charAt(index);
+ index++;
+ }
+
+ // fill the rest of the line with spaces if trailingSpaces option is true
+ if(trailingSpaces){
+ while(index % width > 0){
+ result += ' ';
+ index++;
+ }
+ }
+
+ return result;
+ }
+};
+
+},{"./helper/makeString":21}]},{},[15])
+(15)
+});
\ No newline at end of file