UNPKG

@luminati-io/luminati-proxy

Version:

A configurable local proxy for luminati.io

408 lines (401 loc) 15.7 kB
// LICENSE_CODE ZON ISC 'use strict'; /*zlint node, br*/ (function(){ var define; var is_node_ff = typeof module=='object' && module.exports; if (!is_node_ff) define = self.define; else define = require('./require_node.js').define(module, '../'); define([], function(){ var E = sprintf; E.sprintf = sprintf; var has = Object.prototype.hasOwnProperty; function sprintf(fmt /* args... */){ if (has.call(E.cache, fmt)) return E.cache[fmt](arguments); E.cache[fmt] = E.parse(fmt); E.cache_n++; if (E.cache_cb) E.cache_cb(fmt); return E.cache[fmt](arguments); } E.cache = {}; E.cache_n = 0; E.to_int = function(num){ return (num = +num)>=0 ? Math.floor(num) : -Math.floor(-num); }; E.thousand_grouping = function(num_s){ var m = /^([-+])?(\d*)(\.\d*)?$/.exec(num_s); if (!m) return num_s; m[2] = (m[2]||'').replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); return (m[1]||'')+m[2]+(m[3]||''); }; // non-throwing implementation of JSON.stringify(). main differences: // - doesn't throw when a cycle is detected, instead inserts the string // '__CIRCULAR__' as value for the property with back-reference // - ignores 'space' argument // - doesn't throw when a getter throws, instead inserts the string // '__ERROR__: XXX' where XXX is the error message // mostly a line-by-line translation to JS of the spec omitting formatting // https://www.ecma-international.org/ecma-262/6.0/#sec-json.stringify E.stringify = function(value, replacer){ if (is_array(replacer)) { var r = {}, v; for (var i=0, l=replacer.length; i<l; i++) { v = value_of(replacer[i]); if (typeof v=='string' || typeof v=='number') r[v] = true; } replacer = r; } else if (typeof replacer!='function') replacer = undefined; return _stringify('', {'': value}, replacer, []); }; function json_escape(str){ return JSON.stringify(str); } function _stringify(key, holder, replacer, stack){ var value; try { value = holder[key]; } catch(e){ value = '__ERROR__: '+e; } if (value && typeof value=='object' && typeof value.toJSON=='function') value = value.toJSON(key); if (typeof replacer=='function') value = replacer.call(holder, key, value); value = value_of(value); switch (typeof value) { case 'boolean': return value ? 'true' : 'false'; case 'string': return json_escape(value); case 'number': return Number.isFinite(value) ? json_escape(value) : 'null'; case 'object': if (value===null) return 'null'; if (stack.indexOf(value)>=0) return '"__CIRCULAR__"'; stack.push(value); var s, a = [], p, ret; if (is_array(value)) { for (var i=0, l=value.length; i<l; i++) { s = _stringify(''+i, value, replacer, stack); a.push(s==null ? 'null' : s); } ret = '['+a.join(',')+']'; } else { for (p in value) { if (!has.call(value, p)) continue; if (typeof replacer=='object' && !replacer[p]) continue; if ((s = _stringify(p, value, replacer, stack))!=null) a.push(json_escape(p)+':'+s); } ret = '{'+a.join(',')+'}'; } stack.pop(); return ret; default: return undefined; } } function value_of(v){ return typeof v=='object' && (v instanceof Number || v instanceof String || v instanceof Boolean) ? v.valueOf() : v; } function is_array(a){ return Object.prototype.toString.call(a)=='[object Array]'; } function stringify(value){ try { return JSON.stringify(value); } catch(e){ return E.stringify(value); } } E.parse_fast = function(fmt){ var _fmt = fmt, match = [], arg_names = 0, cursor = 1; var pad_chr, pad_chrs, arg_padded, f, s = stringify; f = 'var out = "", arg, arg_s, sign;\n'; for (; _fmt; _fmt = _fmt.substring(match[0].length)) { if (match = /^[^%]+/.exec(_fmt)) f += 'out += '+s(match[0])+';\n'; else if (match = /^%%/.exec(_fmt)) f += 'out += "%";\n'; else if ((match = /^%(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?(')?([bcdefoOsuxX])/ .exec(_fmt))) { var positional = match[1], keyword = match[2], sign = match[3]; var pad_zero = match[4], pad_min = match[5], pad_max = match[6]; var precision = match[7], thousand_grouping = match[8]=="'"; var conversion = match[9], keyword_list = []; if (keyword) { arg_names |= 1; var _keyword = keyword, kmatch; if (!(kmatch = /^([a-z_][a-z_\d]*)/i.exec(_keyword))) throw 'sprintf: invalid keyword property name '+_keyword; keyword_list.push(kmatch[1]); while (_keyword = _keyword.substring(kmatch[0].length)) { if (kmatch = /^\.([a-z_][a-z_\d]*)/i.exec(_keyword)) keyword_list.push(kmatch[1]); else if (kmatch = /^\[(\d+)\]/.exec(_keyword)) keyword_list.push(kmatch[1]); else throw 'sprintf: invalid keyword format '+_keyword; } } else arg_names |= 2; if (arg_names===3) { throw 'sprintf: mixing positional and named placeholders is ' +'not (yet) supported'; } f += 'sign = false;\n'; if (keyword_list.length) // keyword argument { f += 'arg = argv['+cursor+']'; for (var k = 0; k < keyword_list.length; k++) f += '['+s(keyword_list[k])+']'; f += ';\n'; } else if (positional) // positional argument (explicit) f += 'arg = argv['+positional+'];\n'; else // positional argument (implicit) f += 'arg = argv['+(cursor++)+'];\n'; if (/[^sO]/.test(conversion)) f += 'arg = +arg;\n'; switch (conversion) { case 'b': f += 'arg_s = arg.toString(2);\n'; break; case 'c': f += 'arg_s = String.fromCharCode(arg);\n'; break; case 'd': f += 'arg = sprintf.to_int(arg); arg_s = ""+arg;\n'; if (thousand_grouping) f += 'arg_s = sprintf.thousand_grouping(arg_s);\n'; break; case 'e': f += 'arg_s = arg.toExponential(' +(precision ? s(precision) : '')+');\n'; break; case 'f': if (precision) f += 'arg_s = arg.toFixed('+precision+');\n'; else f += 'arg_s = ""+arg;\n'; if (thousand_grouping) f += 'arg_s = sprintf.thousand_grouping(arg_s);\n'; break; case 'o': f += 'arg_s = arg.toString(8);\n'; break; case 'O': f += 'arg_s = stringify(arg);\n'; break; case 'u': f += 'arg = arg >>> 0; arg_s = ""+arg;\n'; break; case 'x': f += 'arg_s = arg.toString(16);\n'; break; case 'X': f += 'arg_s = arg.toString(16).toUpperCase();\n'; break; case 's': f += 'arg_s = ""+arg;\n'; if (precision) f += 'arg_s = arg_s.substring(0, '+precision+');\n'; break; } if (/[def]/.test(conversion)) { if (sign) f += 'if (arg>=0) arg_s = "+"+arg_s;\n'; f += 'sign = arg_s[0]=="-" || arg_s[0]=="+";\n'; } pad_chr = !pad_zero ? ' ' : pad_zero=='0' ? '0' : pad_zero[1]; pad_chrs = s(pad_chr) +'.repeat(Math.max('+(+pad_max)+'-arg_s.length, 0))'; arg_padded = !pad_max ? 'arg_s' : pad_min ? 'arg_s+'+pad_chrs : /[def]/.test(conversion) && pad_chr=='0' ? '(sign ? arg_s[0]+'+pad_chrs+'+arg_s.slice(1) : ' +pad_chrs+'+arg_s)' : pad_chrs+'+arg_s'; f += 'out += '+arg_padded+';\n'; } else throw 'sprintf invalid format '+_fmt; } f += 'return out;\n'; return new Function(['sprintf', 'stringify', 'argv'], f) .bind(null, sprintf, stringify); }; // slow version for Firefox extention where new Function() is not allowed E.parse_slow = function(fmt){ var _fmt = fmt, match = [], arg_names = 0, cursor = 1; var _f = [], out, arg, arg_s, argv, sign; function f(fn){ _f.push(fn); } for (; _fmt; _fmt = _fmt.substring(match[0].length)) { (function(){ if (match = /^[^%]+/.exec(_fmt)) { var _match = match; f(function(){ return out += _match[0]; }); } else if (match = /^%%/.exec(_fmt)) f(function(){ return out += '%'; }); else if ((match = /^%(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?(')?([bcdefoOsuxX])/ .exec(_fmt))) { var positional = match[1], keyword = match[2], sign = match[3]; var pad_zero = match[4], pad_min = match[5]; var pad_max = match[6]; var precision = match[7], thousand_grouping = match[8]=="'"; var conversion = match[9], keyword_list = [], _cursor = cursor; if (keyword) { arg_names |= 1; var _keyword = keyword, kmatch; if (!(kmatch = /^([a-z_][a-z_\d]*)/i.exec(_keyword))) { throw 'sprintf: invalid keyword property name ' +_keyword; } keyword_list.push(kmatch[1]); while (_keyword = _keyword.substring(kmatch[0].length)) { if (kmatch = /^\.([a-z_][a-z_\d]*)/i.exec(_keyword)) keyword_list.push(kmatch[1]); else if (kmatch = /^\[(\d+)\]/.exec(_keyword)) keyword_list.push(kmatch[1]); else throw 'sprintf: invalid keyword format '+_keyword; } } else arg_names |= 2; if (arg_names===3) { throw 'sprintf: mixing positional and named placeholders' +' is not (yet) supported'; } f(function(){ sign = false; }); if (keyword_list.length) // keyword argument { f(function(){ arg = argv[_cursor]; for (var k = 0; k < keyword_list.length && arg!=null; k++) { arg = arg[keyword_list[k]]; } }); } else if (positional) // positional argument (explicit) f(function(){ arg = argv[positional]; }); else // positional argument (implicit) { f(function(){ arg = argv[_cursor]; }); cursor++; } if (/[^sO]/.test(conversion)) f(function(){ return arg = +arg; }); switch (conversion) { case 'b': f(function(){ arg_s = arg.toString(2); }); break; case 'c': f(function(){ arg_s = String.fromCharCode(arg); }); break; case 'd': f(function(){ arg = sprintf.to_int(arg); arg_s = ''+arg; }); if (thousand_grouping) { f(function(){ arg_s = sprintf.thousand_grouping(arg_s); }); } break; case 'e': f(function(){ arg_s = arg.toExponential( precision ? precision : undefined); }); break; case 'f': if (precision) f(function(){ arg_s = arg.toFixed(precision); }); else f(function(){ arg_s = ''+arg; }); if (thousand_grouping) { f(function(){ arg_s = sprintf.thousand_grouping(arg_s); }); } break; case 'o': f(function(){ arg_s = arg.toString(8); }); break; case 'O': f(function(){ arg_s = stringify(arg); }); break; case 'u': f(function(){ arg = arg >>> 0; arg_s = ''+arg; }); break; case 'x': f(function(){ arg_s = arg.toString(16); }); break; case 'X': f(function(){ arg_s = arg.toString(16).toUpperCase(); }); break; case 's': f(function(){ arg_s = ''+arg; }); if (precision) { f(function(){ arg_s = arg_s.substring(0, precision); }); } break; } if (/[def]/.test(conversion)) { if (sign) { f(function(){ if (arg>=0) arg_s = '+'+arg_s; }); } f(function(){ sign = arg_s[0]=='-' || arg_s[0]=='+'; }); } var pad_chr = !pad_zero ? ' ' : pad_zero=='0' ? '0' : pad_zero[1]; f(function(){ var pad_chrs = pad_chr.repeat( Math.max(+pad_max-arg_s.length, 0)); var arg_padded = !pad_max ? arg_s : pad_min ? arg_s+pad_chrs : sign && pad_chr[0]=='0' ? arg_s[0]+pad_chrs+arg_s.slice(1) : pad_chrs+arg_s; out += arg_padded; }); } else throw 'sprintf invalid format '+_fmt; })(); } return function(_argv){ argv = _argv; out = ''; for (var i=0; i<_f.length; i++) _f[i](argv); return out; }; }; E.parse = (function(){ try { if (new Function('return 1')()==1) return E.parse_fast; } catch(e){} return E.parse_slow; // capp does not support new Function() })(); E.vsprintf = function(fmt, argv, opt){ if (opt) { if (opt.fast) return E.parse_fast(fmt)([fmt].concat(argv)); if (opt.slow) return E.parse_slow(fmt)([fmt].concat(argv)); } return E.sprintf.apply(null, [fmt].concat(argv)); }; return E; }); }());