cropper 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +48 -0
  4. data/Gemfile +7 -0
  5. data/README.md +17 -0
  6. data/Rakefile +31 -0
  7. data/app/assets/images/cropper/progress_stripes.png +0 -0
  8. data/app/assets/images/cropper/scale.png +0 -0
  9. data/app/assets/images/cropper/scale_large.png +0 -0
  10. data/app/assets/images/cropper/scale_small.png +0 -0
  11. data/app/assets/images/cropper/upload_spinner.gif +0 -0
  12. data/app/assets/javascripts/cropper.js.coffee +9 -0
  13. data/app/assets/javascripts/cropper/filedrop.js.coffee +255 -0
  14. data/app/assets/javascripts/cropper/upload_crop_scale.js.coffee +360 -0
  15. data/app/assets/javascripts/lib/es5-shim.js +1105 -0
  16. data/app/assets/javascripts/lib/modernizr.js +4 -0
  17. data/app/assets/stylesheets/cropper/uploads.css.sass +203 -0
  18. data/app/controllers/cropper/application_controller.rb +4 -0
  19. data/app/controllers/cropper/uploads_controller.rb +74 -0
  20. data/app/helpers/cropper/application_helper.rb +4 -0
  21. data/app/models/cropper/upload.rb +231 -0
  22. data/app/views/cropper/uploads/_crop.html.haml +34 -0
  23. data/app/views/cropper/uploads/_error.html.haml +1 -0
  24. data/app/views/cropper/uploads/_pick.html.haml +42 -0
  25. data/app/views/cropper/uploads/edit.html.haml +6 -0
  26. data/app/views/cropper/uploads/new.html.haml +5 -0
  27. data/app/views/cropper/uploads/show.html.haml +1 -0
  28. data/config/locales/en.yml +5 -0
  29. data/config/routes.rb +3 -0
  30. data/cropper.gemspec +32 -0
  31. data/db/migrate/20120510103921_uploads.rb +11 -0
  32. data/db/migrate/20130226190434_uploads_hold_crop_data.rb +8 -0
  33. data/db/migrate/20130402074802_upload_holder.rb +20 -0
  34. data/init.rb +4 -0
  35. data/lib/cropper.rb +159 -0
  36. data/lib/cropper/engine.rb +8 -0
  37. data/lib/cropper/glue.rb +20 -0
  38. data/lib/cropper/routing.rb +23 -0
  39. data/lib/cropper/schema.rb +63 -0
  40. data/lib/cropper/version.rb +3 -0
  41. data/lib/paperclip/geometry_transformation.rb +80 -0
  42. data/lib/paperclip/validators/attachment_height_validator.rb +89 -0
  43. data/lib/paperclip/validators/attachment_width_validator.rb +89 -0
  44. data/lib/paperclip_processors/offset_thumbnail.rb +93 -0
  45. data/lib/tasks/cropper_tasks.rake +4 -0
  46. data/script/rails +8 -0
  47. data/spec/acceptance/acceptance_helper.rb +2 -0
  48. data/spec/controllers/uploads_controller_spec.rb +5 -0
  49. data/spec/dummy/README.rdoc +261 -0
  50. data/spec/dummy/Rakefile +7 -0
  51. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  52. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  53. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  54. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  55. data/spec/dummy/app/mailers/.gitkeep +0 -0
  56. data/spec/dummy/app/models/.gitkeep +0 -0
  57. data/spec/dummy/app/models/thing.rb +4 -0
  58. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  59. data/spec/dummy/config.ru +4 -0
  60. data/spec/dummy/config/application.rb +56 -0
  61. data/spec/dummy/config/boot.rb +10 -0
  62. data/spec/dummy/config/database.yml +25 -0
  63. data/spec/dummy/config/environment.rb +5 -0
  64. data/spec/dummy/config/environments/development.rb +37 -0
  65. data/spec/dummy/config/environments/production.rb +67 -0
  66. data/spec/dummy/config/environments/test.rb +37 -0
  67. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  68. data/spec/dummy/config/initializers/inflections.rb +15 -0
  69. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  70. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  71. data/spec/dummy/config/initializers/session_store.rb +8 -0
  72. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  73. data/spec/dummy/config/locales/en.yml +5 -0
  74. data/spec/dummy/config/routes.rb +6 -0
  75. data/spec/dummy/db/migrate/20120510104910_things.rb +8 -0
  76. data/spec/dummy/db/schema.rb +51 -0
  77. data/spec/dummy/lib/assets/.gitkeep +0 -0
  78. data/spec/dummy/log/.gitkeep +0 -0
  79. data/spec/dummy/public/404.html +26 -0
  80. data/spec/dummy/public/422.html +26 -0
  81. data/spec/dummy/public/500.html +25 -0
  82. data/spec/dummy/public/favicon.ico +0 -0
  83. data/spec/dummy/script/rails +6 -0
  84. data/spec/fixtures/images/icon.png +0 -0
  85. data/spec/fixtures/images/test.jpg +0 -0
  86. data/spec/models/thing_spec.rb +6 -0
  87. data/spec/models/upload_spec.rb +7 -0
  88. data/spec/spec_helper.rb +18 -0
  89. metadata +326 -0
@@ -0,0 +1,1105 @@
1
+ // vim: ts=4 sts=4 sw=4 expandtab
2
+ // -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License
3
+ // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
4
+ // -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA
5
+ // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
6
+ // -- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License
7
+ // -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License
8
+ // -- kossnocorp Sasha Koss XXX TODO License or CLA
9
+ // -- bryanforbes Bryan Forbes XXX TODO License or CLA
10
+ // -- killdream Quildreen Motta Copyright (C) 2011 MIT Licence
11
+ // -- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD License
12
+ // -- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License
13
+ // -- bbqsrc Brendan Molloy (C) 2011 Creative Commons Zero (public domain)
14
+ // -- iwyg XXX TODO License or CLA
15
+ // -- DomenicDenicola Domenic Denicola Copyright (C) 2011 MIT License
16
+ // -- xavierm02 Montillet Xavier Copyright (C) 2011 MIT License
17
+ // -- Raynos Jake Verbaten Copyright (C) 2011 MIT Licence
18
+ // -- samsonjs Sami Samhuri Copyright (C) 2010 MIT License
19
+ // -- rwldrn Rick Waldron Copyright (C) 2011 MIT License
20
+ // -- lexer Alexey Zakharov XXX TODO License or CLA
21
+
22
+ /*!
23
+ Copyright (c) 2009, 280 North Inc. http://280north.com/
24
+ MIT License. http://github.com/280north/narwhal/blob/master/README.md
25
+ */
26
+
27
+ // Module systems magic dance
28
+ (function (definition) {
29
+ // RequireJS
30
+ if (typeof define == "function") {
31
+ define(definition);
32
+ // CommonJS and <script>
33
+ } else {
34
+ definition();
35
+ }
36
+ })(function () {
37
+
38
+ /**
39
+ * Brings an environment as close to ECMAScript 5 compliance
40
+ * as is possible with the facilities of erstwhile engines.
41
+ *
42
+ * Annotated ES5: http://es5.github.com/ (specific links below)
43
+ * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
44
+ * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/
45
+ */
46
+
47
+ //
48
+ // Function
49
+ // ========
50
+ //
51
+
52
+ // ES-5 15.3.4.5
53
+ // http://es5.github.com/#x15.3.4.5
54
+
55
+ if (!Function.prototype.bind) {
56
+ Function.prototype.bind = function bind(that) { // .length is 1
57
+ // 1. Let Target be the this value.
58
+ var target = this;
59
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
60
+ if (typeof target != "function") {
61
+ throw new TypeError("Function.prototype.bind called on incompatible " + target);
62
+ }
63
+ // 3. Let A be a new (possibly empty) internal list of all of the
64
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
65
+ // XXX slicedArgs will stand in for "A" if used
66
+ var args = slice.call(arguments, 1); // for normal call
67
+ // 4. Let F be a new native ECMAScript object.
68
+ // 11. Set the [[Prototype]] internal property of F to the standard
69
+ // built-in Function prototype object as specified in 15.3.3.1.
70
+ // 12. Set the [[Call]] internal property of F as described in
71
+ // 15.3.4.5.1.
72
+ // 13. Set the [[Construct]] internal property of F as described in
73
+ // 15.3.4.5.2.
74
+ // 14. Set the [[HasInstance]] internal property of F as described in
75
+ // 15.3.4.5.3.
76
+ var bound = function () {
77
+
78
+ if (this instanceof bound) {
79
+ // 15.3.4.5.2 [[Construct]]
80
+ // When the [[Construct]] internal method of a function object,
81
+ // F that was created using the bind function is called with a
82
+ // list of arguments ExtraArgs, the following steps are taken:
83
+ // 1. Let target be the value of F's [[TargetFunction]]
84
+ // internal property.
85
+ // 2. If target has no [[Construct]] internal method, a
86
+ // TypeError exception is thrown.
87
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
88
+ // property.
89
+ // 4. Let args be a new list containing the same values as the
90
+ // list boundArgs in the same order followed by the same
91
+ // values as the list ExtraArgs in the same order.
92
+ // 5. Return the result of calling the [[Construct]] internal
93
+ // method of target providing args as the arguments.
94
+
95
+ var F = function(){};
96
+ F.prototype = target.prototype;
97
+ var self = new F;
98
+
99
+ var result = target.apply(
100
+ self,
101
+ args.concat(slice.call(arguments))
102
+ );
103
+ if (Object(result) === result) {
104
+ return result;
105
+ }
106
+ return self;
107
+
108
+ } else {
109
+ // 15.3.4.5.1 [[Call]]
110
+ // When the [[Call]] internal method of a function object, F,
111
+ // which was created using the bind function is called with a
112
+ // this value and a list of arguments ExtraArgs, the following
113
+ // steps are taken:
114
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
115
+ // property.
116
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
117
+ // property.
118
+ // 3. Let target be the value of F's [[TargetFunction]] internal
119
+ // property.
120
+ // 4. Let args be a new list containing the same values as the
121
+ // list boundArgs in the same order followed by the same
122
+ // values as the list ExtraArgs in the same order.
123
+ // 5. Return the result of calling the [[Call]] internal method
124
+ // of target providing boundThis as the this value and
125
+ // providing args as the arguments.
126
+
127
+ // equiv: target.call(this, ...boundArgs, ...args)
128
+ return target.apply(
129
+ that,
130
+ args.concat(slice.call(arguments))
131
+ );
132
+
133
+ }
134
+
135
+ };
136
+ // XXX bound.length is never writable, so don't even try
137
+ //
138
+ // 15. If the [[Class]] internal property of Target is "Function", then
139
+ // a. Let L be the length property of Target minus the length of A.
140
+ // b. Set the length own property of F to either 0 or L, whichever is
141
+ // larger.
142
+ // 16. Else set the length own property of F to 0.
143
+ // 17. Set the attributes of the length own property of F to the values
144
+ // specified in 15.3.5.1.
145
+
146
+ // TODO
147
+ // 18. Set the [[Extensible]] internal property of F to true.
148
+
149
+ // TODO
150
+ // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3).
151
+ // 20. Call the [[DefineOwnProperty]] internal method of F with
152
+ // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]:
153
+ // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and
154
+ // false.
155
+ // 21. Call the [[DefineOwnProperty]] internal method of F with
156
+ // arguments "arguments", PropertyDescriptor {[[Get]]: thrower,
157
+ // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false},
158
+ // and false.
159
+
160
+ // TODO
161
+ // NOTE Function objects created using Function.prototype.bind do not
162
+ // have a prototype property or the [[Code]], [[FormalParameters]], and
163
+ // [[Scope]] internal properties.
164
+ // XXX can't delete prototype in pure-js.
165
+
166
+ // 22. Return F.
167
+ return bound;
168
+ };
169
+ }
170
+
171
+ // Shortcut to an often accessed properties, in order to avoid multiple
172
+ // dereference that costs universally.
173
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
174
+ // us it in defining shortcuts.
175
+ var call = Function.prototype.call;
176
+ var prototypeOfArray = Array.prototype;
177
+ var prototypeOfObject = Object.prototype;
178
+ var slice = prototypeOfArray.slice;
179
+ // Having a toString local variable name breaks in Opera so use _toString.
180
+ var _toString = call.bind(prototypeOfObject.toString);
181
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
182
+
183
+ // If JS engine supports accessors creating shortcuts.
184
+ var defineGetter;
185
+ var defineSetter;
186
+ var lookupGetter;
187
+ var lookupSetter;
188
+ var supportsAccessors;
189
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
190
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
191
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
192
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
193
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
194
+ }
195
+
196
+ //
197
+ // Array
198
+ // =====
199
+ //
200
+
201
+ // ES5 15.4.3.2
202
+ // http://es5.github.com/#x15.4.3.2
203
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
204
+ if (!Array.isArray) {
205
+ Array.isArray = function isArray(obj) {
206
+ return _toString(obj) == "[object Array]";
207
+ };
208
+ }
209
+
210
+ // The IsCallable() check in the Array functions
211
+ // has been replaced with a strict check on the
212
+ // internal class of the object to trap cases where
213
+ // the provided function was actually a regular
214
+ // expression literal, which in V8 and
215
+ // JavaScriptCore is a typeof "function". Only in
216
+ // V8 are regular expression literals permitted as
217
+ // reduce parameters, so it is desirable in the
218
+ // general case for the shim to match the more
219
+ // strict and common behavior of rejecting regular
220
+ // expressions.
221
+
222
+ // ES5 15.4.4.18
223
+ // http://es5.github.com/#x15.4.4.18
224
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
225
+ if (!Array.prototype.forEach) {
226
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
227
+ var self = toObject(this),
228
+ thisp = arguments[1],
229
+ i = -1,
230
+ length = self.length >>> 0;
231
+
232
+ // If no callback function or if callback is not a callable function
233
+ if (_toString(fun) != "[object Function]") {
234
+ throw new TypeError(); // TODO message
235
+ }
236
+
237
+ while (++i < length) {
238
+ if (i in self) {
239
+ // Invoke the callback function with call, passing arguments:
240
+ // context, property value, property key, thisArg object context
241
+ fun.call(thisp, self[i], i, self);
242
+ }
243
+ }
244
+ };
245
+ }
246
+
247
+ // ES5 15.4.4.19
248
+ // http://es5.github.com/#x15.4.4.19
249
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
250
+ if (!Array.prototype.map) {
251
+ Array.prototype.map = function map(fun /*, thisp*/) {
252
+ var self = toObject(this),
253
+ length = self.length >>> 0,
254
+ result = Array(length),
255
+ thisp = arguments[1];
256
+
257
+ // If no callback function or if callback is not a callable function
258
+ if (_toString(fun) != "[object Function]") {
259
+ throw new TypeError(fun + " is not a function");
260
+ }
261
+
262
+ for (var i = 0; i < length; i++) {
263
+ if (i in self)
264
+ result[i] = fun.call(thisp, self[i], i, self);
265
+ }
266
+ return result;
267
+ };
268
+ }
269
+
270
+ // ES5 15.4.4.20
271
+ // http://es5.github.com/#x15.4.4.20
272
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
273
+ if (!Array.prototype.filter) {
274
+ Array.prototype.filter = function filter(fun /*, thisp */) {
275
+ var self = toObject(this),
276
+ length = self.length >>> 0,
277
+ result = [],
278
+ value,
279
+ thisp = arguments[1];
280
+
281
+ // If no callback function or if callback is not a callable function
282
+ if (_toString(fun) != "[object Function]") {
283
+ throw new TypeError(fun + " is not a function");
284
+ }
285
+
286
+ for (var i = 0; i < length; i++) {
287
+ if (i in self) {
288
+ value = self[i];
289
+ if (fun.call(thisp, value, i, self)) {
290
+ result.push(value);
291
+ }
292
+ }
293
+ }
294
+ return result;
295
+ };
296
+ }
297
+
298
+ // ES5 15.4.4.16
299
+ // http://es5.github.com/#x15.4.4.16
300
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
301
+ if (!Array.prototype.every) {
302
+ Array.prototype.every = function every(fun /*, thisp */) {
303
+ var self = toObject(this),
304
+ length = self.length >>> 0,
305
+ thisp = arguments[1];
306
+
307
+ // If no callback function or if callback is not a callable function
308
+ if (_toString(fun) != "[object Function]") {
309
+ throw new TypeError(fun + " is not a function");
310
+ }
311
+
312
+ for (var i = 0; i < length; i++) {
313
+ if (i in self && !fun.call(thisp, self[i], i, self)) {
314
+ return false;
315
+ }
316
+ }
317
+ return true;
318
+ };
319
+ }
320
+
321
+ // ES5 15.4.4.17
322
+ // http://es5.github.com/#x15.4.4.17
323
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
324
+ if (!Array.prototype.some) {
325
+ Array.prototype.some = function some(fun /*, thisp */) {
326
+ var self = toObject(this),
327
+ length = self.length >>> 0,
328
+ thisp = arguments[1];
329
+
330
+ // If no callback function or if callback is not a callable function
331
+ if (_toString(fun) != "[object Function]") {
332
+ throw new TypeError(fun + " is not a function");
333
+ }
334
+
335
+ for (var i = 0; i < length; i++) {
336
+ if (i in self && fun.call(thisp, self[i], i, self)) {
337
+ return true;
338
+ }
339
+ }
340
+ return false;
341
+ };
342
+ }
343
+
344
+ // ES5 15.4.4.21
345
+ // http://es5.github.com/#x15.4.4.21
346
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
347
+ if (!Array.prototype.reduce) {
348
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
349
+ var self = toObject(this),
350
+ length = self.length >>> 0;
351
+
352
+ // If no callback function or if callback is not a callable function
353
+ if (_toString(fun) != "[object Function]") {
354
+ throw new TypeError(fun + " is not a function");
355
+ }
356
+
357
+ // no value to return if no initial value and an empty array
358
+ if (!length && arguments.length == 1) {
359
+ throw new TypeError('reduce of empty array with no initial value');
360
+ }
361
+
362
+ var i = 0;
363
+ var result;
364
+ if (arguments.length >= 2) {
365
+ result = arguments[1];
366
+ } else {
367
+ do {
368
+ if (i in self) {
369
+ result = self[i++];
370
+ break;
371
+ }
372
+
373
+ // if array contains no values, no initial value to return
374
+ if (++i >= length) {
375
+ throw new TypeError('reduce of empty array with no initial value');
376
+ }
377
+ } while (true);
378
+ }
379
+
380
+ for (; i < length; i++) {
381
+ if (i in self) {
382
+ result = fun.call(void 0, result, self[i], i, self);
383
+ }
384
+ }
385
+
386
+ return result;
387
+ };
388
+ }
389
+
390
+ // ES5 15.4.4.22
391
+ // http://es5.github.com/#x15.4.4.22
392
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
393
+ if (!Array.prototype.reduceRight) {
394
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
395
+ var self = toObject(this),
396
+ length = self.length >>> 0;
397
+
398
+ // If no callback function or if callback is not a callable function
399
+ if (_toString(fun) != "[object Function]") {
400
+ throw new TypeError(fun + " is not a function");
401
+ }
402
+
403
+ // no value to return if no initial value, empty array
404
+ if (!length && arguments.length == 1) {
405
+ throw new TypeError('reduceRight of empty array with no initial value');
406
+ }
407
+
408
+ var result, i = length - 1;
409
+ if (arguments.length >= 2) {
410
+ result = arguments[1];
411
+ } else {
412
+ do {
413
+ if (i in self) {
414
+ result = self[i--];
415
+ break;
416
+ }
417
+
418
+ // if array contains no values, no initial value to return
419
+ if (--i < 0) {
420
+ throw new TypeError('reduceRight of empty array with no initial value');
421
+ }
422
+ } while (true);
423
+ }
424
+
425
+ do {
426
+ if (i in this) {
427
+ result = fun.call(void 0, result, self[i], i, self);
428
+ }
429
+ } while (i--);
430
+
431
+ return result;
432
+ };
433
+ }
434
+
435
+ // ES5 15.4.4.14
436
+ // http://es5.github.com/#x15.4.4.14
437
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
438
+ if (!Array.prototype.indexOf) {
439
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
440
+ var self = toObject(this),
441
+ length = self.length >>> 0;
442
+
443
+ if (!length) {
444
+ return -1;
445
+ }
446
+
447
+ var i = 0;
448
+ if (arguments.length > 1) {
449
+ i = toInteger(arguments[1]);
450
+ }
451
+
452
+ // handle negative indices
453
+ i = i >= 0 ? i : Math.max(0, length + i);
454
+ for (; i < length; i++) {
455
+ if (i in self && self[i] === sought) {
456
+ return i;
457
+ }
458
+ }
459
+ return -1;
460
+ };
461
+ }
462
+
463
+ // ES5 15.4.4.15
464
+ // http://es5.github.com/#x15.4.4.15
465
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
466
+ if (!Array.prototype.lastIndexOf) {
467
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
468
+ var self = toObject(this),
469
+ length = self.length >>> 0;
470
+
471
+ if (!length) {
472
+ return -1;
473
+ }
474
+ var i = length - 1;
475
+ if (arguments.length > 1) {
476
+ i = Math.min(i, toInteger(arguments[1]));
477
+ }
478
+ // handle negative indices
479
+ i = i >= 0 ? i : length - Math.abs(i);
480
+ for (; i >= 0; i--) {
481
+ if (i in self && sought === self[i]) {
482
+ return i;
483
+ }
484
+ }
485
+ return -1;
486
+ };
487
+ }
488
+
489
+ //
490
+ // Object
491
+ // ======
492
+ //
493
+
494
+ // ES5 15.2.3.2
495
+ // http://es5.github.com/#x15.2.3.2
496
+ if (!Object.getPrototypeOf) {
497
+ // https://github.com/kriskowal/es5-shim/issues#issue/2
498
+ // http://ejohn.org/blog/objectgetprototypeof/
499
+ // recommended by fschaefer on github
500
+ Object.getPrototypeOf = function getPrototypeOf(object) {
501
+ return object.__proto__ || (
502
+ object.constructor
503
+ ? object.constructor.prototype
504
+ : prototypeOfObject
505
+ );
506
+ };
507
+ }
508
+
509
+ // ES5 15.2.3.3
510
+ // http://es5.github.com/#x15.2.3.3
511
+ if (!Object.getOwnPropertyDescriptor) {
512
+ var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object: ";
513
+
514
+ Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
515
+ if ((typeof object != "object" && typeof object != "function") || object === null) {
516
+ throw new TypeError(ERR_NON_OBJECT + object);
517
+ }
518
+ // If object does not owns property return undefined immediately.
519
+ if (!owns(object, property)) {
520
+ return;
521
+ }
522
+
523
+ // If object has a property then it's for sure both `enumerable` and
524
+ // `configurable`.
525
+ var descriptor = { enumerable: true, configurable: true };
526
+
527
+ // If JS engine supports accessor properties then property may be a
528
+ // getter or setter.
529
+ if (supportsAccessors) {
530
+ // Unfortunately `__lookupGetter__` will return a getter even
531
+ // if object has own non getter property along with a same named
532
+ // inherited getter. To avoid misbehavior we temporary remove
533
+ // `__proto__` so that `__lookupGetter__` will return getter only
534
+ // if it's owned by an object.
535
+ var prototype = object.__proto__;
536
+ object.__proto__ = prototypeOfObject;
537
+
538
+ var getter = lookupGetter(object, property);
539
+ var setter = lookupSetter(object, property);
540
+
541
+ // Once we have getter and setter we can put values back.
542
+ object.__proto__ = prototype;
543
+
544
+ if (getter || setter) {
545
+ if (getter) {
546
+ descriptor.get = getter;
547
+ }
548
+ if (setter) {
549
+ descriptor.set = setter;
550
+ }
551
+ // If it was accessor property we're done and return here
552
+ // in order to avoid adding `value` to the descriptor.
553
+ return descriptor;
554
+ }
555
+ }
556
+
557
+ // If we got this far we know that object has an own property that is
558
+ // not an accessor so we set it as a value and return descriptor.
559
+ descriptor.value = object[property];
560
+ return descriptor;
561
+ };
562
+ }
563
+
564
+ // ES5 15.2.3.4
565
+ // http://es5.github.com/#x15.2.3.4
566
+ if (!Object.getOwnPropertyNames) {
567
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
568
+ return Object.keys(object);
569
+ };
570
+ }
571
+
572
+ // ES5 15.2.3.5
573
+ // http://es5.github.com/#x15.2.3.5
574
+ if (!Object.create) {
575
+ Object.create = function create(prototype, properties) {
576
+ var object;
577
+ if (prototype === null) {
578
+ object = { "__proto__": null };
579
+ } else {
580
+ if (typeof prototype != "object") {
581
+ throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
582
+ }
583
+ var Type = function () {};
584
+ Type.prototype = prototype;
585
+ object = new Type();
586
+ // IE has no built-in implementation of `Object.getPrototypeOf`
587
+ // neither `__proto__`, but this manually setting `__proto__` will
588
+ // guarantee that `Object.getPrototypeOf` will work as expected with
589
+ // objects created using `Object.create`
590
+ object.__proto__ = prototype;
591
+ }
592
+ if (properties !== void 0) {
593
+ Object.defineProperties(object, properties);
594
+ }
595
+ return object;
596
+ };
597
+ }
598
+
599
+ // ES5 15.2.3.6
600
+ // http://es5.github.com/#x15.2.3.6
601
+
602
+ // Patch for WebKit and IE8 standard mode
603
+ // Designed by hax <hax.github.com>
604
+ // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
605
+ // IE8 Reference:
606
+ // http://msdn.microsoft.com/en-us/library/dd282900.aspx
607
+ // http://msdn.microsoft.com/en-us/library/dd229916.aspx
608
+ // WebKit Bugs:
609
+ // https://bugs.webkit.org/show_bug.cgi?id=36423
610
+
611
+ function doesDefinePropertyWork(object) {
612
+ try {
613
+ Object.defineProperty(object, "sentinel", {});
614
+ return "sentinel" in object;
615
+ } catch (exception) {
616
+ // returns falsy
617
+ }
618
+ }
619
+
620
+ // check whether defineProperty works if it's given. Otherwise,
621
+ // shim partially.
622
+ if (Object.defineProperty) {
623
+ var definePropertyWorksOnObject = doesDefinePropertyWork({});
624
+ var definePropertyWorksOnDom = typeof document == "undefined" ||
625
+ doesDefinePropertyWork(document.createElement("div"));
626
+ if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
627
+ var definePropertyFallback = Object.defineProperty;
628
+ }
629
+ }
630
+
631
+ if (!Object.defineProperty || definePropertyFallback) {
632
+ var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
633
+ var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
634
+ var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
635
+ "on this javascript engine";
636
+
637
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
638
+ if ((typeof object != "object" && typeof object != "function") || object === null) {
639
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
640
+ }
641
+ if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) {
642
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
643
+ }
644
+ // make a valiant attempt to use the real defineProperty
645
+ // for I8's DOM elements.
646
+ if (definePropertyFallback) {
647
+ try {
648
+ return definePropertyFallback.call(Object, object, property, descriptor);
649
+ } catch (exception) {
650
+ // try the shim if the real one doesn't work
651
+ }
652
+ }
653
+
654
+ // If it's a data property.
655
+ if (owns(descriptor, "value")) {
656
+ // fail silently if "writable", "enumerable", or "configurable"
657
+ // are requested but not supported
658
+ /*
659
+ // alternate approach:
660
+ if ( // can't implement these features; allow false but not true
661
+ !(owns(descriptor, "writable") ? descriptor.writable : true) ||
662
+ !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
663
+ !(owns(descriptor, "configurable") ? descriptor.configurable : true)
664
+ )
665
+ throw new RangeError(
666
+ "This implementation of Object.defineProperty does not " +
667
+ "support configurable, enumerable, or writable."
668
+ );
669
+ */
670
+
671
+ if (supportsAccessors && (lookupGetter(object, property) ||
672
+ lookupSetter(object, property)))
673
+ {
674
+ // As accessors are supported only on engines implementing
675
+ // `__proto__` we can safely override `__proto__` while defining
676
+ // a property to make sure that we don't hit an inherited
677
+ // accessor.
678
+ var prototype = object.__proto__;
679
+ object.__proto__ = prototypeOfObject;
680
+ // Deleting a property anyway since getter / setter may be
681
+ // defined on object itself.
682
+ delete object[property];
683
+ object[property] = descriptor.value;
684
+ // Setting original `__proto__` back now.
685
+ object.__proto__ = prototype;
686
+ } else {
687
+ object[property] = descriptor.value;
688
+ }
689
+ } else {
690
+ if (!supportsAccessors) {
691
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
692
+ }
693
+ // If we got that far then getters and setters can be defined !!
694
+ if (owns(descriptor, "get")) {
695
+ defineGetter(object, property, descriptor.get);
696
+ }
697
+ if (owns(descriptor, "set")) {
698
+ defineSetter(object, property, descriptor.set);
699
+ }
700
+ }
701
+ return object;
702
+ };
703
+ }
704
+
705
+ // ES5 15.2.3.7
706
+ // http://es5.github.com/#x15.2.3.7
707
+ if (!Object.defineProperties) {
708
+ Object.defineProperties = function defineProperties(object, properties) {
709
+ for (var property in properties) {
710
+ if (owns(properties, property) && property != "__proto__") {
711
+ Object.defineProperty(object, property, properties[property]);
712
+ }
713
+ }
714
+ return object;
715
+ };
716
+ }
717
+
718
+ // ES5 15.2.3.8
719
+ // http://es5.github.com/#x15.2.3.8
720
+ if (!Object.seal) {
721
+ Object.seal = function seal(object) {
722
+ // this is misleading and breaks feature-detection, but
723
+ // allows "securable" code to "gracefully" degrade to working
724
+ // but insecure code.
725
+ return object;
726
+ };
727
+ }
728
+
729
+ // ES5 15.2.3.9
730
+ // http://es5.github.com/#x15.2.3.9
731
+ if (!Object.freeze) {
732
+ Object.freeze = function freeze(object) {
733
+ // this is misleading and breaks feature-detection, but
734
+ // allows "securable" code to "gracefully" degrade to working
735
+ // but insecure code.
736
+ return object;
737
+ };
738
+ }
739
+
740
+ // detect a Rhino bug and patch it
741
+ try {
742
+ Object.freeze(function () {});
743
+ } catch (exception) {
744
+ Object.freeze = (function freeze(freezeObject) {
745
+ return function freeze(object) {
746
+ if (typeof object == "function") {
747
+ return object;
748
+ } else {
749
+ return freezeObject(object);
750
+ }
751
+ };
752
+ })(Object.freeze);
753
+ }
754
+
755
+ // ES5 15.2.3.10
756
+ // http://es5.github.com/#x15.2.3.10
757
+ if (!Object.preventExtensions) {
758
+ Object.preventExtensions = function preventExtensions(object) {
759
+ // this is misleading and breaks feature-detection, but
760
+ // allows "securable" code to "gracefully" degrade to working
761
+ // but insecure code.
762
+ return object;
763
+ };
764
+ }
765
+
766
+ // ES5 15.2.3.11
767
+ // http://es5.github.com/#x15.2.3.11
768
+ if (!Object.isSealed) {
769
+ Object.isSealed = function isSealed(object) {
770
+ return false;
771
+ };
772
+ }
773
+
774
+ // ES5 15.2.3.12
775
+ // http://es5.github.com/#x15.2.3.12
776
+ if (!Object.isFrozen) {
777
+ Object.isFrozen = function isFrozen(object) {
778
+ return false;
779
+ };
780
+ }
781
+
782
+ // ES5 15.2.3.13
783
+ // http://es5.github.com/#x15.2.3.13
784
+ if (!Object.isExtensible) {
785
+ Object.isExtensible = function isExtensible(object) {
786
+ // 1. If Type(O) is not Object throw a TypeError exception.
787
+ if (Object(object) !== object) {
788
+ throw new TypeError(); // TODO message
789
+ }
790
+ // 2. Return the Boolean value of the [[Extensible]] internal property of O.
791
+ var name = '';
792
+ while (owns(object, name)) {
793
+ name += '?';
794
+ }
795
+ object[name] = true;
796
+ var returnValue = owns(object, name);
797
+ delete object[name];
798
+ return returnValue;
799
+ };
800
+ }
801
+
802
+ // ES5 15.2.3.14
803
+ // http://es5.github.com/#x15.2.3.14
804
+ if (!Object.keys) {
805
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
806
+ var hasDontEnumBug = true,
807
+ dontEnums = [
808
+ "toString",
809
+ "toLocaleString",
810
+ "valueOf",
811
+ "hasOwnProperty",
812
+ "isPrototypeOf",
813
+ "propertyIsEnumerable",
814
+ "constructor"
815
+ ],
816
+ dontEnumsLength = dontEnums.length;
817
+
818
+ for (var key in {"toString": null}) {
819
+ hasDontEnumBug = false;
820
+ }
821
+
822
+ Object.keys = function keys(object) {
823
+
824
+ if ((typeof object != "object" && typeof object != "function") || object === null) {
825
+ throw new TypeError("Object.keys called on a non-object");
826
+ }
827
+
828
+ var keys = [];
829
+ for (var name in object) {
830
+ if (owns(object, name)) {
831
+ keys.push(name);
832
+ }
833
+ }
834
+
835
+ if (hasDontEnumBug) {
836
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
837
+ var dontEnum = dontEnums[i];
838
+ if (owns(object, dontEnum)) {
839
+ keys.push(dontEnum);
840
+ }
841
+ }
842
+ }
843
+ return keys;
844
+ };
845
+
846
+ }
847
+
848
+ //
849
+ // Date
850
+ // ====
851
+ //
852
+
853
+ // ES5 15.9.5.43
854
+ // http://es5.github.com/#x15.9.5.43
855
+ // This function returns a String value represent the instance in time
856
+ // represented by this Date object. The format of the String is the Date Time
857
+ // string format defined in 15.9.1.15. All fields are present in the String.
858
+ // The time zone is always UTC, denoted by the suffix Z. If the time value of
859
+ // this object is not a finite Number a RangeError exception is thrown.
860
+ if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) {
861
+ Date.prototype.toISOString = function toISOString() {
862
+ var result, length, value, year;
863
+ if (!isFinite(this)) {
864
+ throw new RangeError("Date.prototype.toISOString called on non-finite value.");
865
+ }
866
+
867
+ // the date time string format is specified in 15.9.1.15.
868
+ result = [this.getUTCMonth() + 1, this.getUTCDate(),
869
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
870
+ year = this.getUTCFullYear();
871
+ year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6);
872
+
873
+ length = result.length;
874
+ while (length--) {
875
+ value = result[length];
876
+ // pad months, days, hours, minutes, and seconds to have two digits.
877
+ if (value < 10) {
878
+ result[length] = "0" + value;
879
+ }
880
+ }
881
+ // pad milliseconds to have three digits.
882
+ return year + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." +
883
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
884
+ }
885
+ }
886
+
887
+ // ES5 15.9.4.4
888
+ // http://es5.github.com/#x15.9.4.4
889
+ if (!Date.now) {
890
+ Date.now = function now() {
891
+ return new Date().getTime();
892
+ };
893
+ }
894
+
895
+ // ES5 15.9.5.44
896
+ // http://es5.github.com/#x15.9.5.44
897
+ // This function provides a String representation of a Date object for use by
898
+ // JSON.stringify (15.12.3).
899
+ if (!Date.prototype.toJSON) {
900
+ Date.prototype.toJSON = function toJSON(key) {
901
+ // When the toJSON method is called with argument key, the following
902
+ // steps are taken:
903
+
904
+ // 1. Let O be the result of calling ToObject, giving it the this
905
+ // value as its argument.
906
+ // 2. Let tv be ToPrimitive(O, hint Number).
907
+ // 3. If tv is a Number and is not finite, return null.
908
+ // XXX
909
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
910
+ // O with argument "toISOString".
911
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
912
+ if (typeof this.toISOString != "function") {
913
+ throw new TypeError('toISOString property is not callable');
914
+ }
915
+ // 6. Return the result of calling the [[Call]] internal method of
916
+ // toISO with O as the this value and an empty argument list.
917
+ return this.toISOString();
918
+
919
+ // NOTE 1 The argument is ignored.
920
+
921
+ // NOTE 2 The toJSON function is intentionally generic; it does not
922
+ // require that its this value be a Date object. Therefore, it can be
923
+ // transferred to other kinds of objects for use as a method. However,
924
+ // it does require that any such object have a toISOString method. An
925
+ // object is free to use the argument key to filter its
926
+ // stringification.
927
+ };
928
+ }
929
+
930
+ // ES5 15.9.4.2
931
+ // http://es5.github.com/#x15.9.4.2
932
+ // based on work shared by Daniel Friesen (dantman)
933
+ // http://gist.github.com/303249
934
+ if (!Date.parse || Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) {
935
+ // XXX global assignment won't work in embeddings that use
936
+ // an alternate object for the context.
937
+ Date = (function(NativeDate) {
938
+
939
+ // Date.length === 7
940
+ var Date = function Date(Y, M, D, h, m, s, ms) {
941
+ var length = arguments.length;
942
+ if (this instanceof NativeDate) {
943
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
944
+ // We explicitly pass it through parse:
945
+ new NativeDate(Date.parse(Y)) :
946
+ // We have to manually make calls depending on argument
947
+ // length here
948
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
949
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
950
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
951
+ length >= 4 ? new NativeDate(Y, M, D, h) :
952
+ length >= 3 ? new NativeDate(Y, M, D) :
953
+ length >= 2 ? new NativeDate(Y, M) :
954
+ length >= 1 ? new NativeDate(Y) :
955
+ new NativeDate();
956
+ // Prevent mixups with unfixed Date object
957
+ date.constructor = Date;
958
+ return date;
959
+ }
960
+ return NativeDate.apply(this, arguments);
961
+ };
962
+
963
+ // 15.9.1.15 Date Time String Format.
964
+ var isoDateExpression = new RegExp("^" +
965
+ "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 6-digit extended year
966
+ "(?:-(\\d{2})" + // optional month capture
967
+ "(?:-(\\d{2})" + // optional day capture
968
+ "(?:" + // capture hours:minutes:seconds.milliseconds
969
+ "T(\\d{2})" + // hours capture
970
+ ":(\\d{2})" + // minutes capture
971
+ "(?:" + // optional :seconds.milliseconds
972
+ ":(\\d{2})" + // seconds capture
973
+ "(?:\\.(\\d{3}))?" + // milliseconds capture
974
+ ")?" +
975
+ "(?:" + // capture UTC offset component
976
+ "Z|" + // UTC capture
977
+ "(?:" + // offset specifier +/-hours:minutes
978
+ "([-+])" + // sign capture
979
+ "(\\d{2})" + // hours offset capture
980
+ ":(\\d{2})" + // minutes offset capture
981
+ ")" +
982
+ ")?)?)?)?" +
983
+ "$");
984
+
985
+ // Copy any custom methods a 3rd party library may have added
986
+ for (var key in NativeDate) {
987
+ Date[key] = NativeDate[key];
988
+ }
989
+
990
+ // Copy "native" methods explicitly; they may be non-enumerable
991
+ Date.now = NativeDate.now;
992
+ Date.UTC = NativeDate.UTC;
993
+ Date.prototype = NativeDate.prototype;
994
+ Date.prototype.constructor = Date;
995
+
996
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
997
+ Date.parse = function parse(string) {
998
+ var match = isoDateExpression.exec(string);
999
+ if (match) {
1000
+ match.shift(); // kill match[0], the full match
1001
+ // parse months, days, hours, minutes, seconds, and milliseconds
1002
+ for (var i = 1; i < 7; i++) {
1003
+ // provide default values if necessary
1004
+ match[i] = +(match[i] || (i < 3 ? 1 : 0));
1005
+ // match[1] is the month. Months are 0-11 in JavaScript
1006
+ // `Date` objects, but 1-12 in ISO notation, so we
1007
+ // decrement.
1008
+ if (i == 1) {
1009
+ match[i]--;
1010
+ }
1011
+ }
1012
+
1013
+ // parse the UTC offset component
1014
+ var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
1015
+
1016
+ // compute the explicit time zone offset if specified
1017
+ var offset = 0;
1018
+ if (sign) {
1019
+ // detect invalid offsets and return early
1020
+ if (hourOffset > 23 || minuteOffset > 59) {
1021
+ return NaN;
1022
+ }
1023
+
1024
+ // express the provided time zone offset in minutes. The offset is
1025
+ // negative for time zones west of UTC; positive otherwise.
1026
+ offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
1027
+ }
1028
+
1029
+ // Date.UTC for years between 0 and 99 converts year to 1900 + year
1030
+ // The Gregorian calendar has a 400-year cycle, so
1031
+ // to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...),
1032
+ // where 12622780800000 - number of milliseconds in Gregorian calendar 400 years
1033
+ var year = +match[0];
1034
+ if (0 <= year && year <= 99) {
1035
+ match[0] = year + 400;
1036
+ return NativeDate.UTC.apply(this, match) + offset - 12622780800000;
1037
+ }
1038
+
1039
+ // compute a new UTC date value, accounting for the optional offset
1040
+ return NativeDate.UTC.apply(this, match) + offset;
1041
+ }
1042
+ return NativeDate.parse.apply(this, arguments);
1043
+ };
1044
+
1045
+ return Date;
1046
+ })(Date);
1047
+ }
1048
+
1049
+ //
1050
+ // String
1051
+ // ======
1052
+ //
1053
+
1054
+ // ES5 15.5.4.20
1055
+ // http://es5.github.com/#x15.5.4.20
1056
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
1057
+ "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
1058
+ "\u2029\uFEFF";
1059
+ if (!String.prototype.trim || ws.trim()) {
1060
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
1061
+ // http://perfectionkills.com/whitespace-deviations/
1062
+ ws = "[" + ws + "]";
1063
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
1064
+ trimEndRegexp = new RegExp(ws + ws + "*$");
1065
+ String.prototype.trim = function trim() {
1066
+ if (this === undefined || this === null) {
1067
+ throw new TypeError("can't convert "+this+" to object");
1068
+ }
1069
+ return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
1070
+ };
1071
+ }
1072
+
1073
+ //
1074
+ // Util
1075
+ // ======
1076
+ //
1077
+
1078
+ // ES5 9.4
1079
+ // http://es5.github.com/#x9.4
1080
+ // http://jsperf.com/to-integer
1081
+ var toInteger = function (n) {
1082
+ n = +n;
1083
+ if (n !== n) { // isNaN
1084
+ n = 0;
1085
+ } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
1086
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
1087
+ }
1088
+ return n;
1089
+ };
1090
+
1091
+ var prepareString = "a"[0] != "a";
1092
+ // ES5 9.9
1093
+ // http://es5.github.com/#x9.9
1094
+ var toObject = function (o) {
1095
+ if (o == null) { // this matches both null and undefined
1096
+ throw new TypeError("can't convert "+o+" to object");
1097
+ }
1098
+ // If the implementation doesn't support by-index access of
1099
+ // string characters (ex. IE < 9), split the string
1100
+ if (prepareString && typeof o == "string" && o) {
1101
+ return o.split("");
1102
+ }
1103
+ return Object(o);
1104
+ };
1105
+ });