Commit 199c8068cdba50d9a6871e20fbc74e513514ecc8

Authored by Andrew Buss
1 parent cb9bedfcdf
Exists in master

included bind shim

Showing 4 changed files with 1554 additions and 1 deletions Side-by-side Diff

... ... @@ -34,7 +34,7 @@
34 34  
35 35 built/screenshots/: .PHONY
36 36 mkdir -p built/screenshots
37   - cd built/screenshots; casperjs --ssl-protocol=tlsv1 ../../ss_test.js
  37 + casperjs --ssl-protocol=tlsv1 take_screenshots.js
38 38  
39 39 .PHONY:
40 40  
Diff suppressed. Click to show
  1 +/*!
  2 + * https://github.com/es-shims/es5-shim
  3 + * @license es5-shim Copyright 2009-2015 by contributors, MIT License
  4 + * see https://github.com/es-shims/es5-shim/blob/master/LICENSE
  5 + */
  6 +
  7 +// vim: ts=4 sts=4 sw=4 expandtab
  8 +
  9 +// Add semicolon to prevent IIFE from being passed as argument to concatenated code.
  10 +;
  11 +
  12 +// UMD (Universal Module Definition)
  13 +// see https://github.com/umdjs/umd/blob/master/returnExports.js
  14 +(function (root, factory) {
  15 + 'use strict';
  16 +
  17 + /*global define, exports, module */
  18 + if (typeof define === 'function' && define.amd) {
  19 + // AMD. Register as an anonymous module.
  20 + define(factory);
  21 + } else if (typeof exports === 'object') {
  22 + // Node. Does not work with strict CommonJS, but
  23 + // only CommonJS-like enviroments that support module.exports,
  24 + // like Node.
  25 + module.exports = factory();
  26 + } else {
  27 + // Browser globals (root is window)
  28 + root.returnExports = factory();
  29 + }
  30 +}(this, function () {
  31 +
  32 +/**
  33 + * Brings an environment as close to ECMAScript 5 compliance
  34 + * as is possible with the facilities of erstwhile engines.
  35 + *
  36 + * Annotated ES5: http://es5.github.com/ (specific links below)
  37 + * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
  38 + * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
  39 + */
  40 +
  41 +// Shortcut to an often accessed properties, in order to avoid multiple
  42 +// dereference that costs universally.
  43 +var ArrayPrototype = Array.prototype;
  44 +var ObjectPrototype = Object.prototype;
  45 +var FunctionPrototype = Function.prototype;
  46 +var StringPrototype = String.prototype;
  47 +var NumberPrototype = Number.prototype;
  48 +var array_slice = ArrayPrototype.slice;
  49 +var array_splice = ArrayPrototype.splice;
  50 +var array_push = ArrayPrototype.push;
  51 +var array_unshift = ArrayPrototype.unshift;
  52 +var call = FunctionPrototype.call;
  53 +
  54 +// Having a toString local variable name breaks in Opera so use to_string.
  55 +var to_string = ObjectPrototype.toString;
  56 +
  57 +var isArray = Array.isArray || function isArray(obj) {
  58 + return to_string.call(obj) === '[object Array]';
  59 +};
  60 +
  61 +var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol';
  62 +var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; };
  63 +var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; };
  64 +var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; };
  65 +
  66 +var isArguments = function isArguments(value) {
  67 + var str = to_string.call(value);
  68 + var isArgs = str === '[object Arguments]';
  69 + if (!isArgs) {
  70 + isArgs = !isArray(value) &&
  71 + value !== null &&
  72 + typeof value === 'object' &&
  73 + typeof value.length === 'number' &&
  74 + value.length >= 0 &&
  75 + isCallable(value.callee);
  76 + }
  77 + return isArgs;
  78 +};
  79 +
  80 +/* inlined from http://npmjs.com/define-properties */
  81 +var defineProperties = (function (has) {
  82 + var supportsDescriptors = Object.defineProperty && (function () {
  83 + try {
  84 + Object.defineProperty({}, 'x', {});
  85 + return true;
  86 + } catch (e) { /* this is ES3 */
  87 + return false;
  88 + }
  89 + }());
  90 +
  91 + // Define configurable, writable and non-enumerable props
  92 + // if they don't exist.
  93 + var defineProperty;
  94 + if (supportsDescriptors) {
  95 + defineProperty = function (object, name, method, forceAssign) {
  96 + if (!forceAssign && (name in object)) { return; }
  97 + Object.defineProperty(object, name, {
  98 + configurable: true,
  99 + enumerable: false,
  100 + writable: true,
  101 + value: method
  102 + });
  103 + };
  104 + } else {
  105 + defineProperty = function (object, name, method, forceAssign) {
  106 + if (!forceAssign && (name in object)) { return; }
  107 + object[name] = method;
  108 + };
  109 + }
  110 + return function defineProperties(object, map, forceAssign) {
  111 + for (var name in map) {
  112 + if (has.call(map, name)) {
  113 + defineProperty(object, name, map[name], forceAssign);
  114 + }
  115 + }
  116 + };
  117 +}(ObjectPrototype.hasOwnProperty));
  118 +
  119 +//
  120 +// Util
  121 +// ======
  122 +//
  123 +
  124 +/* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */
  125 +var isPrimitive = function isPrimitive(input) {
  126 + var type = typeof input;
  127 + return input === null || (type !== 'object' && type !== 'function');
  128 +};
  129 +
  130 +var ES = {
  131 + // ES5 9.4
  132 + // http://es5.github.com/#x9.4
  133 + // http://jsperf.com/to-integer
  134 + /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */
  135 + ToInteger: function ToInteger(num) {
  136 + var n = +num;
  137 + if (n !== n) { // isNaN
  138 + n = 0;
  139 + } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) {
  140 + n = (n > 0 || -1) * Math.floor(Math.abs(n));
  141 + }
  142 + return n;
  143 + },
  144 +
  145 + /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */
  146 + ToPrimitive: function ToPrimitive(input) {
  147 + var val, valueOf, toStr;
  148 + if (isPrimitive(input)) {
  149 + return input;
  150 + }
  151 + valueOf = input.valueOf;
  152 + if (isCallable(valueOf)) {
  153 + val = valueOf.call(input);
  154 + if (isPrimitive(val)) {
  155 + return val;
  156 + }
  157 + }
  158 + toStr = input.toString;
  159 + if (isCallable(toStr)) {
  160 + val = toStr.call(input);
  161 + if (isPrimitive(val)) {
  162 + return val;
  163 + }
  164 + }
  165 + throw new TypeError();
  166 + },
  167 +
  168 + // ES5 9.9
  169 + // http://es5.github.com/#x9.9
  170 + /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */
  171 + ToObject: function (o) {
  172 + /*jshint eqnull: true */
  173 + if (o == null) { // this matches both null and undefined
  174 + throw new TypeError("can't convert " + o + ' to object');
  175 + }
  176 + return Object(o);
  177 + },
  178 +
  179 + /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */
  180 + ToUint32: function ToUint32(x) {
  181 + return x >>> 0;
  182 + }
  183 +};
  184 +
  185 +//
  186 +// Function
  187 +// ========
  188 +//
  189 +
  190 +// ES-5 15.3.4.5
  191 +// http://es5.github.com/#x15.3.4.5
  192 +
  193 +var Empty = function Empty() {};
  194 +
  195 +defineProperties(FunctionPrototype, {
  196 + bind: function bind(that) { // .length is 1
  197 + // 1. Let Target be the this value.
  198 + var target = this;
  199 + // 2. If IsCallable(Target) is false, throw a TypeError exception.
  200 + if (!isCallable(target)) {
  201 + throw new TypeError('Function.prototype.bind called on incompatible ' + target);
  202 + }
  203 + // 3. Let A be a new (possibly empty) internal list of all of the
  204 + // argument values provided after thisArg (arg1, arg2 etc), in order.
  205 + // XXX slicedArgs will stand in for "A" if used
  206 + var args = array_slice.call(arguments, 1); // for normal call
  207 + // 4. Let F be a new native ECMAScript object.
  208 + // 11. Set the [[Prototype]] internal property of F to the standard
  209 + // built-in Function prototype object as specified in 15.3.3.1.
  210 + // 12. Set the [[Call]] internal property of F as described in
  211 + // 15.3.4.5.1.
  212 + // 13. Set the [[Construct]] internal property of F as described in
  213 + // 15.3.4.5.2.
  214 + // 14. Set the [[HasInstance]] internal property of F as described in
  215 + // 15.3.4.5.3.
  216 + var bound;
  217 + var binder = function () {
  218 +
  219 + if (this instanceof bound) {
  220 + // 15.3.4.5.2 [[Construct]]
  221 + // When the [[Construct]] internal method of a function object,
  222 + // F that was created using the bind function is called with a
  223 + // list of arguments ExtraArgs, the following steps are taken:
  224 + // 1. Let target be the value of F's [[TargetFunction]]
  225 + // internal property.
  226 + // 2. If target has no [[Construct]] internal method, a
  227 + // TypeError exception is thrown.
  228 + // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
  229 + // property.
  230 + // 4. Let args be a new list containing the same values as the
  231 + // list boundArgs in the same order followed by the same
  232 + // values as the list ExtraArgs in the same order.
  233 + // 5. Return the result of calling the [[Construct]] internal
  234 + // method of target providing args as the arguments.
  235 +
  236 + var result = target.apply(
  237 + this,
  238 + args.concat(array_slice.call(arguments))
  239 + );
  240 + if (Object(result) === result) {
  241 + return result;
  242 + }
  243 + return this;
  244 +
  245 + } else {
  246 + // 15.3.4.5.1 [[Call]]
  247 + // When the [[Call]] internal method of a function object, F,
  248 + // which was created using the bind function is called with a
  249 + // this value and a list of arguments ExtraArgs, the following
  250 + // steps are taken:
  251 + // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
  252 + // property.
  253 + // 2. Let boundThis be the value of F's [[BoundThis]] internal
  254 + // property.
  255 + // 3. Let target be the value of F's [[TargetFunction]] internal
  256 + // property.
  257 + // 4. Let args be a new list containing the same values as the
  258 + // list boundArgs in the same order followed by the same
  259 + // values as the list ExtraArgs in the same order.
  260 + // 5. Return the result of calling the [[Call]] internal method
  261 + // of target providing boundThis as the this value and
  262 + // providing args as the arguments.
  263 +
  264 + // equiv: target.call(this, ...boundArgs, ...args)
  265 + return target.apply(
  266 + that,
  267 + args.concat(array_slice.call(arguments))
  268 + );
  269 +
  270 + }
  271 +
  272 + };
  273 +
  274 + // 15. If the [[Class]] internal property of Target is "Function", then
  275 + // a. Let L be the length property of Target minus the length of A.
  276 + // b. Set the length own property of F to either 0 or L, whichever is
  277 + // larger.
  278 + // 16. Else set the length own property of F to 0.
  279 +
  280 + var boundLength = Math.max(0, target.length - args.length);
  281 +
  282 + // 17. Set the attributes of the length own property of F to the values
  283 + // specified in 15.3.5.1.
  284 + var boundArgs = [];
  285 + for (var i = 0; i < boundLength; i++) {
  286 + boundArgs.push('$' + i);
  287 + }
  288 +
  289 + // XXX Build a dynamic function with desired amount of arguments is the only
  290 + // way to set the length property of a function.
  291 + // In environments where Content Security Policies enabled (Chrome extensions,
  292 + // for ex.) all use of eval or Function costructor throws an exception.
  293 + // However in all of these environments Function.prototype.bind exists
  294 + // and so this code will never be executed.
  295 + bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder);
  296 +
  297 + if (target.prototype) {
  298 + Empty.prototype = target.prototype;
  299 + bound.prototype = new Empty();
  300 + // Clean up dangling references.
  301 + Empty.prototype = null;
  302 + }
  303 +
  304 + // TODO
  305 + // 18. Set the [[Extensible]] internal property of F to true.
  306 +
  307 + // TODO
  308 + // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
  309 + // 20. Call the [[DefineOwnProperty]] internal method of F with
  310 + // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
  311 + // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
  312 + // false.
  313 + // 21. Call the [[DefineOwnProperty]] internal method of F with
  314 + // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
  315 + // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
  316 + // and false.
  317 +
  318 + // TODO
  319 + // NOTE Function objects created using Function.prototype.bind do not
  320 + // have a prototype property or the [[Code]], [[FormalParameters]], and
  321 + // [[Scope]] internal properties.
  322 + // XXX can't delete prototype in pure-js.
  323 +
  324 + // 22. Return F.
  325 + return bound;
  326 + }
  327 +});
  328 +
  329 +// _Please note: Shortcuts are defined after `Function.prototype.bind` as we
  330 +// us it in defining shortcuts.
  331 +var owns = call.bind(ObjectPrototype.hasOwnProperty);
  332 +
  333 +//
  334 +// Array
  335 +// =====
  336 +//
  337 +
  338 +// ES5 15.4.4.12
  339 +// http://es5.github.com/#x15.4.4.12
  340 +var spliceNoopReturnsEmptyArray = (function () {
  341 + var a = [1, 2];
  342 + var result = a.splice();
  343 + return a.length === 2 && isArray(result) && result.length === 0;
  344 +}());
  345 +defineProperties(ArrayPrototype, {
  346 + // Safari 5.0 bug where .splice() returns undefined
  347 + splice: function splice(start, deleteCount) {
  348 + if (arguments.length === 0) {
  349 + return [];
  350 + } else {
  351 + return array_splice.apply(this, arguments);
  352 + }
  353 + }
  354 +}, !spliceNoopReturnsEmptyArray);
  355 +
  356 +var spliceWorksWithEmptyObject = (function () {
  357 + var obj = {};
  358 + ArrayPrototype.splice.call(obj, 0, 0, 1);
  359 + return obj.length === 1;
  360 +}());
  361 +defineProperties(ArrayPrototype, {
  362 + splice: function splice(start, deleteCount) {
  363 + if (arguments.length === 0) { return []; }
  364 + var args = arguments;
  365 + this.length = Math.max(ES.ToInteger(this.length), 0);
  366 + if (arguments.length > 0 && typeof deleteCount !== 'number') {
  367 + args = array_slice.call(arguments);
  368 + if (args.length < 2) {
  369 + args.push(this.length - start);
  370 + } else {
  371 + args[1] = ES.ToInteger(deleteCount);
  372 + }
  373 + }
  374 + return array_splice.apply(this, args);
  375 + }
  376 +}, !spliceWorksWithEmptyObject);
  377 +
  378 +// ES5 15.4.4.12
  379 +// http://es5.github.com/#x15.4.4.13
  380 +// Return len+argCount.
  381 +// [bugfix, ielt8]
  382 +// IE < 8 bug: [].unshift(0) === undefined but should be "1"
  383 +var hasUnshiftReturnValueBug = [].unshift(0) !== 1;
  384 +defineProperties(ArrayPrototype, {
  385 + unshift: function () {
  386 + array_unshift.apply(this, arguments);
  387 + return this.length;
  388 + }
  389 +}, hasUnshiftReturnValueBug);
  390 +
  391 +// ES5 15.4.3.2
  392 +// http://es5.github.com/#x15.4.3.2
  393 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
  394 +defineProperties(Array, { isArray: isArray });
  395 +
  396 +// The IsCallable() check in the Array functions
  397 +// has been replaced with a strict check on the
  398 +// internal class of the object to trap cases where
  399 +// the provided function was actually a regular
  400 +// expression literal, which in V8 and
  401 +// JavaScriptCore is a typeof "function". Only in
  402 +// V8 are regular expression literals permitted as
  403 +// reduce parameters, so it is desirable in the
  404 +// general case for the shim to match the more
  405 +// strict and common behavior of rejecting regular
  406 +// expressions.
  407 +
  408 +// ES5 15.4.4.18
  409 +// http://es5.github.com/#x15.4.4.18
  410 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
  411 +
  412 +// Check failure of by-index access of string characters (IE < 9)
  413 +// and failure of `0 in boxedString` (Rhino)
  414 +var boxedString = Object('a');
  415 +var splitString = boxedString[0] !== 'a' || !(0 in boxedString);
  416 +
  417 +var properlyBoxesContext = function properlyBoxed(method) {
  418 + // Check node 0.6.21 bug where third parameter is not boxed
  419 + var properlyBoxesNonStrict = true;
  420 + var properlyBoxesStrict = true;
  421 + if (method) {
  422 + method.call('foo', function (_, __, context) {
  423 + if (typeof context !== 'object') { properlyBoxesNonStrict = false; }
  424 + });
  425 +
  426 + method.call([1], function () {
  427 + 'use strict';
  428 +
  429 + properlyBoxesStrict = typeof this === 'string';
  430 + }, 'x');
  431 + }
  432 + return !!method && properlyBoxesNonStrict && properlyBoxesStrict;
  433 +};
  434 +
  435 +defineProperties(ArrayPrototype, {
  436 + forEach: function forEach(callbackfn /*, thisArg*/) {
  437 + var object = ES.ToObject(this);
  438 + var self = splitString && isString(this) ? this.split('') : object;
  439 + var i = -1;
  440 + var length = self.length >>> 0;
  441 + var T;
  442 + if (arguments.length > 1) {
  443 + T = arguments[1];
  444 + }
  445 +
  446 + // If no callback function or if callback is not a callable function
  447 + if (!isCallable(callbackfn)) {
  448 + throw new TypeError('Array.prototype.forEach callback must be a function');
  449 + }
  450 +
  451 + while (++i < length) {
  452 + if (i in self) {
  453 + // Invoke the callback function with call, passing arguments:
  454 + // context, property value, property key, thisArg object
  455 + if (typeof T !== 'undefined') {
  456 + callbackfn.call(T, self[i], i, object);
  457 + } else {
  458 + callbackfn(self[i], i, object);
  459 + }
  460 + }
  461 + }
  462 + }
  463 +}, !properlyBoxesContext(ArrayPrototype.forEach));
  464 +
  465 +// ES5 15.4.4.19
  466 +// http://es5.github.com/#x15.4.4.19
  467 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
  468 +defineProperties(ArrayPrototype, {
  469 + map: function map(callbackfn/*, thisArg*/) {
  470 + var object = ES.ToObject(this);
  471 + var self = splitString && isString(this) ? this.split('') : object;
  472 + var length = self.length >>> 0;
  473 + var result = Array(length);
  474 + var T;
  475 + if (arguments.length > 1) {
  476 + T = arguments[1];
  477 + }
  478 +
  479 + // If no callback function or if callback is not a callable function
  480 + if (!isCallable(callbackfn)) {
  481 + throw new TypeError('Array.prototype.map callback must be a function');
  482 + }
  483 +
  484 + for (var i = 0; i < length; i++) {
  485 + if (i in self) {
  486 + if (typeof T !== 'undefined') {
  487 + result[i] = callbackfn.call(T, self[i], i, object);
  488 + } else {
  489 + result[i] = callbackfn(self[i], i, object);
  490 + }
  491 + }
  492 + }
  493 + return result;
  494 + }
  495 +}, !properlyBoxesContext(ArrayPrototype.map));
  496 +
  497 +// ES5 15.4.4.20
  498 +// http://es5.github.com/#x15.4.4.20
  499 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
  500 +defineProperties(ArrayPrototype, {
  501 + filter: function filter(callbackfn /*, thisArg*/) {
  502 + var object = ES.ToObject(this);
  503 + var self = splitString && isString(this) ? this.split('') : object;
  504 + var length = self.length >>> 0;
  505 + var result = [];
  506 + var value;
  507 + var T;
  508 + if (arguments.length > 1) {
  509 + T = arguments[1];
  510 + }
  511 +
  512 + // If no callback function or if callback is not a callable function
  513 + if (!isCallable(callbackfn)) {
  514 + throw new TypeError('Array.prototype.filter callback must be a function');
  515 + }
  516 +
  517 + for (var i = 0; i < length; i++) {
  518 + if (i in self) {
  519 + value = self[i];
  520 + if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) {
  521 + result.push(value);
  522 + }
  523 + }
  524 + }
  525 + return result;
  526 + }
  527 +}, !properlyBoxesContext(ArrayPrototype.filter));
  528 +
  529 +// ES5 15.4.4.16
  530 +// http://es5.github.com/#x15.4.4.16
  531 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
  532 +defineProperties(ArrayPrototype, {
  533 + every: function every(callbackfn /*, thisArg*/) {
  534 + var object = ES.ToObject(this);
  535 + var self = splitString && isString(this) ? this.split('') : object;
  536 + var length = self.length >>> 0;
  537 + var T;
  538 + if (arguments.length > 1) {
  539 + T = arguments[1];
  540 + }
  541 +
  542 + // If no callback function or if callback is not a callable function
  543 + if (!isCallable(callbackfn)) {
  544 + throw new TypeError('Array.prototype.every callback must be a function');
  545 + }
  546 +
  547 + for (var i = 0; i < length; i++) {
  548 + if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  549 + return false;
  550 + }
  551 + }
  552 + return true;
  553 + }
  554 +}, !properlyBoxesContext(ArrayPrototype.every));
  555 +
  556 +// ES5 15.4.4.17
  557 +// http://es5.github.com/#x15.4.4.17
  558 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
  559 +defineProperties(ArrayPrototype, {
  560 + some: function some(callbackfn/*, thisArg */) {
  561 + var object = ES.ToObject(this);
  562 + var self = splitString && isString(this) ? this.split('') : object;
  563 + var length = self.length >>> 0;
  564 + var T;
  565 + if (arguments.length > 1) {
  566 + T = arguments[1];
  567 + }
  568 +
  569 + // If no callback function or if callback is not a callable function
  570 + if (!isCallable(callbackfn)) {
  571 + throw new TypeError('Array.prototype.some callback must be a function');
  572 + }
  573 +
  574 + for (var i = 0; i < length; i++) {
  575 + if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) {
  576 + return true;
  577 + }
  578 + }
  579 + return false;
  580 + }
  581 +}, !properlyBoxesContext(ArrayPrototype.some));
  582 +
  583 +// ES5 15.4.4.21
  584 +// http://es5.github.com/#x15.4.4.21
  585 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
  586 +var reduceCoercesToObject = false;
  587 +if (ArrayPrototype.reduce) {
  588 + reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object';
  589 +}
  590 +defineProperties(ArrayPrototype, {
  591 + reduce: function reduce(callbackfn /*, initialValue*/) {
  592 + var object = ES.ToObject(this);
  593 + var self = splitString && isString(this) ? this.split('') : object;
  594 + var length = self.length >>> 0;
  595 +
  596 + // If no callback function or if callback is not a callable function
  597 + if (!isCallable(callbackfn)) {
  598 + throw new TypeError('Array.prototype.reduce callback must be a function');
  599 + }
  600 +
  601 + // no value to return if no initial value and an empty array
  602 + if (length === 0 && arguments.length === 1) {
  603 + throw new TypeError('reduce of empty array with no initial value');
  604 + }
  605 +
  606 + var i = 0;
  607 + var result;
  608 + if (arguments.length >= 2) {
  609 + result = arguments[1];
  610 + } else {
  611 + do {
  612 + if (i in self) {
  613 + result = self[i++];
  614 + break;
  615 + }
  616 +
  617 + // if array contains no values, no initial value to return
  618 + if (++i >= length) {
  619 + throw new TypeError('reduce of empty array with no initial value');
  620 + }
  621 + } while (true);
  622 + }
  623 +
  624 + for (; i < length; i++) {
  625 + if (i in self) {
  626 + result = callbackfn(result, self[i], i, object);
  627 + }
  628 + }
  629 +
  630 + return result;
  631 + }
  632 +}, !reduceCoercesToObject);
  633 +
  634 +// ES5 15.4.4.22
  635 +// http://es5.github.com/#x15.4.4.22
  636 +// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
  637 +var reduceRightCoercesToObject = false;
  638 +if (ArrayPrototype.reduceRight) {
  639 + reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object';
  640 +}
  641 +defineProperties(ArrayPrototype, {
  642 + reduceRight: function reduceRight(callbackfn/*, initial*/) {
  643 + var object = ES.ToObject(this);
  644 + var self = splitString && isString(this) ? this.split('') : object;
  645 + var length = self.length >>> 0;
  646 +
  647 + // If no callback function or if callback is not a callable function
  648 + if (!isCallable(callbackfn)) {
  649 + throw new TypeError('Array.prototype.reduceRight callback must be a function');
  650 + }
  651 +
  652 + // no value to return if no initial value, empty array
  653 + if (length === 0 && arguments.length === 1) {
  654 + throw new TypeError('reduceRight of empty array with no initial value');
  655 + }
  656 +
  657 + var result;
  658 + var i = length - 1;
  659 + if (arguments.length >= 2) {
  660 + result = arguments[1];
  661 + } else {
  662 + do {
  663 + if (i in self) {
  664 + result = self[i--];
  665 + break;
  666 + }
  667 +
  668 + // if array contains no values, no initial value to return
  669 + if (--i < 0) {
  670 + throw new TypeError('reduceRight of empty array with no initial value');
  671 + }
  672 + } while (true);
  673 + }
  674 +
  675 + if (i < 0) {
  676 + return result;
  677 + }
  678 +
  679 + do {
  680 + if (i in self) {
  681 + result = callbackfn(result, self[i], i, object);
  682 + }
  683 + } while (i--);
  684 +
  685 + return result;
  686 + }
  687 +}, !reduceRightCoercesToObject);
  688 +
  689 +// ES5 15.4.4.14
  690 +// http://es5.github.com/#x15.4.4.14
  691 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
  692 +var hasFirefox2IndexOfBug = Array.prototype.indexOf && [0, 1].indexOf(1, 2) !== -1;
  693 +defineProperties(ArrayPrototype, {
  694 + indexOf: function indexOf(searchElement /*, fromIndex */) {
  695 + var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
  696 + var length = self.length >>> 0;
  697 +
  698 + if (length === 0) {
  699 + return -1;
  700 + }
  701 +
  702 + var i = 0;
  703 + if (arguments.length > 1) {
  704 + i = ES.ToInteger(arguments[1]);
  705 + }
  706 +
  707 + // handle negative indices
  708 + i = i >= 0 ? i : Math.max(0, length + i);
  709 + for (; i < length; i++) {
  710 + if (i in self && self[i] === searchElement) {
  711 + return i;
  712 + }
  713 + }
  714 + return -1;
  715 + }
  716 +}, hasFirefox2IndexOfBug);
  717 +
  718 +// ES5 15.4.4.15
  719 +// http://es5.github.com/#x15.4.4.15
  720 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
  721 +var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1;
  722 +defineProperties(ArrayPrototype, {
  723 + lastIndexOf: function lastIndexOf(searchElement /*, fromIndex */) {
  724 + var self = splitString && isString(this) ? this.split('') : ES.ToObject(this);
  725 + var length = self.length >>> 0;
  726 +
  727 + if (length === 0) {
  728 + return -1;
  729 + }
  730 + var i = length - 1;
  731 + if (arguments.length > 1) {
  732 + i = Math.min(i, ES.ToInteger(arguments[1]));
  733 + }
  734 + // handle negative indices
  735 + i = i >= 0 ? i : length - Math.abs(i);
  736 + for (; i >= 0; i--) {
  737 + if (i in self && searchElement === self[i]) {
  738 + return i;
  739 + }
  740 + }
  741 + return -1;
  742 + }
  743 +}, hasFirefox2LastIndexOfBug);
  744 +
  745 +//
  746 +// Object
  747 +// ======
  748 +//
  749 +
  750 +// ES5 15.2.3.14
  751 +// http://es5.github.com/#x15.2.3.14
  752 +
  753 +// http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
  754 +var hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'),
  755 + hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'),
  756 + hasStringEnumBug = !owns('x', '0'),
  757 + dontEnums = [
  758 + 'toString',
  759 + 'toLocaleString',
  760 + 'valueOf',
  761 + 'hasOwnProperty',
  762 + 'isPrototypeOf',
  763 + 'propertyIsEnumerable',
  764 + 'constructor'
  765 + ],
  766 + dontEnumsLength = dontEnums.length;
  767 +
  768 +defineProperties(Object, {
  769 + keys: function keys(object) {
  770 + var isFn = isCallable(object),
  771 + isArgs = isArguments(object),
  772 + isObject = object !== null && typeof object === 'object',
  773 + isStr = isObject && isString(object);
  774 +
  775 + if (!isObject && !isFn && !isArgs) {
  776 + throw new TypeError('Object.keys called on a non-object');
  777 + }
  778 +
  779 + var theKeys = [];
  780 + var skipProto = hasProtoEnumBug && isFn;
  781 + if ((isStr && hasStringEnumBug) || isArgs) {
  782 + for (var i = 0; i < object.length; ++i) {
  783 + theKeys.push(String(i));
  784 + }
  785 + }
  786 +
  787 + if (!isArgs) {
  788 + for (var name in object) {
  789 + if (!(skipProto && name === 'prototype') && owns(object, name)) {
  790 + theKeys.push(String(name));
  791 + }
  792 + }
  793 + }
  794 +
  795 + if (hasDontEnumBug) {
  796 + var ctor = object.constructor,
  797 + skipConstructor = ctor && ctor.prototype === object;
  798 + for (var j = 0; j < dontEnumsLength; j++) {
  799 + var dontEnum = dontEnums[j];
  800 + if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) {
  801 + theKeys.push(dontEnum);
  802 + }
  803 + }
  804 + }
  805 + return theKeys;
  806 + }
  807 +});
  808 +
  809 +var keysWorksWithArguments = Object.keys && (function () {
  810 + // Safari 5.0 bug
  811 + return Object.keys(arguments).length === 2;
  812 +}(1, 2));
  813 +var originalKeys = Object.keys;
  814 +defineProperties(Object, {
  815 + keys: function keys(object) {
  816 + if (isArguments(object)) {
  817 + return originalKeys(ArrayPrototype.slice.call(object));
  818 + } else {
  819 + return originalKeys(object);
  820 + }
  821 + }
  822 +}, !keysWorksWithArguments);
  823 +
  824 +//
  825 +// Date
  826 +// ====
  827 +//
  828 +
  829 +// ES5 15.9.5.43
  830 +// http://es5.github.com/#x15.9.5.43
  831 +// This function returns a String value represent the instance in time
  832 +// represented by this Date object. The format of the String is the Date Time
  833 +// string format defined in 15.9.1.15. All fields are present in the String.
  834 +// The time zone is always UTC, denoted by the suffix Z. If the time value of
  835 +// this object is not a finite Number a RangeError exception is thrown.
  836 +var negativeDate = -62198755200000;
  837 +var negativeYearString = '-000001';
  838 +var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1;
  839 +
  840 +defineProperties(Date.prototype, {
  841 + toISOString: function toISOString() {
  842 + var result, length, value, year, month;
  843 + if (!isFinite(this)) {
  844 + throw new RangeError('Date.prototype.toISOString called on non-finite value.');
  845 + }
  846 +
  847 + year = this.getUTCFullYear();
  848 +
  849 + month = this.getUTCMonth();
  850 + // see https://github.com/es-shims/es5-shim/issues/111
  851 + year += Math.floor(month / 12);
  852 + month = (month % 12 + 12) % 12;
  853 +
  854 + // the date time string format is specified in 15.9.1.15.
  855 + result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
  856 + year = (
  857 + (year < 0 ? '-' : (year > 9999 ? '+' : '')) +
  858 + ('00000' + Math.abs(year)).slice((0 <= year && year <= 9999) ? -4 : -6)
  859 + );
  860 +
  861 + length = result.length;
  862 + while (length--) {
  863 + value = result[length];
  864 + // pad months, days, hours, minutes, and seconds to have two
  865 + // digits.
  866 + if (value < 10) {
  867 + result[length] = '0' + value;
  868 + }
  869 + }
  870 + // pad milliseconds to have three digits.
  871 + return (
  872 + year + '-' + result.slice(0, 2).join('-') +
  873 + 'T' + result.slice(2).join(':') + '.' +
  874 + ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'
  875 + );
  876 + }
  877 +}, hasNegativeDateBug);
  878 +
  879 +// ES5 15.9.5.44
  880 +// http://es5.github.com/#x15.9.5.44
  881 +// This function provides a String representation of a Date object for use by
  882 +// JSON.stringify (15.12.3).
  883 +var dateToJSONIsSupported = (function () {
  884 + try {
  885 + return Date.prototype.toJSON &&
  886 + new Date(NaN).toJSON() === null &&
  887 + new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
  888 + Date.prototype.toJSON.call({ // generic
  889 + toISOString: function () { return true; }
  890 + });
  891 + } catch (e) {
  892 + return false;
  893 + }
  894 +}());
  895 +if (!dateToJSONIsSupported) {
  896 + Date.prototype.toJSON = function toJSON(key) {
  897 + // When the toJSON method is called with argument key, the following
  898 + // steps are taken:
  899 +
  900 + // 1. Let O be the result of calling ToObject, giving it the this
  901 + // value as its argument.
  902 + // 2. Let tv be ES.ToPrimitive(O, hint Number).
  903 + var O = Object(this);
  904 + var tv = ES.ToPrimitive(O);
  905 + // 3. If tv is a Number and is not finite, return null.
  906 + if (typeof tv === 'number' && !isFinite(tv)) {
  907 + return null;
  908 + }
  909 + // 4. Let toISO be the result of calling the [[Get]] internal method of
  910 + // O with argument "toISOString".
  911 + var toISO = O.toISOString;
  912 + // 5. If IsCallable(toISO) is false, throw a TypeError exception.
  913 + if (!isCallable(toISO)) {
  914 + throw new TypeError('toISOString property is not callable');
  915 + }
  916 + // 6. Return the result of calling the [[Call]] internal method of
  917 + // toISO with O as the this value and an empty argument list.
  918 + return toISO.call(O);
  919 +
  920 + // NOTE 1 The argument is ignored.
  921 +
  922 + // NOTE 2 The toJSON function is intentionally generic; it does not
  923 + // require that its this value be a Date object. Therefore, it can be
  924 + // transferred to other kinds of objects for use as a method. However,
  925 + // it does require that any such object have a toISOString method. An
  926 + // object is free to use the argument key to filter its
  927 + // stringification.
  928 + };
  929 +}
  930 +
  931 +// ES5 15.9.4.2
  932 +// http://es5.github.com/#x15.9.4.2
  933 +// based on work shared by Daniel Friesen (dantman)
  934 +// http://gist.github.com/303249
  935 +var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15;
  936 +var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z'));
  937 +var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z'));
  938 +if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) {
  939 + // XXX global assignment won't work in embeddings that use
  940 + // an alternate object for the context.
  941 + /*global Date: true */
  942 + /*eslint-disable no-undef*/
  943 + Date = (function (NativeDate) {
  944 + /*eslint-enable no-undef*/
  945 + // Date.length === 7
  946 + var DateShim = function Date(Y, M, D, h, m, s, ms) {
  947 + var length = arguments.length;
  948 + var date;
  949 + if (this instanceof NativeDate) {
  950 + date = length === 1 && String(Y) === Y ? // isString(Y)
  951 + // We explicitly pass it through parse:
  952 + new NativeDate(DateShim.parse(Y)) :
  953 + // We have to manually make calls depending on argument
  954 + // length here
  955 + length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
  956 + length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
  957 + length >= 5 ? new NativeDate(Y, M, D, h, m) :
  958 + length >= 4 ? new NativeDate(Y, M, D, h) :
  959 + length >= 3 ? new NativeDate(Y, M, D) :
  960 + length >= 2 ? new NativeDate(Y, M) :
  961 + length >= 1 ? new NativeDate(Y) :
  962 + new NativeDate();
  963 + } else {
  964 + date = NativeDate.apply(this, arguments);
  965 + }
  966 + // Prevent mixups with unfixed Date object
  967 + defineProperties(date, { constructor: DateShim }, true);
  968 + return date;
  969 + };
  970 +
  971 + // 15.9.1.15 Date Time String Format.
  972 + var isoDateExpression = new RegExp('^' +
  973 + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign +
  974 + // 6-digit extended year
  975 + '(?:-(\\d{2})' + // optional month capture
  976 + '(?:-(\\d{2})' + // optional day capture
  977 + '(?:' + // capture hours:minutes:seconds.milliseconds
  978 + 'T(\\d{2})' + // hours capture
  979 + ':(\\d{2})' + // minutes capture
  980 + '(?:' + // optional :seconds.milliseconds
  981 + ':(\\d{2})' + // seconds capture
  982 + '(?:(\\.\\d{1,}))?' + // milliseconds capture
  983 + ')?' +
  984 + '(' + // capture UTC offset component
  985 + 'Z|' + // UTC capture
  986 + '(?:' + // offset specifier +/-hours:minutes
  987 + '([-+])' + // sign capture
  988 + '(\\d{2})' + // hours offset capture
  989 + ':(\\d{2})' + // minutes offset capture
  990 + ')' +
  991 + ')?)?)?)?' +
  992 + '$');
  993 +
  994 + var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
  995 +
  996 + var dayFromMonth = function dayFromMonth(year, month) {
  997 + var t = month > 1 ? 1 : 0;
  998 + return (
  999 + months[month] +
  1000 + Math.floor((year - 1969 + t) / 4) -
  1001 + Math.floor((year - 1901 + t) / 100) +
  1002 + Math.floor((year - 1601 + t) / 400) +
  1003 + 365 * (year - 1970)
  1004 + );
  1005 + };
  1006 +
  1007 + var toUTC = function toUTC(t) {
  1008 + return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t));
  1009 + };
  1010 +
  1011 + // Copy any custom methods a 3rd party library may have added
  1012 + for (var key in NativeDate) {
  1013 + if (owns(NativeDate, key)) {
  1014 + DateShim[key] = NativeDate[key];
  1015 + }
  1016 + }
  1017 +
  1018 + // Copy "native" methods explicitly; they may be non-enumerable
  1019 + DateShim.now = NativeDate.now;
  1020 + DateShim.UTC = NativeDate.UTC;
  1021 + DateShim.prototype = NativeDate.prototype;
  1022 + DateShim.prototype.constructor = DateShim;
  1023 +
  1024 + // Upgrade Date.parse to handle simplified ISO 8601 strings
  1025 + DateShim.parse = function parse(string) {
  1026 + var match = isoDateExpression.exec(string);
  1027 + if (match) {
  1028 + // parse months, days, hours, minutes, seconds, and milliseconds
  1029 + // provide default values if necessary
  1030 + // parse the UTC offset component
  1031 + var year = Number(match[1]),
  1032 + month = Number(match[2] || 1) - 1,
  1033 + day = Number(match[3] || 1) - 1,
  1034 + hour = Number(match[4] || 0),
  1035 + minute = Number(match[5] || 0),
  1036 + second = Number(match[6] || 0),
  1037 + millisecond = Math.floor(Number(match[7] || 0) * 1000),
  1038 + // When time zone is missed, local offset should be used
  1039 + // (ES 5.1 bug)
  1040 + // see https://bugs.ecmascript.org/show_bug.cgi?id=112
  1041 + isLocalTime = Boolean(match[4] && !match[8]),
  1042 + signOffset = match[9] === '-' ? 1 : -1,
  1043 + hourOffset = Number(match[10] || 0),
  1044 + minuteOffset = Number(match[11] || 0),
  1045 + result;
  1046 + if (
  1047 + hour < (
  1048 + minute > 0 || second > 0 || millisecond > 0 ?
  1049 + 24 : 25
  1050 + ) &&
  1051 + minute < 60 && second < 60 && millisecond < 1000 &&
  1052 + month > -1 && month < 12 && hourOffset < 24 &&
  1053 + minuteOffset < 60 && // detect invalid offsets
  1054 + day > -1 &&
  1055 + day < (
  1056 + dayFromMonth(year, month + 1) -
  1057 + dayFromMonth(year, month)
  1058 + )
  1059 + ) {
  1060 + result = (
  1061 + (dayFromMonth(year, month) + day) * 24 +
  1062 + hour +
  1063 + hourOffset * signOffset
  1064 + ) * 60;
  1065 + result = (
  1066 + (result + minute + minuteOffset * signOffset) * 60 +
  1067 + second
  1068 + ) * 1000 + millisecond;
  1069 + if (isLocalTime) {
  1070 + result = toUTC(result);
  1071 + }
  1072 + if (-8.64e15 <= result && result <= 8.64e15) {
  1073 + return result;
  1074 + }
  1075 + }
  1076 + return NaN;
  1077 + }
  1078 + return NativeDate.parse.apply(this, arguments);
  1079 + };
  1080 +
  1081 + return DateShim;
  1082 + }(Date));
  1083 + /*global Date: false */
  1084 +}
  1085 +
  1086 +// ES5 15.9.4.4
  1087 +// http://es5.github.com/#x15.9.4.4
  1088 +if (!Date.now) {
  1089 + Date.now = function now() {
  1090 + return new Date().getTime();
  1091 + };
  1092 +}
  1093 +
  1094 +//
  1095 +// Number
  1096 +// ======
  1097 +//
  1098 +
  1099 +// ES5.1 15.7.4.5
  1100 +// http://es5.github.com/#x15.7.4.5
  1101 +var hasToFixedBugs = NumberPrototype.toFixed && (
  1102 + (0.00008).toFixed(3) !== '0.000' ||
  1103 + (0.9).toFixed(0) !== '1' ||
  1104 + (1.255).toFixed(2) !== '1.25' ||
  1105 + (1000000000000000128).toFixed(0) !== '1000000000000000128'
  1106 +);
  1107 +
  1108 +var toFixedHelpers = {
  1109 + base: 1e7,
  1110 + size: 6,
  1111 + data: [0, 0, 0, 0, 0, 0],
  1112 + multiply: function multiply(n, c) {
  1113 + var i = -1;
  1114 + var c2 = c;
  1115 + while (++i < toFixedHelpers.size) {
  1116 + c2 += n * toFixedHelpers.data[i];
  1117 + toFixedHelpers.data[i] = c2 % toFixedHelpers.base;
  1118 + c2 = Math.floor(c2 / toFixedHelpers.base);
  1119 + }
  1120 + },
  1121 + divide: function divide(n) {
  1122 + var i = toFixedHelpers.size, c = 0;
  1123 + while (--i >= 0) {
  1124 + c += toFixedHelpers.data[i];
  1125 + toFixedHelpers.data[i] = Math.floor(c / n);
  1126 + c = (c % n) * toFixedHelpers.base;
  1127 + }
  1128 + },
  1129 + numToString: function numToString() {
  1130 + var i = toFixedHelpers.size;
  1131 + var s = '';
  1132 + while (--i >= 0) {
  1133 + if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) {
  1134 + var t = String(toFixedHelpers.data[i]);
  1135 + if (s === '') {
  1136 + s = t;
  1137 + } else {
  1138 + s += '0000000'.slice(0, 7 - t.length) + t;
  1139 + }
  1140 + }
  1141 + }
  1142 + return s;
  1143 + },
  1144 + pow: function pow(x, n, acc) {
  1145 + return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc)));
  1146 + },
  1147 + log: function log(x) {
  1148 + var n = 0;
  1149 + var x2 = x;
  1150 + while (x2 >= 4096) {
  1151 + n += 12;
  1152 + x2 /= 4096;
  1153 + }
  1154 + while (x2 >= 2) {
  1155 + n += 1;
  1156 + x2 /= 2;
  1157 + }
  1158 + return n;
  1159 + }
  1160 +};
  1161 +
  1162 +defineProperties(NumberPrototype, {
  1163 + toFixed: function toFixed(fractionDigits) {
  1164 + var f, x, s, m, e, z, j, k;
  1165 +
  1166 + // Test for NaN and round fractionDigits down
  1167 + f = Number(fractionDigits);
  1168 + f = f !== f ? 0 : Math.floor(f);
  1169 +
  1170 + if (f < 0 || f > 20) {
  1171 + throw new RangeError('Number.toFixed called with invalid number of decimals');
  1172 + }
  1173 +
  1174 + x = Number(this);
  1175 +
  1176 + // Test for NaN
  1177 + if (x !== x) {
  1178 + return 'NaN';
  1179 + }
  1180 +
  1181 + // If it is too big or small, return the string value of the number
  1182 + if (x <= -1e21 || x >= 1e21) {
  1183 + return String(x);
  1184 + }
  1185 +
  1186 + s = '';
  1187 +
  1188 + if (x < 0) {
  1189 + s = '-';
  1190 + x = -x;
  1191 + }
  1192 +
  1193 + m = '0';
  1194 +
  1195 + if (x > 1e-21) {
  1196 + // 1e-21 < x < 1e21
  1197 + // -70 < log2(x) < 70
  1198 + e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69;
  1199 + z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1));
  1200 + z *= 0x10000000000000; // Math.pow(2, 52);
  1201 + e = 52 - e;
  1202 +
  1203 + // -18 < e < 122
  1204 + // x = z / 2 ^ e
  1205 + if (e > 0) {
  1206 + toFixedHelpers.multiply(0, z);
  1207 + j = f;
  1208 +
  1209 + while (j >= 7) {
  1210 + toFixedHelpers.multiply(1e7, 0);
  1211 + j -= 7;
  1212 + }
  1213 +
  1214 + toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0);
  1215 + j = e - 1;
  1216 +
  1217 + while (j >= 23) {
  1218 + toFixedHelpers.divide(1 << 23);
  1219 + j -= 23;
  1220 + }
  1221 +
  1222 + toFixedHelpers.divide(1 << j);
  1223 + toFixedHelpers.multiply(1, 1);
  1224 + toFixedHelpers.divide(2);
  1225 + m = toFixedHelpers.numToString();
  1226 + } else {
  1227 + toFixedHelpers.multiply(0, z);
  1228 + toFixedHelpers.multiply(1 << (-e), 0);
  1229 + m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f);
  1230 + }
  1231 + }
  1232 +
  1233 + if (f > 0) {
  1234 + k = m.length;
  1235 +
  1236 + if (k <= f) {
  1237 + m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m;
  1238 + } else {
  1239 + m = s + m.slice(0, k - f) + '.' + m.slice(k - f);
  1240 + }
  1241 + } else {
  1242 + m = s + m;
  1243 + }
  1244 +
  1245 + return m;
  1246 + }
  1247 +}, hasToFixedBugs);
  1248 +
  1249 +//
  1250 +// String
  1251 +// ======
  1252 +//
  1253 +
  1254 +// ES5 15.5.4.14
  1255 +// http://es5.github.com/#x15.5.4.14
  1256 +
  1257 +// [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers]
  1258 +// Many browsers do not split properly with regular expressions or they
  1259 +// do not perform the split correctly under obscure conditions.
  1260 +// See http://blog.stevenlevithan.com/archives/cross-browser-split
  1261 +// I've tested in many browsers and this seems to cover the deviant ones:
  1262 +// 'ab'.split(/(?:ab)*/) should be ["", ""], not [""]
  1263 +// '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""]
  1264 +// 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not
  1265 +// [undefined, "t", undefined, "e", ...]
  1266 +// ''.split(/.?/) should be [], not [""]
  1267 +// '.'.split(/()()/) should be ["."], not ["", "", "."]
  1268 +
  1269 +var string_split = StringPrototype.split;
  1270 +if (
  1271 + 'ab'.split(/(?:ab)*/).length !== 2 ||
  1272 + '.'.split(/(.?)(.?)/).length !== 4 ||
  1273 + 'tesst'.split(/(s)*/)[1] === 't' ||
  1274 + 'test'.split(/(?:)/, -1).length !== 4 ||
  1275 + ''.split(/.?/).length ||
  1276 + '.'.split(/()()/).length > 1
  1277 +) {
  1278 + (function () {
  1279 + var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group
  1280 +
  1281 + StringPrototype.split = function (separator, limit) {
  1282 + var string = this;
  1283 + if (typeof separator === 'undefined' && limit === 0) {
  1284 + return [];
  1285 + }
  1286 +
  1287 + // If `separator` is not a regex, use native split
  1288 + if (!isRegex(separator)) {
  1289 + return string_split.call(this, separator, limit);
  1290 + }
  1291 +
  1292 + var output = [];
  1293 + var flags = (separator.ignoreCase ? 'i' : '') +
  1294 + (separator.multiline ? 'm' : '') +
  1295 + (separator.extended ? 'x' : '') + // Proposed for ES6
  1296 + (separator.sticky ? 'y' : ''), // Firefox 3+
  1297 + lastLastIndex = 0,
  1298 + // Make `global` and avoid `lastIndex` issues by working with a copy
  1299 + separator2, match, lastIndex, lastLength;
  1300 + var separatorCopy = new RegExp(separator.source, flags + 'g');
  1301 + string += ''; // Type-convert
  1302 + if (!compliantExecNpcg) {
  1303 + // Doesn't need flags gy, but they don't hurt
  1304 + separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
  1305 + }
  1306 + /* Values for `limit`, per the spec:
  1307 + * If undefined: 4294967295 // Math.pow(2, 32) - 1
  1308 + * If 0, Infinity, or NaN: 0
  1309 + * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
  1310 + * If negative number: 4294967296 - Math.floor(Math.abs(limit))
  1311 + * If other: Type-convert, then use the above rules
  1312 + */
  1313 + var splitLimit = typeof limit === 'undefined' ?
  1314 + -1 >>> 0 : // Math.pow(2, 32) - 1
  1315 + ES.ToUint32(limit);
  1316 + match = separatorCopy.exec(string);
  1317 + while (match) {
  1318 + // `separatorCopy.lastIndex` is not reliable cross-browser
  1319 + lastIndex = match.index + match[0].length;
  1320 + if (lastIndex > lastLastIndex) {
  1321 + output.push(string.slice(lastLastIndex, match.index));
  1322 + // Fix browsers whose `exec` methods don't consistently return `undefined` for
  1323 + // nonparticipating capturing groups
  1324 + if (!compliantExecNpcg && match.length > 1) {
  1325 + /*eslint-disable no-loop-func */
  1326 + match[0].replace(separator2, function () {
  1327 + for (var i = 1; i < arguments.length - 2; i++) {
  1328 + if (typeof arguments[i] === 'undefined') {
  1329 + match[i] = void 0;
  1330 + }
  1331 + }
  1332 + });
  1333 + /*eslint-enable no-loop-func */
  1334 + }
  1335 + if (match.length > 1 && match.index < string.length) {
  1336 + array_push.apply(output, match.slice(1));
  1337 + }
  1338 + lastLength = match[0].length;
  1339 + lastLastIndex = lastIndex;
  1340 + if (output.length >= splitLimit) {
  1341 + break;
  1342 + }
  1343 + }
  1344 + if (separatorCopy.lastIndex === match.index) {
  1345 + separatorCopy.lastIndex++; // Avoid an infinite loop
  1346 + }
  1347 + match = separatorCopy.exec(string);
  1348 + }
  1349 + if (lastLastIndex === string.length) {
  1350 + if (lastLength || !separatorCopy.test('')) {
  1351 + output.push('');
  1352 + }
  1353 + } else {
  1354 + output.push(string.slice(lastLastIndex));
  1355 + }
  1356 + return output.length > splitLimit ? output.slice(0, splitLimit) : output;
  1357 + };
  1358 + }());
  1359 +
  1360 +// [bugfix, chrome]
  1361 +// If separator is undefined, then the result array contains just one String,
  1362 +// which is the this value (converted to a String). If limit is not undefined,
  1363 +// then the output array is truncated so that it contains no more than limit
  1364 +// elements.
  1365 +// "0".split(undefined, 0) -> []
  1366 +} else if ('0'.split(void 0, 0).length) {
  1367 + StringPrototype.split = function split(separator, limit) {
  1368 + if (typeof separator === 'undefined' && limit === 0) { return []; }
  1369 + return string_split.call(this, separator, limit);
  1370 + };
  1371 +}
  1372 +
  1373 +var str_replace = StringPrototype.replace;
  1374 +var replaceReportsGroupsCorrectly = (function () {
  1375 + var groups = [];
  1376 + 'x'.replace(/x(.)?/g, function (match, group) {
  1377 + groups.push(group);
  1378 + });
  1379 + return groups.length === 1 && typeof groups[0] === 'undefined';
  1380 +}());
  1381 +
  1382 +if (!replaceReportsGroupsCorrectly) {
  1383 + StringPrototype.replace = function replace(searchValue, replaceValue) {
  1384 + var isFn = isCallable(replaceValue);
  1385 + var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source);
  1386 + if (!isFn || !hasCapturingGroups) {
  1387 + return str_replace.call(this, searchValue, replaceValue);
  1388 + } else {
  1389 + var wrappedReplaceValue = function (match) {
  1390 + var length = arguments.length;
  1391 + var originalLastIndex = searchValue.lastIndex;
  1392 + searchValue.lastIndex = 0;
  1393 + var args = searchValue.exec(match) || [];
  1394 + searchValue.lastIndex = originalLastIndex;
  1395 + args.push(arguments[length - 2], arguments[length - 1]);
  1396 + return replaceValue.apply(this, args);
  1397 + };
  1398 + return str_replace.call(this, searchValue, wrappedReplaceValue);
  1399 + }
  1400 + };
  1401 +}
  1402 +
  1403 +// ECMA-262, 3rd B.2.3
  1404 +// Not an ECMAScript standard, although ECMAScript 3rd Edition has a
  1405 +// non-normative section suggesting uniform semantics and it should be
  1406 +// normalized across all browsers
  1407 +// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
  1408 +var string_substr = StringPrototype.substr;
  1409 +var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b';
  1410 +defineProperties(StringPrototype, {
  1411 + substr: function substr(start, length) {
  1412 + var normalizedStart = start;
  1413 + if (start < 0) {
  1414 + normalizedStart = Math.max(this.length + start, 0);
  1415 + }
  1416 + return string_substr.call(this, normalizedStart, length);
  1417 + }
  1418 +}, hasNegativeSubstrBug);
  1419 +
  1420 +// ES5 15.5.4.20
  1421 +// whitespace from: http://es5.github.io/#x15.5.4.20
  1422 +var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  1423 + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' +
  1424 + '\u2029\uFEFF';
  1425 +var zeroWidth = '\u200b';
  1426 +var wsRegexChars = '[' + ws + ']';
  1427 +var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*');
  1428 +var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$');
  1429 +var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim());
  1430 +defineProperties(StringPrototype, {
  1431 + // http://blog.stevenlevithan.com/archives/faster-trim-javascript
  1432 + // http://perfectionkills.com/whitespace-deviations/
  1433 + trim: function trim() {
  1434 + if (typeof this === 'undefined' || this === null) {
  1435 + throw new TypeError("can't convert " + this + ' to object');
  1436 + }
  1437 + return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, '');
  1438 + }
  1439 +}, hasTrimWhitespaceBug);
  1440 +
  1441 +// ES-5 15.1.2.2
  1442 +if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) {
  1443 + /*global parseInt: true */
  1444 + parseInt = (function (origParseInt) {
  1445 + var hexRegex = /^0[xX]/;
  1446 + return function parseInt(str, radix) {
  1447 + var string = String(str).trim();
  1448 + var defaultedRadix = Number(radix) || (hexRegex.test(string) ? 16 : 10);
  1449 + return origParseInt(string, defaultedRadix);
  1450 + };
  1451 + }(parseInt));
  1452 +}
  1453 +
  1454 +}));
  1 +casper.on( 'page.initialized', function(){
  2 + this.evaluate(function(){
  3 + var isFunction = function(o) {
  4 + return typeof o == 'function';
  5 + };
  6 +
  7 + var bind,
  8 + slice = [].slice,
  9 + proto = Function.prototype,
  10 + featureMap;
  11 +
  12 + featureMap = {
  13 + 'function-bind': 'bind'
  14 + };
  15 +
  16 + function has(feature) {
  17 + var prop = featureMap[feature];
  18 + return isFunction(proto[prop]);
  19 + }
  20 +
  21 + // check for missing features
  22 + if (!has('function-bind')) {
  23 + // adapted from Mozilla Developer Network example at
  24 + // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
  25 + bind = function bind(obj) {
  26 + var args = slice.call(arguments, 1),
  27 + self = this,
  28 + nop = function() {
  29 + },
  30 + bound = function() {
  31 + return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
  32 + };
  33 + nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
  34 + bound.prototype = new nop();
  35 + return bound;
  36 + };
  37 + proto.bind = bind;
  38 + }
  39 + });
  40 +});
take_screenshots.js View file @ 199c806
  1 +//http://docs.casperjs.org/en/latest/modules/casper.html#captureselector
  2 +//Run with: casperjs --ssl-protocol=tlsv1 ss_test.js
  3 +
  4 +var utils = require('utils');
  5 +
  6 +var casper = require('casper').create({
  7 + verbose: true,
  8 + logLevel: "debug",
  9 + viewportSize: {width: 1200, height: 800},
  10 + onResourceReceived: function(C, requestData, request) {
  11 + //utils.dump(requestData);
  12 + },
  13 +});
  14 +casper.on('remote.msg', function(data){
  15 + this.echo(data);
  16 +});
  17 +
  18 +casper.on( 'page.error', function (msg, trace) {
  19 + this.echo(msg);
  20 +});
  21 +phantom.page.injectJs( 'shim.js');
  22 +function screenshot(pagename) {
  23 + casper.capture('built/screenshots/'+pagename+'.png', {
  24 + top: 0,
  25 + left: 0,
  26 + width: 1200,
  27 + height: 600,
  28 + quality:100
  29 + });
  30 +}
  31 +
  32 +casper.start('https://flashy.cards/app/login',function(){
  33 + screenshot('login');
  34 +/* this.fill('form', {
  35 + 'email': 'casper@flashy.cards',
  36 + 'password': 'casper'
  37 + }, true);
  38 + this.echo('logged in?');*/
  39 +}).thenOpen('https://flashy.cards/app/requestpasswordreset', function () {
  40 + screenshot('requestpasswordreset.png');
  41 +}).thenOpen('https://flashy.cards/app/resetpassword', function () {
  42 + screenshot('resetpassword.png');
  43 +}).thenOpen('https://flashy.cards/app/addclass', function () {
  44 + screenshot('addclass.png');
  45 +}).thenOpen('https://flashy.cards/app/deck', function () {
  46 + screenshot('deck.png');
  47 +}).thenOpen('https://flashy.cards/app/feed', function () {
  48 + screenshot('feed.png');
  49 +}).thenOpen('https://flashy.cards/app/study', function () {
  50 + screenshot('study.png');
  51 +}).thenOpen('https://flashy.cards/app/flashcard', function () {
  52 + screenshot('flashcard.png');
  53 +}).thenOpen('https://flashy.cards/app/logout', function () {
  54 + screenshot('logout.png');
  55 +}).thenOpen('https://flashy.cards/app/verifyemail', function () {
  56 + screenshot('verifyemail.png');
  57 +});
  58 +
  59 +casper.run();