stringify.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642
  1. (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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.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(require,module,exports){
  2. (function (process){
  3. var stringify = require('json-stable-stringify');
  4. // expose function for client-side version
  5. if (process.browser) {
  6. window.stringify = stringify;
  7. } else {
  8. module.exports = stringify;
  9. }
  10. }).call(this,require('_process'))
  11. },{"_process":6,"json-stable-stringify":2}],2:[function(require,module,exports){
  12. var json = typeof JSON !== 'undefined' ? JSON : require('jsonify');
  13. module.exports = function (obj, opts) {
  14. if (!opts) opts = {};
  15. if (typeof opts === 'function') opts = { cmp: opts };
  16. var space = opts.space || '';
  17. var separators = opts.separators || { item_separator : ',', key_separator : ':' };
  18. var ascii = opts.ascii || false;
  19. if (typeof space === 'number') space = Array(space+1).join(' ');
  20. var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;
  21. var replacer = opts.replacer || function(key, value) { return value; };
  22. var cmp = opts.cmp && (function (f) {
  23. return function (node) {
  24. return function (a, b) {
  25. var aobj = { key: a, value: node[a] };
  26. var bobj = { key: b, value: node[b] };
  27. return f(aobj, bobj);
  28. };
  29. };
  30. })(opts.cmp);
  31. var seen = [];
  32. return (function stringify (parent, key, node, level) {
  33. var indent = space ? ('\n' + new Array(level + 1).join(space)) : '';
  34. var colonSeparator = separators.key_separator;
  35. if (node && node.toJSON && typeof node.toJSON === 'function') {
  36. node = node.toJSON();
  37. }
  38. node = replacer.call(parent, key, node);
  39. if (node === undefined) {
  40. return;
  41. }
  42. if (typeof node !== 'object' || node === null) {
  43. var result = node;
  44. if (ascii) {
  45. result = toAscii(node);
  46. }
  47. if (result === node) {
  48. return json.stringify(node);
  49. }
  50. else {
  51. return '"' + result + '"';
  52. }
  53. }
  54. if (isArray(node)) {
  55. var out = [];
  56. for (var i = 0; i < node.length; i++) {
  57. var item = stringify(node, i, node[i], level+1) || json.stringify(null);
  58. out.push(indent + space + item);
  59. }
  60. return out.length ? '[' + out.join(separators.item_separator) + indent + ']' : '[]';
  61. }
  62. else {
  63. if (seen.indexOf(node) !== -1) {
  64. if (cycles) return json.stringify('__cycle__');
  65. throw new TypeError('Converting circular structure to JSON');
  66. }
  67. else seen.push(node);
  68. var keys = objectKeys(node).sort(cmp && cmp(node));
  69. var out = [];
  70. for (var i = 0; i < keys.length; i++) {
  71. var key = keys[i];
  72. var value = stringify(node, key, node[key], level+1);
  73. if(!value) continue;
  74. var jsonkey = key;
  75. if (ascii) {
  76. jsonkey = toAscii(key);
  77. }
  78. if (jsonkey === key) {
  79. jsonkey = json.stringify(key);
  80. }
  81. else {
  82. jsonkey = '"' + jsonkey + '"';
  83. }
  84. var keyValue = jsonkey
  85. + colonSeparator
  86. + value;
  87. out.push(indent + space + keyValue);
  88. }
  89. return '{' + out.join(separators.item_separator) + indent + '}';
  90. }
  91. })({ '': obj }, '', obj, 0);
  92. };
  93. var isArray = Array.isArray || function (x) {
  94. return {}.toString.call(x) === '[object Array]';
  95. };
  96. var objectKeys = Object.keys || function (obj) {
  97. var has = Object.prototype.hasOwnProperty || function () { return true };
  98. var keys = [];
  99. for (var key in obj) {
  100. if (has.call(obj, key)) keys.push(key);
  101. }
  102. return keys;
  103. };
  104. var toAscii = function(str) {
  105. var length = str.length,
  106. index = -1,
  107. result = '',
  108. character, charCode, hexadecimal, escaped;
  109. while (++index < length) {
  110. character = str.charAt(index);
  111. charCode = character.charCodeAt(0);
  112. if (charCode > 127) {
  113. hexadecimal = charCode.toString(16).toUpperCase();
  114. escaped = '\\u' + ('0000' + hexadecimal).slice(-4);
  115. result += escaped;
  116. }
  117. else {
  118. result += character;
  119. }
  120. }
  121. return result;
  122. }
  123. },{"jsonify":3}],3:[function(require,module,exports){
  124. exports.parse = require('./lib/parse');
  125. exports.stringify = require('./lib/stringify');
  126. },{"./lib/parse":4,"./lib/stringify":5}],4:[function(require,module,exports){
  127. var at, // The index of the current character
  128. ch, // The current character
  129. escapee = {
  130. '"': '"',
  131. '\\': '\\',
  132. '/': '/',
  133. b: '\b',
  134. f: '\f',
  135. n: '\n',
  136. r: '\r',
  137. t: '\t'
  138. },
  139. text,
  140. error = function (m) {
  141. // Call error when something is wrong.
  142. throw {
  143. name: 'SyntaxError',
  144. message: m,
  145. at: at,
  146. text: text
  147. };
  148. },
  149. next = function (c) {
  150. // If a c parameter is provided, verify that it matches the current character.
  151. if (c && c !== ch) {
  152. error("Expected '" + c + "' instead of '" + ch + "'");
  153. }
  154. // Get the next character. When there are no more characters,
  155. // return the empty string.
  156. ch = text.charAt(at);
  157. at += 1;
  158. return ch;
  159. },
  160. number = function () {
  161. // Parse a number value.
  162. var number,
  163. string = '';
  164. if (ch === '-') {
  165. string = '-';
  166. next('-');
  167. }
  168. while (ch >= '0' && ch <= '9') {
  169. string += ch;
  170. next();
  171. }
  172. if (ch === '.') {
  173. string += '.';
  174. while (next() && ch >= '0' && ch <= '9') {
  175. string += ch;
  176. }
  177. }
  178. if (ch === 'e' || ch === 'E') {
  179. string += ch;
  180. next();
  181. if (ch === '-' || ch === '+') {
  182. string += ch;
  183. next();
  184. }
  185. while (ch >= '0' && ch <= '9') {
  186. string += ch;
  187. next();
  188. }
  189. }
  190. number = +string;
  191. if (!isFinite(number)) {
  192. error("Bad number");
  193. } else {
  194. return number;
  195. }
  196. },
  197. string = function () {
  198. // Parse a string value.
  199. var hex,
  200. i,
  201. string = '',
  202. uffff;
  203. // When parsing for string values, we must look for " and \ characters.
  204. if (ch === '"') {
  205. while (next()) {
  206. if (ch === '"') {
  207. next();
  208. return string;
  209. } else if (ch === '\\') {
  210. next();
  211. if (ch === 'u') {
  212. uffff = 0;
  213. for (i = 0; i < 4; i += 1) {
  214. hex = parseInt(next(), 16);
  215. if (!isFinite(hex)) {
  216. break;
  217. }
  218. uffff = uffff * 16 + hex;
  219. }
  220. string += String.fromCharCode(uffff);
  221. } else if (typeof escapee[ch] === 'string') {
  222. string += escapee[ch];
  223. } else {
  224. break;
  225. }
  226. } else {
  227. string += ch;
  228. }
  229. }
  230. }
  231. error("Bad string");
  232. },
  233. white = function () {
  234. // Skip whitespace.
  235. while (ch && ch <= ' ') {
  236. next();
  237. }
  238. },
  239. word = function () {
  240. // true, false, or null.
  241. switch (ch) {
  242. case 't':
  243. next('t');
  244. next('r');
  245. next('u');
  246. next('e');
  247. return true;
  248. case 'f':
  249. next('f');
  250. next('a');
  251. next('l');
  252. next('s');
  253. next('e');
  254. return false;
  255. case 'n':
  256. next('n');
  257. next('u');
  258. next('l');
  259. next('l');
  260. return null;
  261. }
  262. error("Unexpected '" + ch + "'");
  263. },
  264. value, // Place holder for the value function.
  265. array = function () {
  266. // Parse an array value.
  267. var array = [];
  268. if (ch === '[') {
  269. next('[');
  270. white();
  271. if (ch === ']') {
  272. next(']');
  273. return array; // empty array
  274. }
  275. while (ch) {
  276. array.push(value());
  277. white();
  278. if (ch === ']') {
  279. next(']');
  280. return array;
  281. }
  282. next(',');
  283. white();
  284. }
  285. }
  286. error("Bad array");
  287. },
  288. object = function () {
  289. // Parse an object value.
  290. var key,
  291. object = {};
  292. if (ch === '{') {
  293. next('{');
  294. white();
  295. if (ch === '}') {
  296. next('}');
  297. return object; // empty object
  298. }
  299. while (ch) {
  300. key = string();
  301. white();
  302. next(':');
  303. if (Object.hasOwnProperty.call(object, key)) {
  304. error('Duplicate key "' + key + '"');
  305. }
  306. object[key] = value();
  307. white();
  308. if (ch === '}') {
  309. next('}');
  310. return object;
  311. }
  312. next(',');
  313. white();
  314. }
  315. }
  316. error("Bad object");
  317. };
  318. value = function () {
  319. // Parse a JSON value. It could be an object, an array, a string, a number,
  320. // or a word.
  321. white();
  322. switch (ch) {
  323. case '{':
  324. return object();
  325. case '[':
  326. return array();
  327. case '"':
  328. return string();
  329. case '-':
  330. return number();
  331. default:
  332. return ch >= '0' && ch <= '9' ? number() : word();
  333. }
  334. };
  335. // Return the json_parse function. It will have access to all of the above
  336. // functions and variables.
  337. module.exports = function (source, reviver) {
  338. var result;
  339. text = source;
  340. at = 0;
  341. ch = ' ';
  342. result = value();
  343. white();
  344. if (ch) {
  345. error("Syntax error");
  346. }
  347. // If there is a reviver function, we recursively walk the new structure,
  348. // passing each name/value pair to the reviver function for possible
  349. // transformation, starting with a temporary root object that holds the result
  350. // in an empty key. If there is not a reviver function, we simply return the
  351. // result.
  352. return typeof reviver === 'function' ? (function walk(holder, key) {
  353. var k, v, value = holder[key];
  354. if (value && typeof value === 'object') {
  355. for (k in value) {
  356. if (Object.prototype.hasOwnProperty.call(value, k)) {
  357. v = walk(value, k);
  358. if (v !== undefined) {
  359. value[k] = v;
  360. } else {
  361. delete value[k];
  362. }
  363. }
  364. }
  365. }
  366. return reviver.call(holder, key, value);
  367. }({'': result}, '')) : result;
  368. };
  369. },{}],5:[function(require,module,exports){
  370. var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  371. escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
  372. gap,
  373. indent,
  374. meta = { // table of character substitutions
  375. '\b': '\\b',
  376. '\t': '\\t',
  377. '\n': '\\n',
  378. '\f': '\\f',
  379. '\r': '\\r',
  380. '"' : '\\"',
  381. '\\': '\\\\'
  382. },
  383. rep;
  384. function quote(string) {
  385. // If the string contains no control characters, no quote characters, and no
  386. // backslash characters, then we can safely slap some quotes around it.
  387. // Otherwise we must also replace the offending characters with safe escape
  388. // sequences.
  389. escapable.lastIndex = 0;
  390. return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
  391. var c = meta[a];
  392. return typeof c === 'string' ? c :
  393. '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
  394. }) + '"' : '"' + string + '"';
  395. }
  396. function str(key, holder) {
  397. // Produce a string from holder[key].
  398. var i, // The loop counter.
  399. k, // The member key.
  400. v, // The member value.
  401. length,
  402. mind = gap,
  403. partial,
  404. value = holder[key];
  405. // If the value has a toJSON method, call it to obtain a replacement value.
  406. if (value && typeof value === 'object' &&
  407. typeof value.toJSON === 'function') {
  408. value = value.toJSON(key);
  409. }
  410. // If we were called with a replacer function, then call the replacer to
  411. // obtain a replacement value.
  412. if (typeof rep === 'function') {
  413. value = rep.call(holder, key, value);
  414. }
  415. // What happens next depends on the value's type.
  416. switch (typeof value) {
  417. case 'string':
  418. return quote(value);
  419. case 'number':
  420. // JSON numbers must be finite. Encode non-finite numbers as null.
  421. return isFinite(value) ? String(value) : 'null';
  422. case 'boolean':
  423. case 'null':
  424. // If the value is a boolean or null, convert it to a string. Note:
  425. // typeof null does not produce 'null'. The case is included here in
  426. // the remote chance that this gets fixed someday.
  427. return String(value);
  428. case 'object':
  429. if (!value) return 'null';
  430. gap += indent;
  431. partial = [];
  432. // Array.isArray
  433. if (Object.prototype.toString.apply(value) === '[object Array]') {
  434. length = value.length;
  435. for (i = 0; i < length; i += 1) {
  436. partial[i] = str(i, value) || 'null';
  437. }
  438. // Join all of the elements together, separated with commas, and
  439. // wrap them in brackets.
  440. v = partial.length === 0 ? '[]' : gap ?
  441. '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
  442. '[' + partial.join(',') + ']';
  443. gap = mind;
  444. return v;
  445. }
  446. // If the replacer is an array, use it to select the members to be
  447. // stringified.
  448. if (rep && typeof rep === 'object') {
  449. length = rep.length;
  450. for (i = 0; i < length; i += 1) {
  451. k = rep[i];
  452. if (typeof k === 'string') {
  453. v = str(k, value);
  454. if (v) {
  455. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  456. }
  457. }
  458. }
  459. }
  460. else {
  461. // Otherwise, iterate through all of the keys in the object.
  462. for (k in value) {
  463. if (Object.prototype.hasOwnProperty.call(value, k)) {
  464. v = str(k, value);
  465. if (v) {
  466. partial.push(quote(k) + (gap ? ': ' : ':') + v);
  467. }
  468. }
  469. }
  470. }
  471. // Join all of the member texts together, separated with commas,
  472. // and wrap them in braces.
  473. v = partial.length === 0 ? '{}' : gap ?
  474. '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
  475. '{' + partial.join(',') + '}';
  476. gap = mind;
  477. return v;
  478. }
  479. }
  480. module.exports = function (value, replacer, space) {
  481. var i;
  482. gap = '';
  483. indent = '';
  484. // If the space parameter is a number, make an indent string containing that
  485. // many spaces.
  486. if (typeof space === 'number') {
  487. for (i = 0; i < space; i += 1) {
  488. indent += ' ';
  489. }
  490. }
  491. // If the space parameter is a string, it will be used as the indent string.
  492. else if (typeof space === 'string') {
  493. indent = space;
  494. }
  495. // If there is a replacer, it must be a function or an array.
  496. // Otherwise, throw an error.
  497. rep = replacer;
  498. if (replacer && typeof replacer !== 'function'
  499. && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
  500. throw new Error('JSON.stringify');
  501. }
  502. // Make a fake root object containing our value under the key of ''.
  503. // Return the result of stringifying the value.
  504. return str('', {'': value});
  505. };
  506. },{}],6:[function(require,module,exports){
  507. // shim for using process in browser
  508. var process = module.exports = {};
  509. process.nextTick = (function () {
  510. var canSetImmediate = typeof window !== 'undefined'
  511. && window.setImmediate;
  512. var canPost = typeof window !== 'undefined'
  513. && window.postMessage && window.addEventListener
  514. ;
  515. if (canSetImmediate) {
  516. return function (f) { return window.setImmediate(f) };
  517. }
  518. if (canPost) {
  519. var queue = [];
  520. window.addEventListener('message', function (ev) {
  521. var source = ev.source;
  522. if ((source === window || source === null) && ev.data === 'process-tick') {
  523. ev.stopPropagation();
  524. if (queue.length > 0) {
  525. var fn = queue.shift();
  526. fn();
  527. }
  528. }
  529. }, true);
  530. return function nextTick(fn) {
  531. queue.push(fn);
  532. window.postMessage('process-tick', '*');
  533. };
  534. }
  535. return function nextTick(fn) {
  536. setTimeout(fn, 0);
  537. };
  538. })();
  539. process.title = 'browser';
  540. process.browser = true;
  541. process.env = {};
  542. process.argv = [];
  543. function noop() {}
  544. process.on = noop;
  545. process.addListener = noop;
  546. process.once = noop;
  547. process.off = noop;
  548. process.removeListener = noop;
  549. process.removeAllListeners = noop;
  550. process.emit = noop;
  551. process.binding = function (name) {
  552. throw new Error('process.binding is not supported');
  553. }
  554. // TODO(shtylman)
  555. process.cwd = function () { return '/' };
  556. process.chdir = function (dir) {
  557. throw new Error('process.chdir is not supported');
  558. };
  559. },{}]},{},[1]);