PageSourceSearch

https://lightroom-photoshop-tutorials.com/wp-content/plugins/wplms…/js/course-module-js.min.js?ver=1.9.9.8.2

js lightroom-photoshop-tutorials.com collected 2026-10-05 05:23:36 UTC 205,559 bytes, 3,544 lines download raw bytes

1/* HTML2canvas */
2
3/*
4  html2canvas 0.5.0-alpha1 <http://html2canvas.hertzen.com>
5  Copyright (c) 2015 Niklas von Hertzen
6
7  Released under MIT License
8*/
9
10(function(window, document, exports, global, define, undefined){
11
12/*!
13 * @overview es6-promise - a tiny implementation of Promises/A+.
14 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
15 * @license   Licensed under MIT license
16 *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
17 * @version   2.0.1
18 */
19
20(function(){function r(a,b){n[l]=a;n[l+1]=b;l+=2;2===l&&A()}function s(a){return"function"===typeof a}function F(){return function(){process.nextTick(t)}}function G(){var a=0,b=new B(t),c=document.createTextNode("");b.observe(c,{characterData:!0});return function(){c.data=a=++a%2}}function H(){var a=new MessageChannel;a.port1.onmessage=t;return function(){a.port2.postMessage(0)}}function I(){return function(){setTimeout(t,1)}}function t(){for(var a=0;a<l;a+=2)(0,n[a])(n[a+1]),n[a]=void 0,n[a+1]=void 0;
21l=0}function p(){}function J(a,b,c,d){try{a.call(b,c,d)}catch(e){return e}}function K(a,b,c){r(function(a){var e=!1,f=J(c,b,function(c){e||(e=!0,b!==c?q(a,c):m(a,c))},function(b){e||(e=!0,g(a,b))});!e&&f&&(e=!0,g(a,f))},a)}function L(a,b){1===b.a?m(a,b.b):2===a.a?g(a,b.b):u(b,void 0,function(b){q(a,b)},function(b){g(a,b)})}function q(a,b){if(a===b)g(a,new TypeError("You cannot resolve a promise with itself"));else if("function"===typeof b||"object"===typeof b&&null!==b)if(b.constructor===a.constructor)L(a,
22b);else{var c;try{c=b.then}catch(d){v.error=d,c=v}c===v?g(a,v.error):void 0===c?m(a,b):s(c)?K(a,b,c):m(a,b)}else m(a,b)}function M(a){a.f&&a.f(a.b);x(a)}function m(a,b){void 0===a.a&&(a.b=b,a.a=1,0!==a.e.length&&r(x,a))}function g(a,b){void 0===a.a&&(a.a=2,a.b=b,r(M,a))}function u(a,b,c,d){var e=a.e,f=e.length;a.f=null;e[f]=b;e[f+1]=c;e[f+2]=d;0===f&&a.a&&r(x,a)}function x(a){var b=a.e,c=a.a;if(0!==b.length){for(var d,e,f=a.b,g=0;g<b.length;g+=3)d=b[g],e=b[g+c],d?C(c,d,e,f):e(f);a.e.length=0}}function D(){this.error=
23null}function C(a,b,c,d){var e=s(c),f,k,h,l;if(e){try{f=c(d)}catch(n){y.error=n,f=y}f===y?(l=!0,k=f.error,f=null):h=!0;if(b===f){g(b,new TypeError("A promises callback cannot return that same promise."));return}}else f=d,h=!0;void 0===b.a&&(e&&h?q(b,f):l?g(b,k):1===a?m(b,f):2===a&&g(b,f))}function N(a,b){try{b(function(b){q(a,b)},function(b){g(a,b)})}catch(c){g(a,c)}}function k(a,b,c,d){this.n=a;this.c=new a(p,d);this.i=c;this.o(b)?(this.m=b,this.d=this.length=b.length,this.l(),0===this.length?m(this.c,
24this.b):(this.length=this.length||0,this.k(),0===this.d&&m(this.c,this.b))):g(this.c,this.p())}function h(a){O++;this.b=this.a=void 0;this.e=[];if(p!==a){if(!s(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof h))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object c
24onstructor cannot be called as a function.");N(this,a)}}var E=Array.isArray?Array.isArray:function(a){return"[object Array]"===
25Object.prototype.toString.call(a)},l=0,w="undefined"!==typeof window?window:{},B=w.MutationObserver||w.WebKitMutationObserver,w="undefined"!==typeof Uint8ClampedArray&&"undefined"!==typeof importScripts&&"undefined"!==typeof MessageChannel,n=Array(1E3),A;A="undefined"!==typeof process&&"[object process]"==={}.toString.call(process)?F():B?G():w?H():I();var v=new D,y=new D;k.prototype.o=function(a){return E(a)};k.prototype.p=function(){return Error("Array Methods must be provided an Array")};k.prototype.l=
26function(){this.b=Array(this.length)};k.prototype.k=function(){for(var a=this.length,b=this.c,c=this.m,d=0;void 0===b.a&&d<a;d++)this.j(c[d],d)};k.prototype.j=function(a,b){var c=this.n;"object"===typeof a&&null!==a?a.constructor===c&&void 0!==a.a?(a.f=null,this.g(a.a,b,a.b)):this.q(c.resolve(a),b):(this.d--,this.b[b]=this.h(a))};k.prototype.g=function(a,b,c){var d=this.c;void 0===d.a&&(this.d--,this.i&&2===a?g(d,c):this.b[b]=this.h(c));0===this.d&&m(d,this.b)};k.prototype.h=function(a){return a};
27k.prototype.q=function(a,b){var c=this;u(a,void 0,function(a){c.g(1,b,a)},function(a){c.g(2,b,a)})};var O=0;h.all=function(a,b){return(new k(this,a,!0,b)).c};h.race=function(a,b){function c(a){q(e,a)}function d(a){g(e,a)}var e=new this(p,b);if(!E(a))return (g(e,new TypeError("You must pass an array to race.")), e);for(var f=a.length,h=0;void 0===e.a&&h<f;h++)u(this.resolve(a[h]),void 0,c,d);return e};h.resolve=function(a,b){if(a&&"object"===typeof a&&a.constructor===this)return a;var c=new this(p,b);
28q(c,a);return c};h.reject=function(a,b){var c=new this(p,b);g(c,a);return c};h.prototype={constructor:h,then:function(a,b){var c=this.a;if(1===c&&!a||2===c&&!b)return this;var d=new this.constructor(p),e=this.b;if(c){var f=arguments[c-1];r(function(){C(c,d,f,e)})}else u(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}};var z={Promise:h,polyfill:function(){var a;a="undefined"!==typeof global?global:"undefined"!==typeof window&&window.document?window:self;"Promise"in a&&"resolve"in
29a.Promise&&"reject"in a.Promise&&"all"in a.Promise&&"race"in a.Promise&&function(){var b;new a.Promise(function(a){b=a});return s(b)}()||(a.Promise=h)}};"function"===typeof define&&define.amd?define(function(){return z}):"undefined"!==typeof module&&module.exports?module.exports=z:"undefined"!==typeof this&&(this.ES6Promise=z);}).call(window);
30if (window) {
31    window.ES6Promise.polyfill();
32}
33
34
35if (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") {
36    (window || module.exports).html2canvas = function() {
37        return Promise.reject("No canvas support");
38    };
39    return;
40}
41
42/*! https://mths.be/punycode v1.3.1 by @mathias */
43;(function(root) {
44
45  /** Detect free variables */
46  var freeExports = typeof exports == 'object' && exports &&
47    !exports.nodeType && exports;
48  var freeModule = typeof module == 'object' && module &&
49    !module.nodeType && module;
50  var freeGlobal = typeof global == 'object' && global;
51  if (
52    freeGlobal.global === freeGlobal ||
53    freeGlobal.window === freeGlobal ||
54    freeGlobal.self === freeGlobal
55  ) {
56    root = freeGlobal;
57  }
58
59  /**
60   * The `punycode` object.
61   * @name punycode
62   * @type Object
63   */
64  var punycode,
65
66  /** Highest positive signed 32-bit float value */
67  maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
68
69  /** Bootstring parameters */
70  base = 36,
71  tMin = 1,
72  tMax = 26,
73  skew = 38,
74  damp = 700,
75  initialBias = 72,
76  initialN = 128, // 0x80
77  delimiter = '-', // '\x2D'
78
79  /** Regular expressions */
80  regexPunycode = /^xn--/,
81  regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
82  regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
83
84  /** Error messages */
85  errors = {
86    'overflow': 'Overflow: input needs wider integers to process',
87    'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
88    'invalid-input': 'Invalid input'
89  },
90
91  /** Convenience shortcuts */
92  baseMinusTMin = base - tMin,
93  floor = Math.floor,
94  stringFromCharCode = String.fromCharCode,
95
96  /** Temporary variable */
97  key;
98
99  /*--------------------------------------------------------------------------*/
100
101  /**
102   * A generic error utility function.
103   * @private
104   * @param {String} type The error type.
105   * @returns {Error} Throws a `RangeError` with the applicable error message.
106   */
107  function error(type) {
108    throw RangeError(errors[type]);
109  }
110
111  /**
112   * A generic `Array#map` utility function.
113   * @private
114   * @param {Array} array The array to iterate over.
115   * @param {Function} callback The function that gets called for every array
116   * item.
117   * @returns {Array} A new array of values returned by the callback function.
118   */
119  function map(array, fn) {
120    var length = array.length;
121    var result = [];
122    while (length--) {
123      result[length] = fn(array[length]);
124    }
125    return result;
126  }
127
128  /**
129   * A simple `Array#map`-like wrapper to work with domain name strings or email
130   * addresses.
131   * @private
132   * @param {String} domain The domain name or email address.
133   * @param {Function} callback The function that gets called for every
134   * character.
135   * @returns {Array} A new string of characters returned by the callback
136   * function.
137   */
138  function mapDomain(string, fn) {
139    var parts = string.split('@');
140    var result = '';
141    if (parts.length > 1) {
142      // In email addresses, only the domain name should be punycoded. Leave
143      // the local part (i.e. everything up to `@`) intact.
144      result = parts[0] + '@';
vendor: 11,811 bytes, lines 145-525
145      string = parts[1];
146    }
147    var labels = string.split(regexSeparators);
148    var encoded = map(labels, fn).join('.');
149    return result + encoded;
150  }
151
152  /**
153   * Creates an array containing the numeric code points of each Unicode
154   * character in the string. While JavaScript uses UCS-2 internally,
155   * this function will convert a pair of surrogate halves (each of which
156   * UCS-2 exposes as separate characters) into a single code point,
157   * matching UTF-16.
158   * @see `punycode.ucs2.encode`
159   * @see <https://mathiasbynens.be/notes/javascript-encoding>
160   * @memberOf punycode.ucs2
161   * @name decode
162   * @param {String} string The Unicode input string (UCS-2).
163   * @returns {Array} The new array of code points.
164   */
165  function ucs2decode(string) {
166    var output = [],
167        counter = 0,
168        length = string.length,
169        value,
170        extra;
171    while (counter < length) {
172      value = string.charCodeAt(counter++);
173      if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
174        // high surrogate, and there is a next character
175        extra = string.charCodeAt(counter++);
176        if ((extra & 0xFC00) == 0xDC00) { // low surrogate
177          output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
178        } else {
179          // unmatched surrogate; only append this code unit, in case the next
180          // code unit is the high surrogate of a surrogate pair
181          output.push(value);
182          counter--;
183        }
184      } else {
185        output.push(value);
186      }
187    }
188    return output;
189  }
190
191  /**
192   * Creates a string based on an array of numeric code points.
193   * @see `punycode.ucs2.decode`
194   * @memberOf punycode.ucs2
195   * @name encode
196   * @param {Array} codePoints The array of numeric code points.
197   * @returns {String} The new Unicode string (UCS-2).
198   */
199  function ucs2encode(array) {
200    return map(array, function(value) {
201      var output = '';
202      if (value > 0xFFFF) {
203        value -= 0x10000;
204        output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
205        value = 0xDC00 | value & 0x3FF;
206      }
207      output += stringFromCharCode(value);
208      return output;
209    }).join('');
210  }
211
212  /**
213   * Converts a basic code point into a digit/integer.
214   * @see `digitToBasic()`
215   * @private
216   * @param {Number} codePoint The basic numeric code point value.
217   * @returns {Number} The numeric value of a basic code point (for use in
218   * representing integers) in the range `0` to `base - 1`, or `base` if
219   * the code point does not represent a value.
220   */
221  function basicToDigit(codePoint) {
222    if (codePoint - 48 < 10) {
223      return codePoint - 22;
224    }
225    if (codePoint - 65 < 26) {
226      return codePoint - 65;
227    }
228    if (codePoint - 97 < 26) {
229      return codePoint - 97;
230    }
231    return base;
232  }
233
234  /**
235   * Converts a digit/integer into a basic code point.
236   * @see `basicToDigit()`
237   * @private
238   * @param {Number} digit The numeric value of a basic code point.
239   * @returns {Number} The basic code point whose value (when used for
240   * representing integers) is `digit`, which needs to be in the range
241   * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
242   * used; else, the lowercase form is used. The behavior is undefined
243   * if `flag` is non-zero and `digit` has no uppercase form.
244   */
245  function digitToBasic(digit, flag) {
246    //  0..25 map to ASCII a..z or A..Z
247    // 26..35 map to ASCII 0..9
248    return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
249  }
250
251  /**
252   * Bias adaptation function as per section 3.4 of RFC 3492.
253   * http://tools.ietf.org/html/rfc3492#section-3.4
254   * @private
255   */
256  function adapt(delta, numPoints, firstTime) {
257    var k = 0;
258    delta = firstTime ? floor(delta / damp) : delta >> 1;
259    delta += floor(delta / numPoints);
260    for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
261      delta = floor(delta / baseMinusTMin);
262    }
263    return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
264  }
265
266  /**
267   * Converts a Punycode string of ASCII-only symbols to a string of Unicode
268   * symbols.
269   * @memberOf punycode
270   * @param {String} input The Punycode string of ASCII-only symbols.
271   * @returns {String} The resulting string of Unicode symbols.
272   */
273  function decode(input) {
274    // Don't use UCS-2
275    var output = [],
276        inputLength = input.length,
277        out,
278        i = 0,
279        n = initialN,
280        bias = initialBias,
281        basic,
282        j,
283        index,
284        oldi,
285        w,
286        k,
287        digit,
288        t,
289        /** Cached calculation results */
290        baseMinusT;
291
292    // Handle the basic code points: let `basic` be the number of input code
293    // points before the last delimiter, or `0` if there is none, then copy
294    // the first basic code points to the output.
295
296    basic = input.lastIndexOf(delimiter);
297    if (basic < 0) {
298      basic = 0;
299    }
300
301    for (j = 0; j < basic; ++j) {
302      // if it's not a basic code point
303      if (input.charCodeAt(j) >= 0x80) {
304        error('not-basic');
305      }
306      output.push(input.charCodeAt(j));
307    }
308
309    // Main decoding loop: start just after the last delimiter if any basic code
310    // points were copied; start at the beginning otherwise.
311
312    for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
313
314      // `index` is the index of the next character to be consumed.
315      // Decode a generalized variable-length integer into `delta`,
316      // which gets added to `i`. The overflow checking is easier
317      // if we increase `i` as we go, then subtract off its starting
318      // value at the end to obtain `delta`.
319      for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
320
321        if (index >= inputLength) {
322          error('invalid-input');
323        }
324
325        digit = basicToDigit(input.charCodeAt(index++));
326
327        if (digit >= base || digit > floor((maxInt - i) / w)) {
328          error('overflow');
329        }
330
331        i += digit * w;
332        t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
333
334        if (digit < t) {
335          break;
336        }
337
338        baseMinusT = base - t;
339        if (w > floor(maxInt / baseMinusT)) {
340          error('overflow');
341        }
342
343        w *= baseMinusT;
344
345      }
346
347      out = output.length + 1;
348      bias = adapt(i - oldi, out, oldi == 0);
349
350      // `i` was supposed to wrap around from `out` to `0`,
351      // incrementing `n` each time, so we'll fix that now:
352      if (floor(i / out) > maxInt - n) {
353        error('overflow');
354      }
355
356      n += floor(i / out);
357      i %= out;
358
359      // Insert `n` at position `i` of the output
360      output.splice(i++, 0, n);
361
362    }
363
364    return ucs2encode(output);
365  }
366
367  /**
368   * Converts a string of Unicode symbols (e.g. a domain name label) to a
369   * Punycode string of ASCII-only symbols.
370   * @memberOf punycode
371   * @param {String} input The string of Unicode symbols.
372   * @returns {String} The resulting Punycode string of ASCII-only symbols.
373   */
374  function encode(input) {
375    var n,
376        delta,
377        handledCPCount,
378        basicLength,
379        bias,
380        j,
381        m,
382        q,
383        k,
384        t,
385        currentValue,
386        output = [],
387        /** `inputLength` will hold the number of code points in `input`. */
388        inputLength,
389        /** Cached calculation results */
390        handledCPCountPlusOne,
391        baseMinusT,
392        qMinusT;
393
394    // Convert the input in UCS-2 to Unicode
395    input = ucs2decode(input);
396
397    // Cache the length
398    inputLength = input.length;
399
400    // Initialize the state
401    n = initialN;
402    delta = 0;
403    bias = initialBias;
404
405    // Handle the basic code points
406    for (j = 0; j < inputLength; ++j) {
407      currentValue = input[j];
408      if (currentValue < 0x80) {
409        output.push(stringFromCharCode(currentValue));
410      }
411    }
412
413    handledCPCount = basicLength = output.length;
414
415    // `handledCPCount` is the number of code points that have been handled;
416    // `basicLength` is the number of basic code points.
417
418    // Finish the basic string - if it is not empty - with a delimiter
419    if (basicLength) {
420      output.push(delimiter);
421    }
422
423    // Main encoding loop:
424    while (handledCPCount < inputLength) {
425
426      // All non-basic code points < n have been handled already. Find the next
427      // larger one:
428      for (m = maxInt, j = 0; j < inputLength; ++j) {
429        currentValue = input[j];
430        if (currentValue >= n && currentValue < m) {
431          m = currentValue;
432        }
433      }
434
435      // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
436      // but guard against overflow
437      handledCPCountPlusOne = handledCPCount + 1;
438      if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
439        error('overflow');
440      }
441
442      delta += (m - n) * handledCPCountPlusOne;
443      n = m;
444
445      for (j = 0; j < inputLength; ++j) {
446        currentValue = input[j];
447
448        if (currentValue < n && ++delta > maxInt) {
449          error('overflow');
450        }
451
452        if (currentValue == n) {
453          // Represent delta as a generalized variable-length integer
454          for (q = delta, k = base; /* no condition */; k += base) {
455            t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
456            if (q < t) {
457              break;
458            }
459            qMinusT = q - t;
460            baseMinusT = base - t;
461            output.push(
462              stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
463            );
464            q = floor(qMinusT / baseMinusT);
465          }
466
467          output.push(stringFromCharCode(digitToBasic(q, 0)));
468          bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
469          delta = 0;
470          ++handledCPCount;
471        }
472      }
473
474      ++delta;
475      ++n;
476
477    }
478    return output.join('');
479  }
480
481  /**
482   * Converts a Punycode string representing a domain name or an email address
483   * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
484   * it doesn't matter if you call it on a string that has already been
485   * converted to Unicode.
486   * @memberOf punycode
487   * @param {String} input The Punycoded domain name or email address to
488   * convert to Unicode.
489   * @returns {String} The Unicode representation of the given Punycode
490   * string.
491   */
492  function toUnicode(input) {
493    return mapDomain(input, function(string) {
494      return regexPunycode.test(string)
495        ? decode(string.slice(4).toLowerCase())
496        : string;
497    });
498  }
499
500  /**
501   * Converts a Unicode string representing a domain name or an email address to
502   * Punycode. Only the non-ASCII parts of the domain name will be converted,
503   * i.e. it doesn't matter if you call it with a domain that's already in
504   * ASCII.
505   * @memberOf punycode
506   * @param {String} input The domain name or email address to convert, as a
507   * Unicode string.
508   * @returns {String} The Punycode representation of the given domain name or
509   * email address.
510   */
511  function toASCII(input) {
512    return mapDomain(input, function(string) {
513      return regexNonASCII.test(string)
514        ? 'xn--' + encode(string)
515        : string;
516    });
517  }
518
519  /*--------------------------------------------------------------------------*/
520
521  /** Define the public API */
522  punycode = {
523    /**
524     * A string representing the current Punycode.js version number.
525     * @memberOf punycode
526     * @type String
527     */
528    'version': '1.3.1',
529    /**
530     * An object of methods to convert from JavaScript's internal character
531     * representation (UCS-2) to Unicode code points, and back.
532     * @see <https://mathiasbynens.be/notes/javascript-encoding>
533     * @memberOf punycode
534     * @type Object
535     */
536    'ucs2': {
537      'decode': ucs2decode,
538      'encode': ucs2encode
539    },
540    'decode': decode,
541    'encode': encode,
542    'toASCII': toASCII,
543    'toUnicode': toUnicode
544  };
545
546  /** Expose `punycode` */
547  // Some AMD build optimizers, like r.js, check for specific condition patterns
548  // like the following:
549  if (
550    typeof define == 'function' &&
551    typeof define.amd == 'object' &&
552    define.amd
553  ) {
554    define('punycode', function() {
555      return punycode;
556    });
557  } else if (freeExports && freeModule) {
558    if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
559      freeModule.exports = punycode;
560    } else { // in Narwhal or RingoJS v0.7.0-
561      for (key in punycode) {
562        punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
563      }
564    }
565  } else { // in Rhino or a web browser
566    root.punycode = punycode;
567  }
568
569}(this));
570
571var html2canvasNodeAttribute = "data-html2canvas-node";
572var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone";
573var html2canvasCanvasCloneIndex = 0;
574var html2canvasCloneIndex = 0;
575
576window.html2canvas = function(nodeList, options) {
577    var index = html2canvasCloneIndex++;
578    options = options || {};
579    if (options.logging) {
580        window.html2canvas.logging = true;
581        window.html2canvas.start = Date.now();
582    }
583
584    options.async = typeof(options.async) === "undefined" ? true : options.async;
585    options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
586    options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
587    options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
588    options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
589    options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
590    options.strict = !!options.strict;
591
592    if (typeof(nodeList) === "string") {
593        if (typeof(options.proxy) !== "string") {
594            return Promise.reject("Proxy must be used when rendering url");
595        }
596        var width = options.width != null ? options.width : window.innerWidth;
597        var height = options.height != null ? options.height : window.innerHeight;
598        return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
599            return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
600        });
601    }
602
603    var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
604    node.setAttribute(html2canvasNodeAttribute + index, index);
605    return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
606        if (typeof(options.onrendered) === "function") {
607            log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
608            options.onrendered(canvas);
609        }
610        return canvas;
611    });
612};
613
614window.html2canvas.punycode = this.punycode;
615window.html2canvas.proxy = {};
616
617function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
618    return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
619        log("Document cloned");
620        var attributeName = html2canvasNodeAttribute + html2canvasIndex;
621        var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
622        document.querySelector(selector).removeAttribute(attributeName);
623        var clonedWindow = container.contentWindow;
624        var node = clonedWindow.document.querySelector(selector);
625        var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
626        return oncloneHandler.then(function() {
627            return renderWindow(node, container, options, windowWidth, windowHeight);
628        });
629    });
630}
631
632function renderWindow(node, container, options, windowWidth, windowHeight) {
633    var clonedWindow = container.contentWindow;
634    var support = new Support(clonedWindow.document);
635    var imageLoader = new ImageLoader(options, support);
636    var bounds = getBounds(node);
637    var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
638    var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
639    var renderer = new options.renderer(width, height, imageLoader, options, document);
640    var parser = new NodeParser(node, renderer, support, imageLoader, options);
641    return parser.ready.then(function() {
642        log("Finished rendering");
643        var canvas;
644
645        if (options.type === "view") {
646            canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
647        } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
648            canvas = renderer.canvas;
649        } else {
650            canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: clonedWindow.pageXOffset, y: clonedWindow.pageYOffset});
651        }
652
653        cleanupContainer(container, options);
654        return canvas;
655    });
656}
657
658function cleanupContainer(container, options) {
659    if (options.removeContainer) {
660        container.parentNode.removeChild(container);
661        log("Cleaned up container");
662    }
663}
664
665function crop(canvas, bounds) {
666    var croppedCanvas = document.createElement("canvas");
667    var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
668    var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
669    var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
670    var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
671    croppedCanvas.width = bounds.width;
672    croppedCanvas.height =  bounds.height;
673    log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", (x2-x1), "height:", (y2-y1));
674    log("Resulting crop with width", bounds.width, "and height", bounds.height, " with x", x1, "and y", y1);
675    croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1);
676    return croppedCanvas;
677}
678
679function documentWidth (doc) {
680    return Math.max(
681        Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
682        Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
683        Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
684    );
685}
686
687function documentHeight (doc) {
688    return Math.max(
689        Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
690        Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
691        Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
692    );
693}
694
695function smallImage() {
696    return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
697}
698
699function isIE9() {
700    return document.documentMode && document.documentMode <= 9;
701}
702
703// https://github.com/niklasvh/html2canvas/issues/503
704function cloneNodeIE9(node, javascriptEnabled) {
705    var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
706
707    var child = node.firstChild;
708    while(child) {
709        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
710            clone.appendChild(cloneNodeIE9(child, javascriptEnabled));
711        }
712        child = child.nextSibling;
713    }
714
715    return clone;
716}
717
718function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) {
719    labelCanvasElements(ownerDocument);
720    var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true);
721    var container = containerDocument.createElement("iframe");
722
723    container.className = "html2canvas-container";
724    container.style.visibility = "hidden";
725    container.style.position = "fixed";
726    container.style.left = "-10000px";
727    container.style.top = "0px";
728    container.style.border = "0";
729    container.width = width;
730    container.height = height;
731    container.scrolling = "no"; // ios won't scroll without it
732    containerDocument.body.appendChild(container);
733
734    return new Promise(function(resolve) {
735        var documentClone = container.contentWindow.document;
736
737        cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea");
738        cloneNodeValues(ownerDocument.documentElement, documentElement, "select");
739
740        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
741         if window url is about:blank, we can assign the url to current by writing onto the document
742         */
743        container.contentWindow.onload = container.onload = function() {
744            var interval = setInterval(function() {
745                if (documentClone.body.childNodes.length > 0) {
746                    cloneCanvasContents(ownerDocument, documentClone);
747                    clearInterval(interval);
748                    if (options.type === "view") {
749                        container.contentWindow.scrollTo(x, y);
750                    }
751                    resolve(container);
752                }
753            }, 50);
754        };
755
756        documentClone.open();
757        documentClone.write("<!DOCTYPE html><html></html>");
758        // Chrome scrolls the parent document for some reason after the write to the cloned window???
759        restoreOwnerScroll(ownerDocument, x, y);
760        documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
761        documentClone.close();
762    });
763}
764
765function cloneNodeValues(document, clone, nodeName) {
766    var originalNodes = document.getElementsByTagName(nodeName);
767    var clonedNodes = clone.getElementsByTagName(nodeName);
768    var count = originalNodes.length;
769    for (var i = 0; i < count; i++) {
770        clonedNodes[i].value = originalNodes[i].value;
771    }
772}
773
774function restoreOwnerScroll(ownerDocument, x, y) {
775    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
776        ownerDocument.defaultView.scrollTo(x, y);
777    }
778}
779
780function loadUrlDocument(src, proxy, document, width, height, options) {
781    return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
782        return createWindowClone(doc, document, width, height, options, 0, 0);
783    });
784}
785
786function documentFromHTML(src) {
787    return function(html) {
788        var parser = new DOMParser(), doc;
789        try {
790            doc = parser.parseFromString(html, "text/html");
791        } catch(e) {
792            log("DOMParser not supported, falling back to createHTMLDocument");
793            doc = document.implementation.createHTMLDocument("");
794            try {
795                doc.open();
796                doc.write(html);
797                doc.close();
798            } catch(ee) {
799                log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
800                doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
801            }
802        }
803
804        var b = doc.querySelector("base");
805        if (!b || !b.href.host) {
806            var base = doc.createElement("base");
807            base.href = src;
808            doc.head.insertBefore(base, doc.head.firstChild);
809        }
810
811        return doc;
812    };
813}
814
815
816function labelCanvasElements(ownerDocument) {
817    [].slice.call(ownerDocument.querySelectorAll("canvas"), 0).forEach(function(canvas) {
818        canvas.setAttribute(html2canvasCanvasCloneAttribute, "canvas-" + html2canvasCanvasCloneIndex++);
819    });
820}
821
822function cloneCanvasContents(ownerDocument, documentClone) {
823    [].slice.call(ownerDocument.querySelectorAll("[" + html2canvasCanvasCloneAttribute + "]"), 0).forEach(function(canvas) {
824        try {
825            var clonedCanvas = documentClone.querySelector('[' + html2canvasCanvasCloneAttribute + '="' + canvas.getAttribute(html2canvasCanvasCloneAttribute) + '"]');
826            if (clonedCanvas) {
827                clonedCanvas.width = canvas.width;
828                clonedCanvas.height = canvas.height;
829                clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
830            }
831        } catch(e) {
832            log("Unable to copy canvas content from", canvas, e);
833        }
834        canvas.removeAttribute(html2canvasCanvasCloneAttribute);
835    });
836}
837
838function removeScriptNodes(parent) {
839    [].slice.call(parent.childNodes, 0).filter(isElementNode).forEach(function(node) {
840        if (node.tagName === "SCRIPT") {
841            parent.removeChild(node);
842        } else {
843            removeScriptNodes(node);
844        }
845    });
846    return parent;
847}
848
849function isElementNode(node) {
850    return node.nodeType === Node.ELEMENT_NODE;
851}
852
853function absoluteUrl(url) {
854    var link = document.createElement("a");
855    link.href = url;
856    link.href = link.href;
857    return link;
858}
859
860// http://dev.w3.org/csswg/css-color/
861
862function Color(value) {
863    this.r = 0;
864    this.g = 0;
865    this.b = 0;
866    this.a = null;
867    var result = this.fromArray(value) ||
868        this.namedColor(value) ||
869        this.rgb(value) ||
870        this.rgba(value) ||
871        this.hex6(value) ||
872        this.hex3(value);
873}
874
875Color.prototype.darken = function(amount) {
876    var a = 1 - amount;
877    return  new Color([
878        Math.round(this.r * a),
879        Math.round(this.g * a),
880        Math.round(this.b * a),
881        this.a
882    ]);
883};
884
885Color.prototype.isTransparent = function() {
886    return this.a === 0;
887};
888
889Color.prototype.isBlack = function() {
890    return this.r === 0 && this.g === 0 && this.b === 0;
891};
892
893Color.prototype.fromArray = function(array) {
894    if (Array.isArray(array)) {
895        this.r = Math.min(array[0], 255);
896        this.g = Math.min(array[1], 255);
897        this.b = Math.min(array[2], 255);
898        if (array.length > 3) {
899            this.a = array[3];
900        }
901    }
902
903    return (Array.isArray(array));
904};
905
906var _hex3 = /^#([a-f0-9]{3})$/i;
907
908Color.prototype.hex3 = function(value) {
909    var match = null;
910    if ((match = value.match(_hex3)) !== null) {
911        this.r = parseInt(match[1][0] + match[1][0], 16);
912        this.g = parseInt(match[1][1] + match[1][1], 16);
913        this.b = parseInt(match[1][2] + match[1][2], 16);
914    }
915    return match !== null;
916};
917
918var _hex6 = /^#([a-f0-9]{6})$/i;
919
920Color.prototype.hex6 = function(value) {
921    var match = null;
922    if ((match = value.match(_hex6)) !== null) {
923        this.r = parseInt(match[1].substring(0, 2), 16);
924        this.g = parseInt(match[1].substring(2, 4), 16);
925        this.b = parseInt(match[1].substring(4, 6), 16);
926    }
927    return match !== null;
928};
929
930
931var _rgb = /^rgb\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3})\)$/;
932
933Color.prototype.rgb = function(value) {
934    var match = null;
935    if ((match = value.match(_rgb)) !== null) {
936        this.r = Number(match[1]);
937        this.g = Number(match[2]);
938        this.b = Number(match[3]);
939    }
940    return match !== null;
941};
942
943var _rgba = /^rgba\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *, *(\d+\.?\d*)\)$/;
944
945Color.prototype.rgba = function(value) {
946    var match = null;
947    if ((match = value.match(_rgba)) !== null) {
948        this.r = Number(match[1]);
949        this.g = Number(match[2]);
950        this.b = Number(match[3]);
951        this.a = Number(match[4]);
952    }
953    return match !== null;
954};
955
956Color.prototype.toString = function() {
957    return this.a !== null && this.a !== 1 ?
958    "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
959    "rgb(" + [this.r, this.g, this.b].join(",") + ")";
960};
961
962Color.prototype.namedColor = function(value) {
963    var color = colors[value.toLowerCase()];
964    if (color) {
965        this.r = color[0];
966        this.g = color[1];
967        this.b = color[2];
968    } else if (value.toLowerCase() === "transparent") {
969        this.r = this.g = this.b = this.a = 0;
970        return true;
971    }
972
973    return !!color;
974};
975
976Color.prototype.isColor = true;
977
978// JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(",").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))
979var colors = {
980    "aliceblue": [240, 248, 255],
981    "antiquewhite": [250, 235, 215],
982    "aqua": [0, 255, 255],
983    "aquamarine": [127, 255, 212],
984    "azure": [240, 255, 255],
985    "beige": [245, 245, 220],
986    "bisque": [255, 228, 196],
987    "black": [0, 0, 0],
988    "blanchedalmond": [255, 235, 205],
989    "blue": [0, 0, 255],
990    "blueviolet": [138, 43, 226],
991    "brown": [165, 42, 42],
992    "burlywood": [222, 184, 135],
993    "cadetblue": [95, 158, 160],
994    "chartreuse": [127, 255, 0],
995    "chocolate": [210, 105, 30],
996    "coral": [255, 127, 80],
997    "cornflowerblue": [100, 149, 237],
998    "cornsilk": [255, 248, 220],
999    "crimson": [220, 20, 60],
1000    "cyan": [0, 255, 255],
1001    "darkblue": [0, 0, 139],
1002    "darkcyan": [0, 139, 139],
1003    "darkgoldenrod": [184, 134, 11],
1004    "darkgray": [169, 169, 169],
1005    "darkgreen": [0, 100, 0],
1006    "darkgrey": [169, 169, 169],
1007    "darkkhaki": [189, 183, 107],
1008    "darkmagenta": [139, 0, 139],
1009    "darkolivegreen": [85, 107, 47],
1010    "darkorange": [255, 140, 0],
1011    "darkorchid": [153, 50, 204],
1012    "darkred": [139, 0, 0],
1013    "darksalmon": [233, 150, 122],
1014    "darkseagreen": [143, 188, 143],
1015    "darkslateblue": [72, 61, 139],
1016    "darkslategray": [47, 79, 79],
1017    "darkslategrey": [47, 79, 79],
1018    "darkturquoise": [0, 206, 209],
1019    "darkviolet": [148, 0, 211],
1020    "deeppink": [255, 20, 147],
1021    "deepskyblue": [0, 191, 255],
1022    "dimgray": [105, 105, 105],
1023    "dimgrey": [105, 105, 105],
1024    "dodgerblue": [30, 144, 255],
1025    "firebrick": [178, 34, 34],
1026    "floralwhite": [255, 250, 240],
1027    "forestgreen": [34, 139, 34],
1028    "fuchsia": [255, 0, 255],
1029    "gainsboro": [220, 220, 220],
1030    "ghostwhite": [248, 248, 255],
1031    "gold": [255, 215, 0],
1032    "goldenrod": [218, 165, 32],
1033    "gray": [128, 128, 128],
1034    "green": [0, 128, 0],
1035    "greenyellow": [173, 255, 47],
1036    "grey": [128, 128, 128],
1037    "honeydew": [240, 255, 240],
1038    "hotpink": [255, 105, 180],
1039    "indianred": [205, 92, 92],
1040    "indigo": [75, 0, 130],
1041    "ivory": [255, 255, 240],
1042    "khaki": [240, 230, 140],
1043    "lavender": [230, 230, 250],
1044    "lavenderblush": [255, 240, 245],
1045    "lawngreen": [124, 252, 0],
1046    "lemonchiffon": [255, 250, 205],
1047    "lightblue": [173, 216, 230],
1048    "lightcoral": [240, 128, 128],
1049    "lightcyan": [224, 255, 255],
1050    "lightgoldenrodyellow": [250, 250, 210],
1051    "lightgray": [211, 211, 211],
1052    "lightgreen": [144, 238, 144],
1053    "lightgrey": [211, 211, 211],
1054    "lightpink": [255, 182, 193],
1055    "lightsalmon": [255, 160, 122],
1056    "lightseagreen": [32, 178, 170],
1057    "lightskyblue": [135, 206, 250],
1058    "lightslategray": [119, 136, 153],
1059    "lightslategrey": [119, 136, 153],
1060    "lightsteelblue": [176, 196, 222],
1061    "lightyellow": [255, 255, 224],
1062    "lime": [0, 255, 0],
1063    "limegreen": [50, 205, 50],
1064    "linen": [250, 240, 230],
1065    "magenta": [255, 0, 255],
1066    "maroon": [128, 0, 0],
1067    "mediumaquamarine": [102, 205, 170],
1068    "mediumblue": [0, 0, 205],
1069    "mediumorchid": [186, 85, 211],
1070    "mediumpurple": [147, 112, 219],
1071    "mediumseagreen": [60, 179, 113],
1072    "mediumslateblue": [123, 104, 238],
1073    "mediumspringgreen": [0, 250, 154],
1074    "mediumturquoise": [72, 209, 204],
1075    "mediumvioletred": [199, 21, 133],
1076    "midnightblue": [25, 25, 112],
1077    "mintcream": [245, 255, 250],
1078    "mistyrose": [255, 228, 225],
1079    "moccasin": [255, 228, 181],
1080    "navajowhite": [255, 222, 173],
1081    "navy": [0, 0, 128],
1082    "oldlace": [253, 245, 230],
1083    "olive": [128, 128, 0],
1084    "olivedrab": [107, 142, 35],
1085    "orange": [255, 165, 0],
1086    "orangered": [255, 69, 0],
1087    "orchid": [218, 112, 214],
1088    "palegoldenrod": [238, 232, 170],
1089    "palegreen": [152, 251, 152],
1090    "paleturquoise": [175, 238, 238],
1091    "palevioletred": [219, 112, 147],
1092    "papayawhip": [255, 239, 213],
1093    "peachpuff": [255, 218, 185],
1094    "peru": [205, 133, 63],
1095    "pink": [255, 192, 203],
1096    "plum": [221, 160, 221],
1097    "powderblue": [176, 224, 230],
1098    "purple": [128, 0, 128],
1099    "rebeccapurple": [102, 51, 153],
1100    "red": [255, 0, 0],
1101    "rosybrown": [188, 143, 143],
1102    "royalblue": [65, 105, 225],
1103    "saddlebrown": [139, 69, 19],
1104    "salmon": [250, 128, 114],
1105    "sandybrown": [244, 164, 96],
1106    "seagreen": [46, 139, 87],
1107    "seashell": [255, 245, 238],
1108    "sienna": [160, 82, 45],
1109    "silver": [192, 192, 192],
1110    "skyblue": [135, 206, 235],
1111    "slateblue": [106, 90, 205],
1112    "slategray": [112, 128, 144],
1113    "slategrey": [112, 128, 144],
1114    "snow": [255, 250, 250],
1115    "springgreen": [0, 255, 127],
1116    "steelblue": [70, 130, 180],
1117    "tan": [210, 180, 140],
1118    "teal": [0, 128, 128],
1119    "thistle": [216, 191, 216],
1120    "tomato": [255, 99, 71],
1121    "turquoise": [64, 224, 208],
1122    "violet": [238, 130, 238],
1123    "wheat": [245, 222, 179],
1124    "white": [255, 255, 255],
1125    "whitesmoke": [245, 245, 245],
1126    "yellow": [255, 255, 0],
1127    "yellowgreen": [154, 205, 50]
1128};
1129
1130
1131function DummyImageContainer(src) {
1132    this.src = src;
1133    log("DummyImageContainer for", src);
1134    if (!this.promise || !this.image) {
1135        log("Initiating DummyImageContainer");
1136        DummyImageContainer.prototype.image = new Image();
1137        var image = this.image;
1138        DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
1139            image.onload = resolve;
1140            image.onerror = reject;
1141            image.src = smallImage();
1142            if (image.complete === true) {
1143                resolve(image);
1144            }
1145        });
1146    }
1147}
1148
1149function Font(family, size) {
1150    var container = document.createElement('div'),
1151        img = document.createElement('img'),
1152        span = document.createElement('span'),
1153        sampleText = 'Hidden Text',
1154        baseline,
1155        middle;
1156
1157    container.style.visibility = "hidden";
1158    container.style.fontFamily = family;
1159    container.style.fontSize = size;
1160    container.style.margin = 0;
1161    container.style.padding = 0;
1162
1163    document.body.appendChild(container);
1164
1165    img.src = smallImage();
1166    img.width = 1;
1167    img.height = 1;
1168
1169    img.style.margin = 0;
1170    img.style.padding = 0;
1171    img.style.verticalAlign = "baseline";
1172
1173    span.style.fontFamily = family;
1174    span.style.fontSize = size;
1175    span.style.margin = 0;
1176    span.style.padding = 0;
1177
1178    span.appendChild(document.createTextNode(sampleText));
1179    container.appendChild(span);
1180    container.appendChild(img);
1181    baseline = (img.offsetTop - span.offsetTop) + 1;
1182
1183    container.removeChild(span);
1184    container.appendChild(document.createTextNode(sampleText));
1185
1186    container.style.lineHeight = "normal";
1187    img.style.verticalAlign = "super";
1188
1189    middle = (img.offsetTop-container.offsetTop) + 1;
1190
1191    document.body.removeChild(container);
1192
1193    this.baseline = baseline;
1194    this.lineWidth = 1;
1195    this.middle = middle;
1196}
1197
1198function FontMetrics() {
1199    this.data = {};
1200}
1201
1202FontMetrics.prototype.getMetrics = function(family, size) {
1203    if (this.data[family + "-" + size] === undefined) {
1204        this.data[family + "-" + size] = new Font(family, size);
1205    }
1206    return this.data[family + "-" + size];
1207};
1208
1209function FrameContainer(container, sameOrigin, options) {
1210    this.image = null;
1211    this.src = container;
1212    var self = this;
1213    var bounds = getBounds(container);
1214    this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
1215        if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
1216            container.contentWindow.onload = container.onload = function() {
1217                resolve(container);
1218            };
1219        } else {
1220            resolve(container);
1221        }
1222    })).then(function(container) {
1223        return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});
1224    }).then(function(canvas) {
1225        return self.image = canvas;
1226    });
1227}
1228
1229FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
1230    var container = this.src;
1231    return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
1232};
1233
1234function GradientContainer(imageData) {
1235    this.src = imageData.value;
1236    this.colorStops = [];
1237    this.type = null;
1238    this.x0 = 0.5;
1239    this.y0 = 0.5;
1240    this.x1 = 0.5;
1241    this.y1 = 0.5;
1242    this.promise = Promise.resolve(true);
1243}
1244
1245GradientContainer.prototype.TYPES = {
1246    LINEAR: 1,
1247    RADIAL: 2
1248};
1249
1250function ImageContainer(src, cors) {
1251    this.src = src;
1252    this.image = new Image();
1253    var self = this;
1254    this.tainted = null;
1255    this.promise = new Promise(function(resolve, reject) {
1256        self.image.onload = resolve;
1257        self.image.onerror = reject;
1258        if (cors) {
1259            self.image.crossOrigin = "anonymous";
1260        }
1261        self.image.src = src;
1262        if (self.image.complete === true) {
1263            resolve(self.image);
1264        }
1265    });
1266}
1267
1268function ImageLoader(options, support) {
1269    this.link = null;
1270    this.options = options;
1271    this.support = support;
1272    this.origin = this.getOrigin(window.location.href);
1273}
1274
1275ImageLoader.prototype.findImages = function(nodes) {
1276    var images = [];
1277    nodes.reduce(function(imageNodes, container) {
1278        switch(container.node.nodeName) {
1279        case "IMG":
1280            return imageNodes.concat([{
1281                args: [container.node.src],
1282                method: "url"
1283            }]);
1284        case "svg":
1285        case "IFRAME":
1286            return imageNodes.concat([{
1287                args: [container.node],
1288                method: container.node.nodeName
1289            }]);
1290        }
1291        return imageNodes;
1292    }, []).forEach(this.addImage(images, this.loadImage), this);
1293    return images;
1294};
1295
1296ImageLoader.prototype.findBackgroundImage = function(images, container) {
1297    container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
1298    return images;
1299};
1300
1301ImageLoader.prototype.addImage = function(images, callback) {
1302    return function(newImage) {
1303        newImage.args.forEach(function(image) {
1304            if (!this.imageExists(images, image)) {
1305                images.splice(0, 0, callback.call(this, newImage));
1306                log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image);
1307            }
1308        }, this);
1309    };
1310};
1311
1312ImageLoader.prototype.hasImageBackground = function(imageData) {
1313    return imageData.method !== "none";
1314};
1315
1316ImageLoader.prototype.loadImage = function(imageData) {
1317    if (imageData.method === "url") {
1318        var src = imageData.args[0];
1319        if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {
1320            return new SVGContainer(src);
1321        } else if (src.match(/data:image\/.*;base64,/i)) {
1322            return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
1323        } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {
1324            return new ImageContainer(src, false);
1325        } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
1326            return new ImageContainer(src, true);
1327        } else if (this.options.proxy) {
1328            return new ProxyImageContainer(src, this.options.proxy);
1329        } else {
1330            return new DummyImageContainer(src);
1331        }
1332    } else if (imageData.method === "linear-gradient") {
1333        return new LinearGradientContainer(imageData);
1334    } else if (imageData.method === "gradient") {
1335        return new WebkitGradientContainer(imageData);
1336    } else if (imageData.method === "svg") {
1337        return new SVGNodeContainer(imageData.args[0], this.support.svg);
1338    } else if (imageData.method === "IFRAME") {
1339        return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
1340    } else {
1341        return new DummyImageContainer(imageData);
1342    }
1343};
1344
1345ImageLoader.prototype.isSVG = function(src) {
1346    return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src);
1347};
1348
1349ImageLoader.prototype.imageExists = function(images, src) {
1350    return images.some(function(image) {
1351        return image.src === src;
1352    });
1353};
1354
1355ImageLoader.prototype.isSameOrigin = function(url) {
1356    return (this.getOrigin(url) === this.origin);
1357};
1358
1359ImageLoader.prototype.getOrigin = function(url) {
1360    var link = this.link || (this.link = document.createElement("a"));
1361    link.href = url;
1362    link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
1363    return link.protocol + link.hostname + link.port;
1364};
1365
1366ImageLoader.prototype.getPromise = function(container) {
1367    return this.timeout(container, this.options.imageTimeout)['catch'](function() {
1368        var dummy = new DummyImageContainer(container.src);
1369        return dummy.promise.then(function(image) {
1370            container.image = image;
1371        });
1372    });
1373};
1374
1375ImageLoader.prototype.get = function(src) {
1376    var found = null;
1377    return this.images.some(function(img) {
1378        return (found = img).src === src;
1379    }) ? found : null;
1380};
1381
1382ImageLoader.prototype.fetch = function(nodes) {
1383    this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));
1384    this.images.forEach(function(image, index) {
1385        image.promise.then(function() {
1386            log("Succesfully loaded image #"+ (index+1), image);
1387        }, function(e) {
1388            log("Failed loading image #"+ (index+1), image, e);
1389        });
1390    });
1391    this.ready = Promise.all(this.images.map(this.getPromise, this));
1392    log("Finished searching images");
1393    return this;
1394};
1395
1396ImageLoader.prototype.timeout = function(container, timeout) {
1397    var timer;
1398    var promise = Promise.race([container.promise, new Promise(function(res, reject) {
1399        timer = setTimeout(function() {
1400            log("Timed out loading image", container);
1401            reject(container);
1402        }, timeout);
1403    })]).then(function(container) {
1404        clearTimeout(timer);
1405        return container;
1406    });
1407    promise['catch'](function() {
1408        clearTimeout(timer);
1409    });
1410    return promise;
1411};
1412
1413function LinearGradientContainer(imageData) {
1414    GradientContainer.apply(this, arguments);
1415    this.type = this.TYPES.LINEAR;
1416
1417    var hasDirection = imageData.args[0].match(this.stepRegExp) === null;
1418
1419    if (hasDirection) {
1420        imageData.args[0].split(" ").reverse().forEach(function(position) {
1421            switch(position) {
1422            case "left":
1423                this.x0 = 0;
1424                this.x1 = 1;
1425                break;
1426            case "top":
1427                this.y0 = 0;
1428                this.y1 = 1;
1429                break;
1430            case "right":
1431                this.x0 = 1;
1432                this.x1 = 0;
1433                break;
1434            case "bottom":
1435                this.y0 = 1;
1436                this.y1 = 0;
1437                break;
1438            case "to":
1439                var y0 = this.y0;
1440                var x0 = this.x0;
1441                this.y0 = this.y1;
1442                this.x0 = this.x1;
1443                this.x1 = x0;
1444                this.y1 = y0;
1445                break;
1446            }
1447        }, this);
1448    } else {
1449        this.y0 = 0;
1450        this.y1 = 1;
1451    }
1452
1453    this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
1454        var colorStopMatch = colorStop.match(this.stepRegExp);
1455        return {
1456            color: new Color(colorStopMatch[1]),
1457            stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
1458        };
1459    }, this);
1460
1461    if (this.colorStops[0].stop === null) {
1462        this.colorStops[0].stop = 0;
1463    }
1464
1465    if (this.colorStops[this.colorStops.length - 1].stop === null) {
1466        this.colorStops[this.colorStops.length - 1].stop = 1;
1467    }
1468
1469    this.colorStops.forEach(function(colorStop, index) {
1470        if (colorStop.stop === null) {
1471            this.colorStops.slice(index).some(function(find, count) {
1472                if (find.stop !== null) {
1473                    colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;
1474                    return true;
1475                } else {
1476                    return false;
1477                }
1478            }, this);
1479        }
1480    }, this);
1481}
1482
1483LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
1484
1485LinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/;
1486
1487function log() {
1488    if (window.html2canvas.logging && window.console && window.console.log) {
1489        Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
1490    }
1491}
1492
1493function NodeContainer(node, parent) {
1494    this.node = node;
1495    this.parent = parent;
1496    this.stack = null;
1497    this.bounds = null;
1498    this.borders = null;
1499    this.clip = [];
1500    this.backgroundClip = [];
1501    this.offsetBounds = null;
1502    this.visible = null;
1503    this.computedStyles = null;
1504    this.colors = {};
1505    this.styles = {};
1506    this.backgroundImages = null;
1507    this.transformData = null;
1508    this.transformMatrix = null;
1509    this.isPseudoElement = false;
1510    this.opacity = null;
1511}
1512
1513NodeContainer.prototype.cloneTo = function(stack) {
1514    stack.visible = this.visible;
1515    stack.borders = this.borders;
1516    stack.bounds = this.bounds;
1517    stack.clip = this.clip;
1518    stack.backgroundClip = this.backgroundClip;
1519    stack.computedStyles = this.computedStyles;
1520    stack.styles = this.styles;
1521    stack.backgroundImages = this.backgroundImages;
1522    stack.opacity = this.opacity;
1523};
1524
1525NodeContainer.prototype.getOpacity = function() {
1526    return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;
1527};
1528
1529NodeContainer.prototype.assignStack = function(stack) {
1530    this.stack = stack;
1531    stack.children.push(this);
1532};
1533
1534NodeContainer.prototype.isElementVisible = function() {
1535    return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (
1536        this.css('display') !== "none" &&
1537        this.css('visibility') !== "hidden" &&
1538        !this.node.hasAttribute("data-html2canvas-ignore") &&
1539        (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden")
1540    );
1541};
1542
1543NodeContainer.prototype.css = function(attribute) {
1544    if (!this.computedStyles) {
1545        this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after") 
1545: this.computedStyle(null);
1546    }
1547
1548    return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);
1549};
1550
1551NodeContainer.prototype.prefixedCss = function(attribute) {
1552    var prefixes = ["webkit", "moz", "ms", "o"];
1553    var value = this.css(attribute);
1554    if (value === undefined) {
1555        prefixes.some(function(prefix) {
1556            value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));
1557            return value !== undefined;
1558        }, this);
1559    }
1560    return value === undefined ? null : value;
1561};
1562
1563NodeContainer.prototype.computedStyle = function(type) {
1564    return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
1565};
1566
1567NodeContainer.prototype.cssInt = function(attribute) {
1568    var value = parseInt(this.css(attribute), 10);
1569    return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
1570};
1571
1572NodeContainer.prototype.color = function(attribute) {
1573    return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
1574};
1575
1576NodeContainer.prototype.cssFloat = function(attribute) {
1577    var value = parseFloat(this.css(attribute));
1578    return (isNaN(value)) ? 0 : value;
1579};
1580
1581NodeContainer.prototype.fontWeight = function() {
1582    var weight = this.css("fontWeight");
1583    switch(parseInt(weight, 10)){
1584    case 401:
1585        weight = "bold";
1586        break;
1587    case 400:
1588        weight = "normal";
1589        break;
1590    }
1591    return weight;
1592};
1593
1594NodeContainer.prototype.parseClip = function() {
1595    var matches = this.css('clip').match(this.CLIP);
1596    if (matches) {
1597        return {
1598            top: parseInt(matches[1], 10),
1599            right: parseInt(matches[2], 10),
1600            bottom: parseInt(matches[3], 10),
1601            left: parseInt(matches[4], 10)
1602        };
1603    }
1604    return null;
1605};
1606
1607NodeContainer.prototype.parseBackgroundImages = function() {
1608    return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage")));
1609};
1610
1611NodeContainer.prototype.cssList = function(property, index) {
1612    var value = (this.css(property) || '').split(',');
1613    value = value[index || 0] || value[0] || 'auto';
1614    value = value.trim().split(' ');
1615    if (value.length === 1) {
1616        value = [value[0], value[0]];
1617    }
1618    return value;
1619};
1620
1621NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {
1622    var size = this.cssList("backgroundSize", index);
1623    var width, height;
1624
1625    if (isPercentage(size[0])) {
1626        width = bounds.width * parseFloat(size[0]) / 100;
1627    } else if (/contain|cover/.test(size[0])) {
1628        var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;
1629        return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};
1630    } else {
1631        width = parseInt(size[0], 10);
1632    }
1633
1634    if (size[0] === 'auto' && size[1] === 'auto') {
1635        height = image.height;
1636    } else if (size[1] === 'auto') {
1637        height = width / image.width * image.height;
1638    } else if (isPercentage(size[1])) {
1639        height =  bounds.height * parseFloat(size[1]) / 100;
1640    } else {
1641        height = parseInt(size[1], 10);
1642    }
1643
1644    if (size[0] === 'auto') {
1645        width = height / image.height * image.width;
1646    }
1647
1648    return {width: width, height: height};
1649};
1650
1651NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {
1652    var position = this.cssList('backgroundPosition', index);
1653    var left, top;
1654
1655    if (isPercentage(position[0])){
1656        left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);
1657    } else {
1658        left = parseInt(position[0], 10);
1659    }
1660
1661    if (position[1] === 'auto') {
1662        top = left / image.width * image.height;
1663    } else if (isPercentage(position[1])){
1664        top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;
1665    } else {
1666        top = parseInt(position[1], 10);
1667    }
1668
1669    if (position[0] === 'auto') {
1670        left = top / image.height * image.width;
1671    }
1672
1673    return {left: left, top: top};
1674};
1675
1676NodeContainer.prototype.parseBackgroundRepeat = function(index) {
1677    return this.cssList("backgroundRepeat", index)[0];
1678};
1679
1680NodeContainer.prototype.parseTextShadows = function() {
1681    var textShadow = this.css("textShadow");
1682    var results = [];
1683
1684    if (textShadow && textShadow !== 'none') {
1685        var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);
1686        for (var i = 0; shadows && (i < shadows.length); i++) {
1687            var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
1688            results.push({
1689                color: new Color(s[0]),
1690                offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
1691                offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
1692                blur: s[3] ? s[3].replace('px', '') : 0
1693            });
1694        }
1695    }
1696    return results;
1697};
1698
1699NodeContainer.prototype.parseTransform = function() {
1700    if (!this.transformData) {
1701        if (this.hasTransform()) {
1702            var offset = this.parseBounds();
1703            var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
1704            origin[0] += offset.left;
1705            origin[1] += offset.top;
1706            this.transformData = {
1707                origin: origin,
1708                matrix: this.parseTransformMatrix()
1709            };
1710        } else {
1711            this.transformData = {
1712                origin: [0, 0],
1713                matrix: [1, 0, 0, 1, 0, 0]
1714            };
1715        }
1716    }
1717    return this.transformData;
1718};
1719
1720NodeContainer.prototype.parseTransformMatrix = function() {
1721    if (!this.transformMatrix) {
1722        var transform = this.prefixedCss("transform");
1723        var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;
1724        this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];
1725    }
1726    return this.transformMatrix;
1727};
1728
1729NodeContainer.prototype.parseBounds = function() {
1730    return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
1731};
1732
1733NodeContainer.prototype.hasTransform = function() {
1734    return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform());
1735};
1736
1737NodeContainer.prototype.getValue = function() {
1738    var value = this.node.value || "";
1739    if (this.node.tagName === "SELECT") {
1740        value = selectionValue(this.node);
1741    } else if (this.node.type === "password") {
1742        value = Array(value.length + 1).join('\u2022'); // jshint ignore:line
1743    }
1744    return value.length === 0 ? (this.node.placeholder || "") : value;
1745};
1746
1747NodeContainer.prototype.MATRIX_PROPERTY = /(matrix)\((.+)\)/;
1748NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
1749NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
1750NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;
1751
1752function selectionValue(node) {
1753    var option = node.options[node.selectedIndex || 0];
1754    return option ? (option.text || "") : "";
1755}
1756
1757function parseMatrix(match) {
1758    if (match && match[1] === "matrix") {
1759        return match[2].split(",").map(function(s) {
1760            return parseFloat(s.trim());
1761        });
1762    }
1763}
1764
1765function isPercentage(value) {
1766    return value.toString().indexOf("%") !== -1;
1767}
1768
1769function parseBackgrounds(backgroundImage) {
1770    var whitespace = ' \r\n\t',
1771        method, definition, prefix, prefix_i, block, results = [],
1772        mode = 0, numParen = 0, quote, args;
1773    var appendResult = function() {
1774        if(method) {
1775            if (definition.substr(0, 1) === '"') {
1776                definition = definition.substr(1, definition.length - 2);
1777            }
1778            if (definition) {
1779                args.push(definition);
1780            }
1781            if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
1782                prefix = method.substr(0, prefix_i);
1783                method = method.substr(prefix_i);
1784            }
1785            results.push({
1786                prefix: prefix,
1787                method: method.toLowerCase(),
1788                value: block,
1789                args: args,
1790                image: null
1791            });
1792        }
1793        args = [];
1794        method = prefix = definition = block = '';
1795    };
1796    args = [];
1797    method = prefix = definition = block = '';
1798    backgroundImage.split("").forEach(function(c) {
1799        if (mode === 0 && whitespace.indexOf(c) > -1) {
1800            return;
1801        }
1802        switch(c) {
1803        case '"':
1804            if(!quote) {
1805                quote = c;
1806            } else if(quote === c) {
1807                quote = null;
1808            }
1809            break;
1810        case '(':
1811            if(quote) {
1812                break;
1813            } else if(mode === 0) {
1814                mode = 1;
1815                block += c;
1816                return;
1817            } else {
1818                numParen++;
1819            }
1820            break;
1821        case ')':
1822            if (quote) {
1823                break;
1824            } else if(mode === 1) {
1825                if(numParen === 0) {
1826                    mode = 0;
1827                    block += c;
1828                    appendResult();
1829                    return;
1830                } else {
1831                    numParen--;
1832                }
1833            }
1834            break;
1835
1836        case ',':
1837            if (quote) {
1838                break;
1839            } else if(mode === 0) {
1840                appendResult();
1841                return;
1842            } else if (mode === 1) {
1843                if (numParen === 0 && !method.match(/^url$/i)) {
1844                    args.push(definition);
1845                    definition = '';
1846                    block += c;
1847                    return;
1848                }
1849            }
1850            break;
1851        }
1852
1853        block += c;
1854        if (mode === 0) {
1855            method += c;
1856        } else {
1857            definition += c;
1858        }
1859    });
1860
1861    appendResult();
1862    return results;
1863}
1864
1865function removePx(str) {
1866    return str.replace("px", "");
1867}
1868
1869function asFloat(str) {
1870    return parseFloat(str);
1871}
1872
1873function getBounds(node) {
1874    if (node.getBoundingClientRect) {
1875        var clientRect = node.getBoundingClientRect();
1876        var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
1877        return {
1878            top: clientRect.top,
1879            bottom: clientRect.bottom || (clientRect.top + clientRect.height),
1880            right: clientRect.left + width,
1881            left: clientRect.left,
1882            width:  width,
1883            height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
1884        };
1885    }
1886    return {};
1887}
1888
1889function offsetBounds(node) {
1890    var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};
1891
1892    return {
1893        top: node.offsetTop + parent.top,
1894        bottom: node.offsetTop + node.offsetHeight + parent.top,
1895        right: node.offsetLeft + parent.left + node.offsetWidth,
1896        left: node.offsetLeft + parent.left,
1897        width: node.offsetWidth,
1898        height: node.offsetHeight
1899    };
1900}
1901
1902function NodeParser(element, renderer, support, imageLoader, options) {
1903    log("Starting NodeParser");
1904    this.renderer = renderer;
1905    this.options = options;
1906    this.range = null;
1907    this.support = support;
1908    this.renderQueue = [];
1909    this.stack = new StackingContext(true, 1, element.ownerDocument, null);
1910    var parent = new NodeContainer(element, null);
1911    if (options.background) {
1912        renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));
1913    }
1914    if (element === element.ownerDocument.documentElement) {
1915        // http://www.w3.org/TR/css3-background/#special-backgrounds
1916        var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
1917        renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
1918    }
1919    parent.visibile = parent.isElementVisible();
1920    this.createPseudoHideStyles(element.ownerDocument);
1921    this.disableAnimations(element.ownerDocument);
1922    this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {
1923        return container.visible = container.isElementVisible();
1924    }).map(this.getPseudoElements, this));
1925    this.fontMetrics = new FontMetrics();
1926    log("Fetched nodes, total:", this.nodes.length);
1927    log("Calculate overflow clips");
1928    this.calculateOverflowClips();
1929    log("Start fetching images");
1930    this.images = imageLoader.fetch(this.nodes.filter(isElement));
1931    this.ready = this.images.ready.then(bind(function() {
1932        log("Images loaded, starting parsing");
1933        log("Creating stacking contexts");
1934        this.createStackingContexts();
1935        log("Sorting stacking contexts");
1936        this.sortStackingContexts(this.stack);
1937        this.parse(this.stack);
1938        log("Render queue created with " + this.renderQueue.length + " items");
1939        return new Promise(bind(function(resolve) {
1940            if (!options.async) {
1941                this.renderQueue.forEach(this.paint, this);
1942                resolve();
1943            } else if (typeof(options.async) === "function") {
1944                options.async.call(this, this.renderQueue, resolve);
1945            } else if (this.renderQueue.length > 0){
1946                this.renderIndex = 0;
1947                this.asyncRenderer(this.renderQueue, resolve);
1948            } else {
1949                resolve();
1950            }
1951        }, this));
1952    }, this));
1953}
1954
1955NodeParser.prototype.calculateOverflowClips = function() {
1956    this.nodes.forEach(function(container) {
1957        if (isElement(container)) {
1958            if (isPseudoElement(container)) {
1959                container.appendToDOM();
1960            }
1961            container.borders = this.parseBorders(container);
1962            var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : [];
1963            var cssClip = container.parseClip();
1964            if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) {
1965                clip.push([["rect",
1966                        container.bounds.left + cssClip.left,
1967                        container.bounds.top + cssClip.top,
1968                        cssClip.right - cssClip.left,
1969                        cssClip.bottom - cssClip.top
1970                ]]);
1971            }
1972            container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;
1973            container.backgroundClip = (container.css('overflow') !== "hidden") ? c
1973ontainer.clip.concat([container.borders.clip]) : container.clip;
1974            if (isPseudoElement(container)) {
1975                container.cleanDOM();
1976            }
1977        } else if (isTextNode(container)) {
1978            container.clip = hasParentClip(container) ? container.parent.clip : [];
1979        }
1980        if (!isPseudoElement(container)) {
1981            container.bounds = null;
1982        }
1983    }, this);
1984};
1985
1986function hasParentClip(container) {
1987    return container.parent && container.parent.clip.length;
1988}
1989
1990NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {
1991    asyncTimer = asyncTimer || Date.now();
1992    this.paint(queue[this.renderIndex++]);
1993    if (queue.length === this.renderIndex) {
1994        resolve();
1995    } else if (asyncTimer + 20 > Date.now()) {
1996        this.asyncRenderer(queue, resolve, asyncTimer);
1997    } else {
1998        setTimeout(bind(function() {
1999            this.asyncRenderer(queue, resolve);
2000        }, this), 0);
2001    }
2002};
2003
2004NodeParser.prototype.createPseudoHideStyles = function(document) {
2005    this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' +
2006        '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }');
2007};
2008
2009NodeParser.prototype.disableAnimations = function(document) {
2010    this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +
2011        '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');
2012};
2013
2014NodeParser.prototype.createStyles = function(document, styles) {
2015    var hidePseudoElements = document.createElement('style');
2016    hidePseudoElements.innerHTML = styles;
2017    document.body.appendChild(hidePseudoElements);
2018};
2019
2020NodeParser.prototype.getPseudoElements = function(container) {
2021    var nodes = [[container]];
2022    if (container.node.nodeType === Node.ELEMENT_NODE) {
2023        var before = this.getPseudoElement(container, ":before");
2024        var after = this.getPseudoElement(container, ":after");
2025
2026        if (before) {
2027            nodes.push(before);
2028        }
2029
2030        if (after) {
2031            nodes.push(after);
2032        }
2033    }
2034    return flatten(nodes);
2035};
2036
2037function toCamelCase(str) {
2038    return str.replace(/(\-[a-z])/g, function(match){
2039        return match.toUpperCase().replace('-','');
2040    });
2041}
2042
2043NodeParser.prototype.getPseudoElement = function(container, type) {
2044    var style = container.computedStyle(type);
2045    if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") {
2046        return null;
2047    }
2048
2049    var content = stripQuotes(style.content);
2050    var isImage = content.substr(0, 3) === 'url';
2051    var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
2052    var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);
2053
2054    for (var i = style.length-1; i >= 0; i--) {
2055        var property = toCamelCase(style.item(i));
2056        pseudoNode.style[property] = style[property];
2057    }
2058
2059    pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
2060
2061    if (isImage) {
2062        pseudoNode.src = parseBackgrounds(content)[0].args[0];
2063        return [pseudoContainer];
2064    } else {
2065        var text = document.createTextNode(content);
2066        pseudoNode.appendChild(text);
2067        return [pseudoContainer, new TextContainer(text, pseudoContainer)];
2068    }
2069};
2070
2071
2072NodeParser.prototype.getChildren = function(parentContainer) {
2073    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
2074        var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
2075        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
2076    }, this));
2077};
2078
2079NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
2080    var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);
2081    container.cloneTo(stack);
2082    var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;
2083    parentStack.contexts.push(stack);
2084    container.stack = stack;
2085};
2086
2087NodeParser.prototype.createStackingContexts = function() {
2088    this.nodes.forEach(function(container) {
2089        if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
2090            this.newStackingContext(container, true);
2091        } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
2092            this.newStackingContext(container, false);
2093        } else {
2094            container.assignStack(container.parent.stack);
2095        }
2096    }, this);
2097};
2098
2099NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
2100    return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
2101};
2102
2103NodeParser.prototype.isRootElement = function(container) {
2104    return container.parent === null;
2105};
2106
2107NodeParser.prototype.sortStackingContexts = function(stack) {
2108    stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
2109    stack.contexts.forEach(this.sortStackingContexts, this);
2110};
2111
2112NodeParser.prototype.parseTextBounds = function(container) {
2113    return function(text, index, textList) {
2114        if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
2115            if (this.support.rangeBounds && !container.parent.hasTransform()) {
2116                var offset = textList.slice(0, index).join("").length;
2117                return this.getRangeBounds(container.node, offset, text.length);
2118            } else if (container.node && typeof(container.node.data) === "string") {
2119                var replacementNode = container.node.splitText(text.length);
2120                var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
2121                container.node = replacementNode;
2122                return bounds;
2123            }
2124        } else if(!this.support.rangeBounds || container.parent.hasTransform()){
2125            container.node = container.node.splitText(text.length);
2126        }
2127        return {};
2128    };
2129};
2130
2131NodeParser.prototype.getWrapperBounds = function(node, transform) {
2132    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
2133    var parent = node.parentNode,
2134        backupText = node.cloneNode(true);
2135
2136    wrapper.appendChild(node.cloneNode(true));
2137    parent.replaceChild(wrapper, node);
2138    var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
2139    parent.replaceChild(backupText, wrapper);
2140    return bounds;
2141};
2142
2143NodeParser.prototype.getRangeBounds = function(node, offset, length) {
2144    var range = this.range || (this.range = node.ownerDocument.createRange());
2145    range.setStart(node, offset);
2146    range.setEnd(node, offset + length);
2147    return range.getBoundingClientRect();
2148};
2149
2150function ClearTransform() {}
2151
2152NodeParser.prototype.parse = function(stack) {
2153    // http://www.w3.org/TR/CSS21/visuren.html#z-index
2154    var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
2155    var descendantElements = stack.children.filter(isElement);
2156    var descendantNonFloats = descendantElements.filter(not(isFloating));
2157    var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.
2158    var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.
2159    var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
2160    var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
2161    var text = stack.children.filter(isTextNode).filter(hasText);
2162    var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).
2163    negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)
2164        .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {
2165            this.renderQueue.push(container);
2166            if (isStackingContext(container)) {
2167                this.parse(container);
2168                this.renderQueue.push(new ClearTransform());
2169            }
2170        }, this);
2171};
2172
2173NodeParser.prototype.paint = function(container) {
2174    try {
2175        if (container instanceof ClearTransform) {
2176            this.renderer.ctx.restore();
2177        } else if (isTextNode(container)) {
2178            if (isPseudoElement(container.parent)) {
2179                container.parent.appendToDOM();
2180            }
2181            this.paintText(container);
2182            if (isPseudoElement(container.parent)) {
2183                container.parent.cleanDOM();
2184            }
2185        } else {
2186            this.paintNode(container);
2187        }
2188    } catch(e) {
2189        log(e);
2190        if (this.options.strict) {
2191            throw e;
2192        }
2193    }
2194};
2195
2196NodeParser.prototype.paintNode = function(container) {
2197    if (isStackingContext(container)) {
2198        this.renderer.setOpacity(container.opacity);
2199        this.renderer.ctx.save();
2200        if (container.hasTransform()) {
2201            this.renderer.setTransform(container.parseTransform());
2202        }
2203    }
2204
2205    if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") {
2206        this.paintCheckbox(container);
2207    } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") {
2208        this.paintRadio(container);
2209    } else {
2210        this.paintElement(container);
2211    }
2212};
2213
2214NodeParser.prototype.paintElement = function(container) {
2215    var bounds = container.parseBounds();
2216    this.renderer.clip(container.backgroundClip, function() {
2217        this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));
2218    }, this);
2219
2220    this.renderer.clip(container.clip, function() {
2221        this.renderer.renderBorders(container.borders.borders);
2222    }, this);
2223
2224    this.renderer.clip(container.backgroundClip, function() {
2225        switch (container.node.nodeName) {
2226        case "svg":
2227        case "IFRAME":
2228            var imgContainer = this.images.get(container.node);
2229            if (imgContainer) {
2230                this.renderer.renderImage(container, bounds, container.borders, imgContainer);
2231            } else {
2232                log("Error loading <" + container.node.nodeName + ">", container.node);
2233            }
2234            break;
2235        case "IMG":
2236            var imageContainer = this.images.get(container.node.src);
2237            if (imageContainer) {
2238                this.renderer.renderImage(container, bounds, container.borders, imageContainer);
2239            } else {
2240                log("Error loading <img>", container.node.src);
2241            }
2242            break;
2243        case "CANVAS":
2244            this.renderer.renderImage(container, bounds, container.borders, {image: container.node});
2245            break;
2246        case "SELECT":
2247        case "INPUT":
2248        case "TEXTAREA":
2249            this.paintFormValue(container);
2250            break;
2251        }
2252    }, this);
2253};
2254
2255NodeParser.prototype.paintCheckbox = function(container) {
2256    var b = container.parseBounds();
2257
2258    var size = Math.min(b.width, b.height);
2259    var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};
2260    var r = [3, 3];
2261    var radius = [r, r, r, r];
2262    var borders = [1,1,1,1].map(function(w) {
2263        return {color: new Color('#A5A5A5'), width: w};
2264    });
2265
2266    var borderPoints = calculateCurvePoints(bounds, radius, borders);
2267
2268    this.renderer.clip(container.backgroundClip, function() {
2269        this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
2270        this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
2271        if (container.node.checked) {
2272            this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
2273            this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
2274        }
2275    }, this);
2276};
2277
2278NodeParser.prototype.paintRadio = function(container) {
2279    var bounds = container.parseBounds();
2280
2281    var size = Math.min(bounds.width, bounds.height) - 2;
2282
2283    this.renderer.clip(container.backgroundClip, function() {
2284        this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
2285        if (container.node.checked) {
2286            this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
2287        }
2288    }, this);
2289};
2290
2291NodeParser.prototype.paintFormValue = function(container) {
2292    var value = container.getValue();
2293    if (value.length > 0) {
2294        var document = container.node.ownerDocument;
2295        var wrapper = document.createElement('html2canvaswrapper');
2296        var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
2297            'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',
2298            'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',
2299            'boxSizing', 'whiteSpace', 'wordWrap'];
2300
2301        properties.forEach(function(property) {
2302            try {
2303                wrapper.style[property] = container.css(property);
2304            } catch(e) {
2305                // Older IE has issues with "border"
2306                log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
2307            }
2308        });
2309        var bounds = container.parseBounds();
2310        wrapper.style.position = "fixed";
2311        wrapper.style.left = bounds.left + "px";
2312        wrapper.style.top = bounds.top + "px";
2313        wrapper.textContent = value;
2314        document.body.appendChild(wrapper);
2315        this.paintText(new TextContainer(wrapper.firstChild, container));
2316        document.body.removeChild(wrapper);
2317    }
2318};
2319
2320NodeParser.prototype.paintText = function(container) {
2321    container.applyTextTransform();
2322    var characters = window.html2canvas.punycode.ucs2.decode(container.node.data);
2323    var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
2324        return window.html2canvas.punycode.ucs2.encode([character]);
2325    });
2326
2327    var weight = container.parent.fontWeight();
2328    var size = container.parent.css('fontSize');
2329    var family = container.parent.css('fontFamily');
2330    var shadows = container.parent.parseTextShadows();
2331
2332    this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
2333    if (shadows.length) {
2334        // TODO: support multiple text shadows
2335        this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
2336    } else {
2337        this.renderer.clearShadow();
2338    }
2339
2340    this.renderer.clip(container.parent.clip, function() {
2341        textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {
2342            if (bounds) {
2343                this.renderer.text(textList[index], bounds.left, bounds.bottom);
2344                this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));
2345            }
2346        }, this);
2347    }, this);
2348};
2349
2350NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {
2351    switch(container.css("textDecoration").split(" ")[0]) {
2352    case "underline":
2353        // Draws a line at the baseline of the font
2354        // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
2355        this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
2356        break;
2357    case "overline":
2358        this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
2359        break;
2360    case "line-through":
2361        // TODO try and find exact position for line-through
2362        this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
2363        break;
2364    }
2365};
2366
2367var borderColorTransforms = {
2368    inset: [
2369        ["darken", 0.60],
2370        ["darken", 0.10],
2371        ["darken", 0.10],
2372        ["darken", 0.60]
2373    ]
2374};
2375
2376NodeParser.prototype.parseBorders = function(container) {
2377    var nodeBounds = container.parseBounds();
2378    var radius = getBorderRadiusData(container);
2379    var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) {
2380        var style = container.css('border' + side + 'Style');
2381        var color = container.color('border' + side + 'Color');
2382        if (style === "inset" && color.isBlack()) {
2383            color = new Color([255, 255, 255, color.a]); // this is wrong, but
2384        }
2385        var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;
2386        return {
2387            width: container.cssInt('border' + side + 'Width'),
2388            color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,
2389            args: null
2390        };
2391    });
2392    var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);
2393
2394    return {
2395        clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),
2396        borders: calculateBorders(borders, nodeBounds, borderPoints, radius)
2397    };
2398};
2399
2400function calculateBorders(borders, nodeBounds, borderPoints, radius) {
2401    return borders.map(function(border, borderSide) {
2402        if (border.width > 0) {
2403            var bx = nodeBounds.left;
2404            var by = nodeBounds.top;
2405            var bw = nodeBounds.width;
2406            var bh = nodeBounds.height - (borders[2].width);
2407
2408            switch(borderSide) {
2409            case 0:
2410                // top border
2411                bh = borders[0].width;
2412                border.args = drawSide({
2413                        c1: [bx, by],
2414                        c2: [bx + bw, by],
2415                        c3: [bx + bw - borders[1].width, by + bh],
2416                        c4: [bx + borders[3].width, by + bh]
2417                    }, radius[0], radius[1],
2418                    borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
2419                break;
2420            case 1:
2421                // right border
2422                bx = nodeBounds.left + nodeBounds.width - (borders[1].width);
2423                bw = borders[1].width;
2424
2425                border.args = drawSide({
2426                        c1: [bx + bw, by],
2427                        c2: [bx + bw, by + bh + borders[2].width],
2428                        c3: [bx, by + bh],
2429                        c4: [bx, by + borders[0].width]
2430                    }, radius[1], radius[2],
2431                    borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
2432                break;
2433            case 2:
2434                // bottom border
2435                by = (by + nodeBounds.height) - (borders[2].width);
2436                bh = borders[2].width;
2437                border.args = drawSide({
2438                        c1: [bx + bw, by + bh],
2439                        c2: [bx, by + bh],
2440                        c3: [bx + borders[3].width, by],
2441                        c4: [bx + bw - borders[3].width, by]
2442                    }, radius[2], radius[3],
2443                    borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
2444                break;
2445            case 3:
2446                // left border
2447                bw = borders[3].width;
2448                border.args = drawSide({
2449                        c1: [bx, by + bh + borders[2].width],
2450                        c2: [bx, by],
2451                        c3: [bx + bw, by + borders[0].width],
2452                        c4: [bx + bw, by + bh]
2453                    }, radius[3], radius[0],
2454                    borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
2455                break;
2456            }
2457        }
2458        return border;
2459    });
2460}
2461
2462NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {
2463    var backgroundClip = container.css('backgroundClip'),
2464        borderArgs = [];
2465
2466    switch(backgroundClip) {
2467    case "content-box":
2468    case "padding-box":
2469        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
2470        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
2471        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
2472        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
2473        break;
2474
2475    default:
2476        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
2477        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
2478        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
2479        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
2480        break;
2481    }
2482
2483    return borderArgs;
2484};
2485
2486function getCurvePoints(x, y, r1, r2) {
2487    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
2488    var ox = (r1) * kappa, // control point offset horizontal
2489        oy = (r2) * kappa, // control point offset vertical
2490        xm = x + r1, // x-middle
2491        ym = y + r2; // y-middle
2492    return {
2493        topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),
2494        topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),
2495        bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),
2496        bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})
2497    };
2498}
2499
2500function calculateCurvePoints(bounds, borderRadius, borders) {
2501    var x = bounds.left,
2502        y = bounds.top,
2503        width = bounds.width,
2504        height = bounds.height,
2505
2506        tlh = borderRadius[0][0],
2507        tlv = borderRadius[0][1],
2508        trh = borderRadius[1][0],
2509        trv = borderRadius[1][1],
2510        brh = borderRadius[2][0],
2511        brv = borderRadius[2][1],
2512        blh = borderRadius[3][0],
2513        blv = borderRadius[3][1];
2514
2515    var topWidth = width - trh,
2516        rightHeight = height - brv,
2517        bottomWidth = width - brh,
2518        leftHeight = height - blv;
2519
2520    return {
2521        topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),
2522        topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),
2523        topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),
2524        topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),
2525        bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),
2526        bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),
2527        bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),
2528        bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)
2529    };
2530}
2531
2532function bezierCurve(start, startControl, endControl, end) {
2533    var lerp = function (a, b, t) {
2534        return {
2535            x: a.x + (b.x - a.x) * t,
2536            y: a.y + (b.y - a.y) * t
2537        };
2538    };
2539
2540    return {
2541        start: start,
2542        startControl: startControl,
2543        endControl: endControl,
2544        end: end,
2545        subdivide: function(t) {
2546            var ab = lerp(start, startControl, t),
2547                bc = lerp(startControl, endControl, t),
2548                cd = lerp(endControl, end, t),
2549                abbc = lerp(ab, bc, t),
2550                bccd = lerp(bc, cd, t),
2551                dest = lerp(abbc, bccd, t);
2552            return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
2553        },
2554        curveTo: function(borderArgs) {
2555            borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
2556        },
2557        curveToReversed: function(borderArgs) {
2558            borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
2559        }
2560    };
2561}
2562
2563function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
2564    var borderArgs = [];
2565
2566    if (radius1[0] > 0 || radius1[1] > 0) {
2567        borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
2568        outer1[1].curveTo(borderArgs);
2569    } else {
2570        borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
2571    }
2572
2573    if (radius2[0] > 0 || radius2[1] > 0) {
2574        borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
2575        outer2[0].curveTo(borderArgs);
2576        borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
2577        inner2[0].curveToReversed(borderArgs);
2578    } else {
2579        borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]);
2580        borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]);
2581    }
2582
2583    if (radius1[0] > 0 || radius1[1] > 0) {
2584        borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
2585        inner1[1].curveToReversed(borderArgs);
2586    } else {
2587        borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]);
2588    }
2589
2590    return borderArgs;
2591}
2592
2593function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
2594    if (radius1[0] > 0 || radius1[1] > 0) {
2595        borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
2596        corner1[0].curveTo(borderArgs);
2597        corner1[1].curveTo(borderArgs);
2598    } else {
2599        borderArgs.push(["line", x, y]);
2600    }
2601
2602    if (radius2[0] > 0 || radius2[1] > 0) {
2603        borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
2604    }
2605}
2606
2607function negativeZIndex(container) {
2608    return container.cssInt("zIndex") < 0;
2609}
2610
2611function positiveZIndex(container) {
2612    return container.cssInt("zIndex") > 0;
2613}
2614
2615function zIndex0(container) {
2616    return container.cssInt("zIndex") === 0;
2617}
2618
2619function inlineLevel(container) {
2620    return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
2621}
2622
2623function isStackingContext(container) {
2624    return (container instanceof StackingContext);
2625}
2626
2627function hasText(container) {
2628    return container.node.data.trim().length > 0;
2629}
2630
2631function noLetterSpacing(container) {
2632    return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing")));
2633}
2634
2635function getBorderRadiusData(container) {
2636    return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
2637        var value = container.css('border' + side + 'Radius');
2638        var arr = value.split(" ");
2639        if (arr.length <= 1) {
2640            arr[1] = arr[0];
2641        }
2642        return arr.map(asInt);
2643    });
2644}
2645
2646function renderableNode(node) {
2647    return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);
2648}
2649
2650function isPositionedForStacking(container) {
2651    var position = container.css("position");
2652    var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto";
2653    return zIndex !== "auto";
2654}
2655
2656function isPositioned(container) {
2657    return container.css("position") !== "static";
2658}
2659
2660function isFloating(container) {
2661    return container.css("float") !== "none";
2662}
2663
2664function isInlineBlock(container) {
2665    return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
2666}
2667
2668function not(callback) {
2669    var context = this;
2670    return function() {
2671        return !callback.apply(context, arguments);
2672    };
2673}
2674
2675function isElement(container) {
2676    return container.node.nodeType === Node.ELEMENT_NODE;
2677}
2678
2679function isPseudoElement(container) {
2680    return container.isPseudoElement === true;
2681}
2682
2683function isTextNode(container) {
2684    return container.node.nodeType === Node.TEXT_NODE;
2685}
2686
2687function zIndexSort(contexts) {
2688    return function(a, b) {
2689        return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length));
2690    };
2691}
2692
2693function hasOpacity(container) {
2694    return container.getOpacity() < 1;
2695}
2696
2697function bind(callback, context) {
2698    return function() {
2699        return callback.apply(context, arguments);
2700    };
2701}
2702
2703function asInt(value) {
2704    return parseInt(value, 10);
2705}
2706
2707function getWidth(border) {
2708    return border.width;
2709}
2710
2711function nonIgnoredElement(nodeContainer) {
2712    return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1);
2713}
2714
2715function flatten(arrays) {
2716    return [].concat.apply([], arrays);
2717}
2718
2719function stripQuotes(content) {
2720    var first = content.substr(0, 1);
2721    return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content;
2722}
2723
2724function getWords(characters) {
2725    var words = [], i = 0, onWordBoundary = false, word;
2726    while(characters.length) {
2727        if (isWordBoundary(characters[i]) === onWordBoundary) {
2728            word = characters.splice(0, i);
2729            if (word.length) {
2730                words.push(window.html2canvas.punycode.ucs2.encode(word));
2731            }
2732            onWordBoundary =! onWordBoundary;
2733            i = 0;
2734        } else {
2735            i++;
2736        }
2737
2738        if (i >= characters.length) {
2739            word = characters.splice(0, i);
2740            if (word.length) {
2741                words.push(window.html2canvas.punycode.ucs2.encode(word));
2742            }
2743        }
2744    }
2745    return words;
2746}
2747
2748function isWordBoundary(characterCode) {
2749    return [
2750        32, // <space>
2751        13, // \r
2752        10, // \n
2753        9, // \t
2754        45 // -
2755    ].indexOf(characterCode) !== -1;
2756}
2757
2758function hasUnicode(string) {
2759    return (/[^\u0000-\u00ff]/).test(string);
2760}
2761
2762function Proxy(src, proxyUrl, document) {
2763    if (!proxyUrl) {
2764        return Promise.reject("No proxy configured");
2765    }
2766    var callback = createCallback(supportsCORS);
2767    var url = createProxyUrl(proxyUrl, src, callback);
2768
2769    return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {
2770        return decode64(response.content);
2771    }));
2772}
2773var proxyCount = 0;
2774
2775var supportsCORS = ('withCredentials' in new XMLHttpRequest());
2776var supportsCORSImage = ('crossOrigin' in new Image());
2777
2778function ProxyURL(src, proxyUrl, document) {
2779    var callback = createCallback(supportsCORSImage);
2780    var url = createProxyUrl(proxyUrl, src, callback);
2781    return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
2782        return "data:" + response.type + ";base64," + response.content;
2783    }));
2784}
2785
2786function jsonp(document, url, callback) {
2787    return new Promise(function(resolve, reject) {
2788        var s = document.createElement("script");
2789        var cleanup = function() {
2790            delete window.html2canvas.proxy[callback];
2791            document.body.removeChild(s);
2792        };
2793        window.html2canvas.proxy[callback] = function(response) {
2794            cleanup();
2795            resolve(response);
2796        };
2797        s.src = url;
2798        s.onerror = function(e) {
2799            cleanup();
2800            reject(e);
2801        };
2802        document.body.appendChild(s);
2803    });
2804}
2805
2806function createCallback(useCORS) {
2807    return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : "";
2808}
2809
2810function createProxyUrl(proxyUrl, src, callback) {
2811    return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
2812}
2813
2814function ProxyImageContainer(src, proxy) {
2815    var script = document.createElement("script");
2816    var link = document.createElement("a");
2817    link.href = src;
2818    src = link.href;
2819    this.src = src;
2820    this.image = new Image();
2821    var self = this;
2822    this.promise = new Promise(function(resolve, reject) {
2823        self.image.crossOrigin = "Anonymous";
2824        self.image.onload = resolve;
2825        self.image.onerror = reject;
2826
2827        new ProxyURL(src, proxy, document).then(function(url) {
2828            self.image.src = url;
2829        })['catch'](reject);
2830    });
2831}
2832
2833function PseudoElementContainer(node, parent, type) {
2834    NodeContainer.call(this, node, parent);
2835    this.isPseudoElement = true;
2836    this.before = type === ":before";
2837}
2838
2839PseudoElementContainer.prototype.cloneTo = function(stack) {
2840    PseudoElementContainer.prototype.cloneTo.call(this, stack);
2841    stack.isPseudoElement = true;
2842    stack.before = this.before;
2843};
2844
2845PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);
2846
2847PseudoElementContainer.prototype.appendToDOM = function() {
2848    if (this.before) {
2849        this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
2850    } else {
2851        this.parent.node.appendChild(this.node);
2852    }
2853    this.parent.node.className += " " + this.getHideClass();
2854};
2855
2856PseudoElementContainer.prototype.cleanDOM = function() {
2857    this.node.parentNode.removeChild(this.node);
2858    this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
2859};
2860
2861PseudoElementContainer.prototype.getHideClass = function() {
2862    return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
2863};
2864
2865PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
2866PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
2867
2868function Renderer(width, height, images, options, document) {
2869    this.width = width;
2870    this.height = height;
2871    this.images = images;
2872    this.options = options;
2873    this.document = document;
2874}
2875
2876Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {
2877    var paddingLeft = container.cssInt('paddingLeft'),
2878        paddingTop = container.cssInt('paddingTop'),
2879        paddingRight = container.cssInt('paddingRight'),
2880        paddingBottom = container.cssInt('paddingBottom'),
2881        borders = borderData.borders;
2882
2883    var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);
2884    var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);
2885    this.drawImage(
2886        imageContainer,
2887        0,
2888        0,
2889        imageContainer.image.width || width,
2890        imageContainer.image.height || height,
2891        bounds.left + paddingLeft + borders[3].width,
2892        bounds.top + paddingTop + borders[0].width,
2893        width,
2894        height
2895    );
2896};
2897
2898Renderer.prototype.renderBackground = function(container, bounds, borderData) {
2899    if (bounds.height > 0 && bounds.width > 0) {
2900        this.renderBackgroundColor(container, bounds);
2901        this.renderBackgroundImage(container, bounds, borderData);
2902    }
2903};
2904
2905Renderer.prototype.renderBackgroundColor = function(container, bounds) {
2906    var color = container.color("backgroundColor");
2907    if (!color.isTransparent()) {
2908        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
2909    }
2910};
2911
2912Renderer.prototype.renderBorders = function(borders) {
2913    borders.forEach(this.renderBorder, this);
2914};
2915
2916Renderer.prototype.renderBorder = function(data) {
2917    if (!data.color.isTransparent() && data.args !== null) {
2918        this.drawShape(data.args, data.color);
2919    }
2920};
2921
2922Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {
2923    var backgroundImages = container.parseBackgroundImages();
2924    backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
2925        switch(backgroundImage.method) {
2926        case "url":
2927            var image = this.images.get(backgroundImage.args[0]);
2928            if (image) {
2929                this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
2930            } else {
2931                log("Error loading background-image", backgroundImage.args[0]);
2932            }
2933            break;
2934        case "linear-gradient":
2935        case "gradient":
2936            var gradientImage = this.images.get(backgroundImage.value);
2937            if (gradientImage) {
2938                this.renderBackgroundGradient(gradientImage, bounds, borderData);
2939            } else {
2940                log("Error loading background-image", backgroundImage.args[0]);
2941            }
2942            break;
2943        case "none":
2944            break;
2945        default:
2946            log("Unknown background-image type", backgroundImage.args[0]);
2947        }
2948    }, this);
2949};
2950
2951Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {
2952    var size = container.parseBackgroundSize(bounds, imageContainer.image, index);
2953    var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);
2954    var repeat = container.parseBackgroundRepeat(index);
2955    switch (repeat) {
2956    case "repeat-x":
2957    case "repeat no-repeat":
2958        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);
2959        break;
2960    case "repeat-y":
2961    case "no-repeat repeat":
2962        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);
2963        break;
2964    case "no-repeat":
2965        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);
2966        break;
2967    default:
2968        this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);
2969        break;
2970    }
2971};
2972
2973function StackingContext(hasOwnStacking, opacity, element, parent) {
2974    NodeContainer.call(this, element, parent);
2975    this.ownStacking = hasOwnStacking;
2976    this.contexts = [];
2977    this.children = [];
2978    this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;
2979}
2980
2981StackingContext.prototype = Object.create(NodeContainer.prototype);
2982
2983StackingContext.prototype.getParentStack = function(context) {
2984    var parentStack = (this.parent) ? this.parent.stack : null;
2985    return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
2986};
2987
2988function Support(document) {
2989    this.rangeBounds = this.testRangeBounds(document);
2990    this.cors = this.testCORS();
2991    this.svg = this.testSVG();
2992}
2993
2994Support.prototype.testRangeBounds = function(document) {
2995    var range, testElement, rangeBounds, rangeHeight, support = false;
2996
2997    if (document.createRange) {
2998        range = document.createRange();
2999        if (range.getBoundingClientRect) {
3000            testElement = document.createElement('boundtest');
3001            testElement.style.height = "123px";
3002            testElement.style.display = "block";
3003            document.body.appendChild(testElement);
3004
3005            range.selectNode(testElement);
3006            rangeBounds = range.getBoundingClientRect();
3007            rangeHeight = rangeBounds.height;
3008
3009            if (rangeHeight === 123) {
3010                support = true;
3011            }
3012            document.body.removeChild(testElement);
3013        }
3014    }
3015
3016    return support;
3017};
3018
3019Support.prototype.testCORS = function() {
3020    return typeof((new Image()).crossOrigin) !== "undefined";
3021};
3022
3023Support.prototype.testSVG = function() {
3024    var img = new Image();
3025    var canvas = document.createElement("canvas");
3026    var ctx =  canvas.getContext("2d");
3027    img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
3028
3029    try {
3030        ctx.drawImage(img, 0, 0);
3031        canvas.toDataURL();
3032    } catch(e) {
3033        return false;
3034    }
3035    return true;
3036};
3037
3038function SVGContainer(src) {
3039    this.src = src;
3040    this.image = null;
3041    var self = this;
3042
3043    this.promise = this.hasFabric().then(function() {
3044        return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
3045    }).then(function(svg) {
3046        return new Promise(function(resolve) {
3047            html2canvas.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
3048        });
3049    });
3050}
3051
3052SVGContainer.prototype.hasFabric = function() {
3053    return !html2canvas.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
3054};
3055
3056SVGContainer.prototype.inlineFormatting = function(src) {
3057    return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);
3058};
3059
3060SVGContainer.prototype.removeContentType = function(src) {
3061    return src.replace(/^data:image\/svg\+xml(;base64)?,/,'');
3062};
3063
3064SVGContainer.prototype.isInline = function(src) {
3065    return (/^data:image\/svg\+xml/i.test(src));
3066};
3067
3068SVGContainer.prototype.createCanvas = function(resolve) {
3069    var self = this;
3070    return function (objects, options) {
3071        var canvas = new html2canvas.fabric.StaticCanvas('c');
3072        self.image = canvas.lowerCanvasEl;
3073        canvas
3074            .setWidth(options.width)
3075            .setHeight(options.height)
3076            .add(html2canvas.fabric.util.groupSVGElements(objects, options))
3077            .renderAll();
3078        resolve(canvas.lowerCanvasEl);
3079    };
3080};
3081
3082SVGContainer.prototype.decode64 = function(str) {
3083    return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
3084};
3085
3086/*
3087 * base64-arraybuffer
3088 * https://github.com/niklasvh/base64-arraybuffer
3089 *
3090 * Copyright (c) 2012 Niklas von Hertzen
3091 * Licensed under the MIT license.
3092 */
3093
3094function decode64(base64) {
3095    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3096    var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
3097
3098    var output = "";
3099
3100    for (i = 0; i < len; i+=4) {
3101        encoded1 = chars.indexOf(base64[i]);
3102        encoded2 = chars.indexOf(base64[i+1]);
3103        encoded3 = chars.indexOf(base64[i+2]);
3104        encoded4 = chars.indexOf(base64[i+3]);
3105
3106        byte1 = (encoded1 << 2) | (encoded2 >> 4);
3107        byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
3108        byte3 = ((encoded3 & 3) << 6) | encoded4;
3109        if (encoded3 === 64) {
3110            output += String.fromCharCode(byte1);
3111        } else if (encoded4 === 64 || encoded4 === -1) {
3112            output += String.fromCharCode(byte1, byte2);
3113        } else{
3114            output += String.fromCharCode(byte1, byte2, byte3);
3115        }
3116    }
3117
3118    return output;
3119}
3120
3121function SVGNodeContainer(node, native) {
3122    this.src = node;
3123    this.image = null;
3124    var self = this;
3125
3126    this.promise = native ? new Promise(function(resolve, reject) {
3127        self.image = new Image();
3128        self.image.onload = resolve;
3129        self.image.onerror = reject;
3130        self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
3131        if (self.image.complete === true) {
3132            resolve(self.image);
3133        }
3134    }) : this.hasFabric().then(function() {
3135        return new Promise(function(resolve) {
3136            html2canvas.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
3137        });
3138    });
3139}
3140
3141SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
3142
3143function TextContainer(node, parent) {
3144    NodeContainer.call(this, node, parent);
3145}
3146
3147TextContainer.prototype = Object.create(NodeContainer.prototype);
3148
3149TextContainer.prototype.applyTextTransform = function() {
3150    this.node.data = this.transform(this.parent.css("textTransform"));
3151};
3152
3153TextContainer.prototype.transform = function(transform) {
3154    var text = this.node.data;
3155    switch(transform){
3156        case "lowercase":
3157            return text.toLowerCase();
3158        case "capitalize":
3159            return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
3160        case "uppercase":
3161            return text.toUpperCase();
3162        default:
3163            return text;
3164    }
3165};
3166
3167function capitalize(m, p1, p2) {
3168    if (m.length > 0) {
3169        return p1 + p2.toUpperCase();
3170    }
3171}
3172
3173function WebkitGradientContainer(imageData) {
3174    GradientContainer.apply(this, arguments);
3175    this.type = (imageData.args[0] === "linear") ? this.TYPES.LINEAR : this.TYPES.RADIAL;
3176}
3177
3178WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);
3179
3180function XHR(url) {
3181    return new Promise(function(resolve, reject) {
3182        var xhr = new XMLHttpRequest();
3183        xhr.open('GET', url);
3184
3185        xhr.onload = function() {
3186            if (xhr.status === 200) {
3187                resolve(xhr.responseText);
3188            } else {
3189                reject(new Error(xhr.statusText));
3190            }
3191        };
3192
3193        xhr.onerror = function() {
3194            reject(new Error("Network Error"));
3195        };
3196
3197        xhr.send();
3198    });
3199}
3200
3201function CanvasRenderer(width, height) {
3202    Renderer.apply(this, arguments);
3203    this.canvas = this.options.canvas || this.document.createElement("canvas");
3204    if (!this.options.canvas) {
3205        this.canvas.width = width;
3206        this.canvas.height = height;
3207    }
3208    this.ctx = this.canvas.getContext("2d");
3209    this.taintCtx = this.document.createElement("canvas").getContext("2d");
3210    this.ctx.textBaseline = "bottom";
3211    this.variables = {};
3212    log("Initialized CanvasRenderer with size", width, "x", height);
3213}
3214
3215CanvasRenderer.prototype = Object.create(Renderer.prototype);
3216
3217CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
3218    this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;
3219    return this.ctx;
3220};
3221
3222CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
3223    this.setFillStyle(color).fillRect(left, top, width, height);
3224};
3225
3226CanvasRenderer.prototype.circle = function(left, top, size, color) {
3227    this.setFillStyle(color);
3228    this.ctx.beginPath();
3229    this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);
3230    this.ctx.closePath();
3231    this.ctx.fill();
3232};
3233
3234CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {
3235    this.circle(left, top, size, color);
3236    this.ctx.strokeStyle = strokeColor.toString();
3237    this.ctx.stroke();
3238};
3239
3240CanvasRenderer.prototype.drawShape = function(shape, color) {
3241    this.shape(shape);
3242    this.setFillStyle(color).fill();
3243};
3244
3245CanvasRenderer.prototype.taints = function(imageContainer) {
3246    if (imageContainer.tainted === null) {
3247        this.taintCtx.drawImage(imageContainer.image, 0, 0);
3248        try {
3249            this.taintCtx.getImageData(0, 0, 1, 1);
3250            imageContainer.tainted = false;
3251        } catch(e) {
3252            this.taintCtx = document.createElement("canvas").getContext("2d");
3253            imageContainer.tainted = true;
3254        }
3255    }
3256
3257    return imageContainer.tainted;
3258};
3259
3260CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {
3261    if (!this.taints(imageContainer) || this.options.allowTaint) {
3262        this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);
3263    }
3264};
3265
3266CanvasRenderer.prototype.clip = function(shapes, callback, context) {
3267    this.ctx.save();
3268    shapes.filter(hasEntries).forEach(function(shape) {
3269        this.shape(shape).clip();
3270    }, this);
3271    callback.call(context);
3272    this.ctx.restore();
3273};
3274
3275CanvasRenderer.prototype.shape = function(shape) {
3276    this.ctx.beginPath();
3277    shape.forEach(function(point, index) {
3278        if (point[0] === "rect") {
3279            this.ctx.rect.apply(this.ctx, point.slice(1));
3280        } else {
3281            this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
3282        }
3283    }, this);
3284    this.ctx.closePath();
3285    return this.ctx;
3286};
3287
3288CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
3289    this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0];
3290};
3291
3292CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {
3293    this.setVariable("shadowColor", color.toString())
3294        .setVariable("shadowOffsetY", offsetX)
3295        .setVariable("shadowOffsetX", offsetY)
3296        .setVariable("shadowBlur", blur);
3297};
3298
3299CanvasRenderer.prototype.clearShadow = function() {
3300    this.setVariable("shadowColor", "rgba(0,0,0,0)");
3301};
3302
3303CanvasRenderer.prototype.setOpacity = function(opacity) {
3304    this.ctx.globalAlpha = opacity;
3305};
3306
3307CanvasRenderer.prototype.setTransform = function(transform) {
3308    this.ctx.translate(transform.origin[0], transform.origin[1]);
3309    this.ctx.transform.apply(this.ctx, transform.matrix);
3310    this.ctx.translate(-transform.origin[0], -transform.origin[1]);
3311};
3312
3313CanvasRenderer.prototype.setVariable = function(property, value) {
3314    if (this.variables[property] !== value) {
3315        this.variables[property] = this.ctx[property] = value;
3316    }
3317
3318    return this;
3319};
3320
3321CanvasRenderer.prototype.text = function(text, left, bottom) {
3322    this.ctx.fillText(text, left, bottom);
3323};
3324
3325CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {
3326    var shape = [
3327        ["line", Math.round(left), Math.round(top)],
3328        ["line", Math.round(left + width), Math.round(top)],
3329        ["line", Math.round(left + width), Math.round(height + top)],
3330        ["line", Math.round(left), Math.round(height + top)]
3331    ];
3332    this.clip([shape], function() {
3333        this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);
3334    }, this);
3335};
3336
3337CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {
3338    var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);
3339    this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat"));
3340    this.ctx.translate(offsetX, offsetY);
3341    this.ctx.fill();
3342    this.ctx.translate(-offsetX, -offsetY);
3343};
3344
3345CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
3346    if (gradientImage instanceof LinearGradientContainer) {
3347        var gradient = this.ctx.createLinearGradient(
3348            bounds.left + bounds.width * gradientImage.x0,
3349            bounds.top + bounds.height * gradientImage.y0,
3350            bounds.left +  bounds.width * gradientImage.x1,
3351            bounds.top +  bounds.height * gradientImage.y1);
3352        gradientImage.colorStops.forEach(function(colorStop) {
3353            gradient.addColorStop(colorStop.stop, colorStop.color.toString());
3354        });
3355        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);
3356    }
3357};
3358
3359CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
3360    var image = imageContainer.image;
3361    if(image.width === size.width && image.height === size.height) {
3362        return image;
3363    }
3364
3365    var ctx, canvas = document.createElement('canvas');
3366    canvas.width = size.width;
3367    canvas.height = size.height;
3368    ctx = canvas.getContext("2d");
3369    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );
3370    return canvas;
3371};
3372
3373function hasEntries(array) {
3374    return array.length > 0;
3375}
3376
3377}).call({}, typeof(window) !== "undefined" ? window : undefined, typeof(document) !== "undefined" ? document : undefined);
3378/*!
3379 * jquery.confirm
3380 *
3381 * @version 2.0.1
3382 *
3383 * @author My C-Labs
3384 * @author Matthieu Napoli <[email protected]>
3385 * @author Russel Vela
3386 *
3387 * @license MIT
3388 * @url http://myclabs.github.io/jquery.confirm/
3389 */
3390(function($){$.fn.confirm=function(options){if(typeof options==="undefined"){options={}}this.click(function(e){e.preventDefault();var newOptions=$.extend({button:$(this)},options);$.confirm(newOptions,e)});return this};$.confirm=function(options,e){var settings=$.extend({text:"Are you sure?",title:"",confirmButton:"Yes",cancelButton:"Cancel",post:false,confirm:function(o){var url=e.currentTarget.attributes["href"].value;if(options.post){var form=$('<form method="post" class="hide" action="'+url+'"></form>');$("body").append(form);form.submit()}else{window.location=url}},cancel:function(o){},button:null},options);var modalHeader="";if(settings.title!==""){modalHeader="<div class=modal-header>"+'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'+'<h4 class="modal-title">'+settings.title+"</h4>"+"</div>"}var modalHTML='<div class="confirmation-modal modal fade" tabindex="-1" role="dialog">'+'<div class="modal-dialog">'+'<div class="modal-content">'+modalHeader+'<div class="modal-body">'+settings.text+"</div>"+'<div class="modal-footer">'+'<button class="confirm btn btn-primary" type="button" data-dismiss="modal">'+settings.confirmButton+"</button>"+'<button class="cancel btn btn-default" type="button" data-dismiss="modal">'+settings.cancelButton+"</div>"+"</div>"+"</div>"+"</div>"+"</div>";var modal=$(modalHTML);modal.on("shown",function(){modal.find(".btn-primary:first").focus()});modal.on("hidden",function(){modal.remove()});modal.find(".confirm").click(function(){settings.confirm(settings.button)});modal.find(".cancel").click(function(){settings.cancel(settings.button)});$("body").append(modal);modal.modal("show")}})(jQuery);
3391
3392/*
3393
3394jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser, jQuery
3395Copyright (c) 2012 2012 Willow Systems Corporation, willow-systems.com
3396 jsPDF 0.9.0rc1 ( 2013-04-07T16:52 commit ID d95d8f69915bb999f6704e8021108e2e755bd868 )
3397Copyright (c) 2010-2012 James Hall, [email protected], https://github.com/MrRio/jsPDF
3398Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
3399MIT license.
3400
3401            -----------------------------------------------------------------------------------------------
3402            JavaScript PubSub library
3403            2012 (c) [email protected]
3404            based on Peter Higgins ([email protected])
3405            Loosely based on Dojo publish/subscribe API, limited in scope. Rewritten blindly.
3406            Original is (c) Dojo Foundation 2004-2010. Released under either AFL or new BSD, see:
3407            http://dojofoundation.org/license for more information.
3408            -----------------------------------------------------------------------------------------------
3409 
3410jsPDF addImage plugin (JPEG only at this time)
3411Copyright (c) 2012 https://github.com/siefkenj/
3412
3413jsPDF Silly SVG plugin
3414Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
3415 
3416jsPDF split_text_to_size plugin
3417Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
3418MIT license.
3419 
3420jsPDF standard_fonts_metrics plugin
3421Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
3422MIT license.
3423*/
3424var jsPDF=function(){function f(g,d,e,h){g="undefined"===typeof g?"p":g.toString().toLowerCase();"undefined"===typeof d&&(d="mm");"undefined"===typeof e&&(e="a4");"undefined"===typeof h&&"undefined"===typeof zpipe&&(h=!1);var a=e.toString().toLowerCase(),p=[],j=0,m=h;h={a3:[841.89,1190.55],a4:[595.28,841.89],a5:[420.94,595.28],letter:[612,792],legal:[612,1008]};var u="0 g",c=0,q=[],C=2,F=!1,H=[],n={},x={},z=16,A,y,s,r,I={title:"",subject:"",author:"",keywords:"",creator:""},w=0,aa=0,D={},G=new k(D),
3425B,v=function(c){return c.toFixed(2)},V=function(c){var e=c.toFixed(0);return 10>c?"0"+e:e},l=function(e){F?q[c].push(e):(p.push(e),j+=e.length+1)},N=function(){C++;H[C]=j;l(C+" 0 obj");return C},Q=function(c){l("stream");l(c);l("endstream")},J,ca,R,t=function(c,e){var d;d=c;var j=e,a,h,b,p,g,m;void 0===j&&(j={});a=j.sourceEncoding?a:"Unicode";b=j.outputEncoding;if((j.autoencode||b)&&n[A].metadata&&n[A].metadata[a]&&n[A].metadata[a].encoding)if(a=n[A].metadata[a].encoding,!b&&n[A].encoding&&(b=n[A].encoding),
3426!b&&a.codePages&&(b=a.codePages[0]),"string"===typeof b&&(b=a[b]),b){g=!1;p=[];a=0;for(h=d.length;a<h;a++)(m=b[d.charCodeAt(a)])?p.push(String.fromCharCode(m)):p.push(d[a]),p[a].charCodeAt(0)>>8&&(g=!0);d=p.join("")}for(a=d.length;void 0===g&&0!==a;)d.charCodeAt(a-1)>>8&&(g=!0),a--;if(g){p=j.noBOM?[]:[254,255];a=0;for(h=d.length;a<h;a++){m=d.charCodeAt(a);j=m>>8;if(j>>8)throw Error("Character at position "+a.toString(10)+" of string '"+d+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");p.push(j);
3427p.push(m-(j<<8))}d=String.fromCharCode.apply(void 0,p)}return d.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},W=function(){c++;F=!0;q[c]=[];l(v(0.200025*r)+" w");l("0 G");0!==w&&l(w.toString(10)+" J");0!==aa&&l(aa.toString(10)+" j");G.publish("addPage",{pageNumber:c})},E=function(c,a){var d;void 0===c&&(c=n[A].fontName);void 0===a&&(a=n[A].fontStyle);try{d=x[c][a]}catch(e){d=void 0}if(!d)throw Error("Unable to look up font label for font '"+c+"', '"+a+"'. Refer to getFontList() for available fonts.");
3428return d},K=function(){F=!1;p=[];H=[];l("%PDF-1.3");J=s*r;ca=y*r;var a,d,e,b,h;for(a=1;a<=c;a++){N();l("<</Type /Page");l("/Parent 1 0 R");l("/Resources 2 0 R");l("/Contents "+(C+1)+" 0 R>>");l("endobj");d=q[a].join("\n");N();if(m){e=[];for(b=0;b<d.length;++b)e[b]=d.charCodeAt(b);h=adler32cs.from(d);d=new Deflater(6);d.append(new Uint8Array(e));d=d.flush();e=[new Uint8Array([120,156]),new Uint8Array(d),new Uint8Array([h&255,h>>8&255,h>>16&255,h>>24&255])];d="";for(b in e)e.hasOwnProperty(b)&&(d+=
3429String.fromCharCode.apply(null,e[b]));l("<</Length "+d.length+" /Filter [/FlateDecode]>>")}else l("<</Length "+d.length+">>");Q(d);l("endobj")}H[1]=j;l("1 0 obj");l("<</Type /Pages");R="/Kids [";for(b=0;b<c;b++)R+=3+2*b+" 0 R ";l(R+"]");l("/Count "+c);l("/MediaBox [0 0 "+v(J)+" "+v(ca)+"]");l(">>");l("endobj");for(var g in n)n.hasOwnProperty(g)&&(a=n[g],a.objectNumber=N(),l("<</BaseFont/"+a.PostScriptName+"/Type/Font"),"string"===typeof a.encoding&&l("/Encoding/"+a.encoding),l("/Subtype/Type1>>"),
3430l("endobj"));G.publish("putResources");H[2]=j;l("2 0 obj");l("<<");l("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");l("/Font <<");for(var f in n)n.hasOwnProperty(f)&&l("/"+f+" "+n[f].objectNumber+" 0 R");l(">>");l("/XObject <<");G.publish("putXobjectDict");l(">>");l(">>");l("endobj");G.publish("postPutResources");N();l("<<");
3430l("/Producer (jsPDF 20120619)");I.title&&l("/Title ("+t(I.title)+")");I.subject&&l("/Subject ("+t(I.subject)+")");I.author&&l("/Author ("+t(I.author)+")");I.keywords&&l("/Keywords ("+
3431t(I.keywords)+")");I.creator&&l("/Creator ("+t(I.creator)+")");g=new Date;l("/CreationDate (D:"+[g.getFullYear(),V(g.getMonth()+1),V(g.getDate()),V(g.getHours()),V(g.getMinutes()),V(g.getSeconds())].join("")+")");l(">>");l("endobj");N();l("<<");l("/Type /Catalog");l("/Pages 1 0 R");l("/OpenAction [3 0 R /FitH null]");l("/PageLayout /OneColumn");G.publish("putCatalog");l(">>");l("endobj");g=j;l("xref");l("0 "+(C+1));l("0000000000 65535 f ");for(f=1;f<=C;f++)a=H[f].toFixed(0),a=10>a.length?Array(11-
3432a.length).join("0")+a:a,l(a+" 00000 n ");l("trailer");l("<<");l("/Size "+(C+1));l("/Root "+C+" 0 R");l("/Info "+(C-1)+" 0 R");l(">>");l("startxref");l(g);l("%%EOF");F=!0;return p.join("\n")},Y=function(c){var a="S";if("F"===c)a="f";else if("FD"===c||"DF"===c)a="B";return a},Z=function(c,a){var d,e,b,j;switch(c){case void 0:return K();case "save":if(navigator.getUserMedia&&(void 0===window.URL||void 0===window.URL.createObjectURL))return D.output("dataurlnewwindow");d=K();e=d.length;b=new Uint8Array(new ArrayBuffer(e));
3433for(j=0;j<e;j++)b[j]=d.charCodeAt(j);d=new Blob([b],{type:"application/pdf"});saveAs(d,a);break;case "datauristring":case "dataurlstring":return"data:application/pdf;base64,"+btoa(K());case "datauri":case "dataurl":document.location.href="data:application/pdf;base64,"+btoa(K());break;case "dataurlnewwindow":window.open("data:application/pdf;base64,"+btoa(K()));break;default:throw Error('Output type "'+c+'" is not supported.');}};if("pt"===d)r=1;else if("mm"===d)r=72/25.4;else if("cm"===d)r=72/2.54;
3434else if("in"===d)r=72;else throw"Invalid unit: "+d;if(h.hasOwnProperty(a))y=h[a][1]/r,s=h[a][0]/r;else try{y=e[1],s=e[0]}catch(M){throw"Invalid format: "+e;}if("p"===g||"portrait"===g)g="p",s>y&&(g=s,s=y,y=g);else if("l"===g||"landscape"===g)g="l",y>s&&(g=s,s=y,y=g);else throw"Invalid orientation: "+g;D.internal={pdfEscape:t,getStyle:Y,getFont:function(){return n[E.apply(D,arguments)]},getFontSize:function(){return z},btoa:btoa,write:function(c,a,d,e){l(1===arguments.length?c:Array.prototype.join.call(arguments,
3435" "))},getCoordinateString:function(c){return v(c*r)},getVerticalCoordinateString:function(c){return v((y-c)*r)},collections:{},newObject:N,putStream:Q,events:G,scaleFactor:r,pageSize:{width:s,height:y},output:function(c,a){return Z(c,a)}};D.addPage=function(){W();return this};D.text=function(c,a,d,e){var b,j;"number"===typeof c&&(b=c,j=a,c=d,a=b,d=j);"string"===typeof c&&c.match(/[\n\r]/)&&(c=c.split(/\r\n|\r|\n/g));"undefined"===typeof e?e={noBOM:!0,autoencode:!0}:(void 0===e.noBOM&&(e.noBOM=!0),
3436void 0===e.autoencode&&(e.autoencode=!0));if("string"===typeof c)e=t(c,e);else if(c instanceof Array){c=c.concat();for(b=c.length-1;-1!==b;b--)c[b]=t(c[b],e);e=c.join(") Tj\nT* (")}else throw Error('Type of text must be string or Array. "'+c+'" is not recognized.');l("BT\n/"+A+" "+z+" Tf\n"+z+" TL\n"+u+"\n"+v(a*r)+" "+v((y-d)*r)+" Td\n("+e+") Tj\nET");return this};D.line=function(c,a,d,e){l(v(c*r)+" "+v((y-a)*r)+" m "+v(d*r)+" "+v((y-e)*r)+" l S");return this};D.lines=function(c,a,d,e,b){var j,g,
3437h,p,m,f,q,u;"number"===typeof c&&(j=c,g=a,c=d,a=j,d=g);b=Y(b);e=void 0===e?[1,1]:e;l((a*r).toFixed(3)+" "+((y-d)*r).toFixed(3)+" m ");j=e[0];e=e[1];g=c.length;u=d;for(d=0;d<g;d++)h=c[d],2===h.length?(a=h[0]*j+a,u=h[1]*e+u,l((a*r).toFixed(3)+" "+((y-u)*r).toFixed(3)+" l")):(p=h[0]*j+a,m=h[1]*e+u,f=h[2]*j+a,q=h[3]*e+u,a=h[4]*j+a,u=h[5]*e+u,l((p*r).toFixed(3)+" "+((y-m)*r).toFixed(3)+" "+(f*r).toFixed(3)+" "+((y-q)*r).toFixed(3)+" "+(a*r).toFixed(3)+" "+((y-u)*r).toFixed(3)+" c"));l(b);return this};
3438D.rect=function(c,a,d,e,b){b=Y(b);l([v(c*r),v((y-a)*r),v(d*r),v(-e*r),"re",b].join(" "));return this};D.triangle=function(c,a,d,e,b,j,h){this.lines([[d-c,e-a],[b-d,j-e],[c-b,a-j]],c,a,[1,1],h);return this};D.roundedRect=function(c,a,d,e,b,j,h){var g=4/3*(Math.SQRT2-1);this.lines([[d-2*b,0],[b*g,0,b,j-j*g,b,j],[0,e-2*j],[0,j*g,-(b*g),j,-b,j],[-d+2*b,0],[-(b*g),0,-b,-(j*g),-b,-j],[0,-e+2*j],[0,-(j*g),b*g,-j,b,-j]],c+b,a,[1,1],h);return this};D.ellipse=function(c,a,d,e,b){b=Y(b);var j=4/3*(Math.SQRT2-
34391)*d,g=4/3*(Math.SQRT2-1)*e;l([v((c+d)*r),v((y-a)*r),"m",v((c+d)*r),v((y-(a-g))*r),v((c+j)*r),v((y-(a-e))*r),v(c*r),v((y-(a-e))*r),"c"].join(" "));l([v((c-j)*r),v((y-(a-e))*r),v((c-d)*r),v((y-(a-g))*r),v((c-d)*r),v((y-a)*r),"c"].join(" "));l([v((c-d)*r),v((y-(a+g))*r),v((c-j)*r),v((y-(a+e))*r),v(c*r),v((y-(a+e))*r),"c"].join(" "));l([v((c+j)*r),v((y-(a+e))*r),v((c+d)*r),v((y-(a+g))*r),v((c+d)*r),v((y-a)*r),"c",b].join(" "));return this};D.circle=function(c,a,d,e){return this.ellipse(c,a,d,d,e)};D.setProperties=
3440function(c){for(var a in I)I.hasOwnProperty(a)&&c[a]&&(I[a]=c[a]);return this};D.setFontSize=function(c){z=c;return this};D.setFont=function(c,a){A=E(c,a);return this};D.setFontStyle=D.setFontType=function(c){A=E(void 0,c);return this};D.getFontList=function(){var c={},a,d,e;for(a in x)if(x.hasOwnProperty(a))for(d in c[a]=e=[],x[a])x[a].hasOwnProperty(d)&&e.push(d);return c};D.setLineWidth=function(c){l((c*r).toFixed(2)+" w");return this};D.setDrawColor=function(c,a,d,e){c=void 0===a||void 0===e&&
3441c===a===d?"string"===typeof c?c+" G":v(c/255)+" G":void 0===e?"string"===typeof c?[c,a,d,"RG"].join(" "):[v(c/255),v(a/255),v(d/255),"RG"].join(" "):"str
3441ing"===typeof c?[c,a,d,e,"K"].join(" "):[v(c),v(a),v(d),v(e),"K"].join(" ");l(c);return this};D.setFillColor=function(c,a,d,e){c=void 0===a||void 0===e&&c===a===d?"string"===typeof c?c+" g":v(c/255)+" g":void 0===e?"string"===typeof c?[c,a,d,"rg"].join(" "):[v(c/255),v(a/255),v(d/255),"rg"].join(" "):"string"===typeof c?[c,a,d,e,"k"].join(" "):[v(c),
3442v(a),v(d),v(e),"k"].join(" ");l(c);return this};D.setTextColor=function(c,a,d){u=0===c&&0===a&&0===d||"undefined"===typeof a?(c/255).toFixed(3)+" g":[(c/255).toFixed(3),(a/255).toFixed(3),(d/255).toFixed(3),"rg"].join(" ");return this};D.CapJoinStyles={"0":0,butt:0,but:0,bevel:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,milter:2};D.setLineCap=function(c){var a=this.CapJoinStyles[c];if(void 0===a)throw Error("Line cap style of '"+c+"' is not recognized. See or extend .CapJoinStyles property for valid styles");
3443w=a;l(a.toString(10)+" J");return this};D.setLineJoin=function(c){var a=this.CapJoinStyles[c];if(void 0===a)throw Error("Line join style of '"+c+"' is not recognized. See or extend .CapJoinStyles property for valid styles");aa=a;l(a.toString(10)+" j");return this};D.output=Z;D.save=function(c){D.output("save",c)};for(B in f.API)if(f.API.hasOwnProperty(B))if("events"===B&&f.API.events.length){g=G;d=f.API.events;h=a=e=void 0;for(h=d.length-1;-1!==h;h--)e=d[h][0],a=d[h][1],g.subscribe.apply(g,[e].concat("function"===
3444typeof a?[a]:a))}else D[B]=f.API[B];B=[["Helvetica","helvetica","normal"],["Helvetica-Bold","helvetica","bold"],["Helvetica-Oblique","helvetica","italic"],["Helvetica-BoldOblique","helvetica","bolditalic"],["Courier","courier","normal"],["Courier-Bold","courier","bold"],["Courier-Oblique","courier","italic"],["Courier-BoldOblique","courier","bolditalic"],["Times-Roman","times","normal"],["Times-Bold","times","bold"],["Times-Italic","times","italic"],["Times-BoldItalic","times","bolditalic"]];g=0;
3445for(d=B.length;g<d;g++){h=B[g][0];var T=B[g][1],a=B[g][2];e="F"+(b(n)+1).toString(10);h=n[e]={id:e,PostScriptName:h,fontName:T,fontStyle:a,encoding:"StandardEncoding",metadata:{}};var ha=e;void 0===x[T]&&(x[T]={});x[T][a]=ha;G.publish("addFont",h);a=e;e=B[g][0].split("-");h=e[0];e=e[1]||"";void 0===x[h]&&(x[h]={});x[h][e]=a}G.publish("addFonts",{fonts:n,dictionary:x});A="F1";W();G.publish("initialized");return D}"undefined"===typeof btoa&&(window.btoa=function(b){var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split(""),
3446e,h,a,p,j=0,m=0,f="",f=[];do e=b.charCodeAt(j++),h=b.charCodeAt(j++),a=b.charCodeAt(j++),p=e<<16|h<<8|a,e=p>>18&63,h=p>>12&63,a=p>>6&63,p&=63,f[m++]=d[e]+d[h]+d[a]+d[p];while(j<b.length);f=f.join("");b=b.length%3;return(b?f.slice(0,b-3):f)+"===".slice(b||3)});"undefined"===typeof atob&&(window.atob=function(b){var d,e,h,a,p,j=0,m=0;a="";var f=[];if(!b)return b;b+="";do d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),
3447a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(b.charAt(j++)),h=d<<18|e<<12|a<<6|p,d=h>>16&255,e=h>>8&255,h&=255,64===a?f[m++]=String.fromCharCode(d):64===p?f[m++]=String.fromCharCode(d,e):f[m++]=String.fromCharCode(d,e,h);while(j<b.length);return a=f.join("")});var b="function"===typeof Object.keys?function(b){return Object.keys(b).length}:function(b){var d=0,e;for(e in b)b.hasOwnProperty(e)&&
3448d++;return d},k=function(b){this.topics={};this.context=b;this.publish=function(d,b){if(this.topics[d]){var h=this.topics[d],a=[],p,j,g,f,c=function(){};b=Array.prototype.slice.call(arguments,1);j=0;for(g=h.length;j<g;j++)f=h[j],p=f[0],f[1]&&(f[0]=c,a.push(j)),p.apply(this.context,b);j=0;for(g=a.length;j<g;j++)h.splice(a[j],1)}};this.subscribe=function(d,b,h){this.topics[d]?this.topics[d].push([b,h]):this.topics[d]=[[b,h]];return{topic:d,callback:b}};this.unsubscribe=function(d){if(this.topics[d.topic]){var b=
3449this.topics[d.topic],h,a;h=0;for(a=b.length;h<a;h++)b[h][0]===d.callback&&b.splice(h,1)}}};f.API={events:[]};return f}();
3450(function(f){var b=function(){var b=this.internal.collections.addImage_images,d;for(d in b){var e=b[d],h=this.internal.newObject(),a=this.internal.write,p=this.internal.putStream;e.n=h;a("<</Type /XObject");a("/Subtype /Image");a("/Width "+e.w);a("/Height "+e.h);"Indexed"===e.cs?a("/ColorSpace [/Indexed /DeviceRGB "+(e.pal.length/3-1)+" "+(h+1)+" 0 R]"):(a("/ColorSpace /"+e.cs),"DeviceCMYK"===e.cs&&a("/Decode [1 0 1 0 1 0 1 0]"));a("/BitsPerComponent "+e.bpc);"f"in e&&a("/Filter /"+e.f);"dp"in e&&
3451a("/DecodeParms <<"+e.dp+">>");if("trns"in e&&e.trns.constructor==Array)for(var j="",f=0;f<e.trns.length;f++)j+=e[j][f]+" "+e.trns[f]+" ",a("/Mask ["+j+"]");"smask"in e&&a("/SMask "+(h+1)+" 0 R");a("/Length "+e.data.length+">>");p(e.data);a("endobj")}},k=function(){var b=this.internal.collections.addImage_images,d=this.internal.write,e,h;for(h in b)e=b[h],d("/I"+e.i,e.n,"0","R")};f.addImage=function(g,d,e,h,a,p){if("object"===typeof g&&1===g.nodeType){d=document.createElement("canvas");d.width=g.clientWidth;
3452d.height=g.clientHeight;var j=d.getContext("2d");if(!j)throw"addImage requires canvas to be supported by browser.";j.drawImage(g,0,0,d.width,d.height);g=d.toDataURL("image/jpeg");d="JPEG"}if("JPEG"!==d.toUpperCase())throw Error("addImage currently only supports format 'JPEG', not '"+d+"'");var f;d=this.internal.collections.addImage_images;var j=this.internal.getCoordinateString,u=this.internal.getVerticalCoordinateString;"data:image/jpeg;base64,"===g.substring(0,23)&&(g=atob(g.replace("data:image/jpeg;base64,",
3453"")));if(d)if(Object.keys)f=Object.keys(d).length;else{var c=d,q=0;for(f in c)c.hasOwnProperty(f)&&q++;f=q}else f=0,this.internal.collections.addImage_images=d={},this.internal.events.subscribe("putResources",b),this.internal.events.subscribe("putXobjectDict",k);a:{var c=g,C;if(255===!c.charCodeAt(0)||216===!c.charCodeAt(1)||255===!c.charCodeAt(2)||224===!c.charCodeAt(3)||74===!c.charCodeAt(6)||70===!c.charCodeAt(7)||73===!c.charCodeAt(8)||70===!c.charCodeAt(9)||0===!c.charCodeAt(10))throw Error("getJpegSize requires a binary jpeg file");
3454C=256*c.charCodeAt(4)+c.charCodeAt(5);for(var q=4,F=c.length;q<F;){q+=C;if(255!==c.charCodeAt(q))throw Error("getJpegSize could not find the size of the image");if(192===c.charCodeAt(q+1)){C=256*c.charCodeAt(q+5)+c.charCodeAt(q+6);c=256*c.charCodeAt(q+7)+c.charCodeAt(q+8);c=[c,C];break a}else q+=2,C=256*c.charCodeAt(q)+c.charCodeAt(q+1)}c=void 0}g={w:c[0],h:c[1],cs:"DeviceRGB",bpc:8,f:"DCTDecode",i:f,data:g};d[f]=g;!a&&!p&&(p=a=-96);0>a&&(a=-72*g.w/a/this.internal.scaleFactor);0>p&&(p=-72*g.h/p/this.internal.scaleFactor);
34550===a&&(a=p*g.w/g.h);0===p&&(p=a*g.h/g.w);this.internal.write("q",j(a),"0 0",j(p),j(e),u(h+p),"cm /I"+g.i,"Do Q");return this}})(jsPDF.API);
3456(function(f){function b(a,b,d,e){this.pdf=a;this.x=b;this.y=d;this.settings=e;this.init();return this}function k(b){var d=a[b];if(d)return d;d={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[b];if(void 0!==d||(d=parseFloat(b)))return a[b]=d/16;d=b.match(/([\d\.]+)(px)/);return 3===d.length?a[b]=parseFloat(d[1])/16:a[b]=1}function g(a,b,f){var u=a.childNodes,c;c=$(a);a={};for(var q,C=c.css("font-family").split(","),F=C.shift();!q&&F;)q=d[F.trim().toLowerCase()],
3457F=C.shift();a["font-family"]=q||"times";a["font-style"]=h[c.css("font-style")]||"normal";q=e[c.css("font-weight")]||"normal";"bold"===q&&(a["font-style"]="normal"===a["font-style"]?q:q+a["font-style"]);a["font-size"]=k(c.css("font-size"))||1;a["line-height"]=k(c.css("line-height"))||1;a.display="inline"===c.css("display")?"inline":"block";"block"===a.display&&(a["margin-top"]=k(c.css("margin-top"))||0,a["margin-bottom"]=k(c.css("margin-bottom"))||0,a["padding-top"]=k(c.css("padding-top"))||0,a["padding-bottom"]=
3458k(c.css("padding-bottom"))||0);if(q="block"===a.display)b.setBlockBoundary(),b.setBlockStyle(a);C=0;for(F=u.length;C<F;C++)if(c=u[C],"object"===typeof c)if(1===c.nodeType&&"SCRIPT"!=c.nodeName){var H=c,n=b,x=f,z=!1,A=void 0,y=void 0,s=x["#"+H.id];if(s)if("function"===typeof s)z=s(H,n);else{A=0;for(y=s.length;!z&&A!==y;)z=s[A](H,n),A++}s=x[H.nodeName];if(!z&&s)if("function"===typeof s)z=s(H,n);else{A=0;for(y=s.length;!z&&A!==y;)z=s[A](H,n),A++}z||g(c,b,f)}else 3===c.nodeType&&b.addText(c.nodeValue,
3459a);else"string"===typeof c&&b.addText(c,a);q&&b.setBlockBoundary()}String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")});String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")});b.prototype.init=function(){this.paragraph={text:[],style:[]};this.pdf.internal.write("q")};b.prototype.dispose=function(){this.pdf.internal.write("Q");
3460return{x:this.x,y:this.y}};b.prototype.splitFragmentsIntoLines=function(a,b){for(var d=this.pdf.internal.scaleFactor,e={},c,h,g,f,k,n=[],x=[n],z=0,A=this.settings.width;a.length;)if(f=a.shift(),k=b.shift(),f)if(c=k["font-family"],h=k["font-style"],g=e[c+h],g||(g=this.pdf.internal.getFont(c,h).metadata.Unicode,e[c+h]=g),c={widths:g.widths,kerning:g.kerning,fontSize:12*k["font-size"],textIndent:z},h=this.pdf.getStringUnitWidth(f,c)*c.fontSize/d,z+h>A){f=this.pdf.splitTextToSize(f,A,c);for(n.push([f.shift(),
3461k]);f.length;)n=[[f.shift(),k]],x.push(n);z=this.pdf.getStringUnitWidth(n[0][0],c)*c.fontSize/d}else n.push([f,k]),z+=h;return x};b.prototype.RenderTextFragment=function(a,b){var d=this.pdf.internal.getFont(b["font-family"],b["font-style"]);this.pdf.internal.write("/"+d.id,(12*b["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(a)+") Tj")};b.prototype.renderParagraph=function(){for(var a=this.paragraph.text,b=0,d=a.length,e,c=!1,h=!1;!c&&b!==d;)(e=a[b]=a[b].trimLeft())&&(c=!0),b++;for(b=
3462d-1;d&&!h&&-1!==b;)(e=a[b]=a[b].trimRight())&&(h=!0),b--;c=/\s+$/g;h=!0;for(b=0;b!==d;b++)e=a[b].replace(/\s+/g," "),h&&(e=e.trimLeft()),e&&(h=c.test(e)),a[b]=e;b=this.paragraph.style;e=(d=this.paragraph.blockstyle)||{};this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:d};if(a.join("").trim()){a=this.splitFragmentsIntoLines(a,b);b=12/this.pdf.internal.scaleFactor;c=(Math.max((d["margin-top"]||0)-(e["margin-bottom"]||0),0)+(d["padding-top"]||0))*b;d=((d["margin-bottom"]||0)+(d["padding-bottom"]||
34630))*b;e=this.pdf.internal.write;var g,f;this.y+=c;for(e("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");a.length;){c=a.shift();g=h=0;for(f=c.length;g!==f;g++)c[g][0].trim()&&(h=Math.max(h,c[g][1]["line-height"],c[g][1]["font-size"]));e(0,(-12*h).toFixed(2),"Td");g=0;for(f=c.length;g!==f;g++)c[g][0]&&this.RenderTextFragment(c[g][0],c[g][1]);this.y+=h*b}e("ET","Q");this.y+=d}};b.prototype.setBlockBoundary=function(){this.renderParagraph()};
3464b.prototype.setBlockStyle=function(a){this.paragraph.blockstyle=a};b.prototype.addText=function(a,b){this.paragraph.text.push(a);this.paragraph.style.push(b)};var d={helvetica:"helvetica","sans-serif":"helvetica",serif:"times",times:"times","times new roman":"times",monospace:"courier",courier:"courier"},e={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},h={normal:"normal",italic:"italic",
3465oblique:"italic"},a={normal:1};f.fromHTML=function(a,d,e,h){if("string"===typeof a){var c="jsPDFhtmlText"+Date.now().toString()+(1E3*Math.random()).toFixed(0);
3465$('<div style="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;"><iframe style="height:1px;width:1px" name="'+c+'" /></div>').appendTo(document.body);a=$(window.frames[c].document.body).html(a)[0]}d=
3466new b(this,d,e,h);g(a,d,h.elementHandlers);return d.dispose()}})(jsPDF.API);
3467(function(f){f.addSVG=function(b,f,g,d,e){if(void 0===f||void 0===f)throw Error("addSVG needs values for 'x' and 'y'");var h=document.createElement("iframe"),a=document.createElement("style");a.type="text/css";a.styleSheet?a.styleSheet.cssText=".jsPDF_sillysvg_iframe {display:none;position:absolute;}":a.appendChild(document.createTextNode(".jsPDF_sillysvg_iframe {display:none;position:absolute;}"));document.getElementsByTagName("head")[0].appendChild(a);h.name="childframe";h.setAttribute("width",
34680);h.setAttribute("height",0);h.setAttribute("frameborder","0");h.setAttribute("scrolling","no");h.setAttribute("seamless","seamless");h.setAttribute("class","jsPDF_sillysvg_iframe");document.body.appendChild(h);h=(h.contentWindow||h.contentDocument).document;h.write(b);h.close();h=h.getElementsByTagName("svg")[0];b=[1,1];var a=parseFloat(h.getAttribute("width")),p=parseFloat(h.getAttribute("height"));a&&p&&(d&&e?b=[d/a,e/p]:d?b=[d/a,d/a]:e&&(b=[e/p,e/p]));h=h.childNodes;d=0;for(e=h.length;d<e;d++)if(a=
3469h[d],a.tagName&&"PATH"===a.tagName.toUpperCase()){for(var a=a.getAttribute("d").split(" "),p=parseFloat(a[1]),j=parseFloat(a[2]),m=[],u=3,c=a.length;u<c;)"c"===a[u]?(m.push([parseFloat(a[u+1]),parseFloat(a[u+2]),parseFloat(a[u+3]),parseFloat(a[u+4]),parseFloat(a[u+5]),parseFloat(a[u+6])]),u+=7):"l"===a[u]?(m.push([parseFloat(a[u+1]),parseFloat(a[u+2])]),u+=3):u+=1;a=[p,j,m];a[0]=a[0]*b[0]+f;a[1]=a[1]*b[1]+g;this.lines.call(this,a[2],a[0],a[1],b)}return this}})(jsPDF.API);
3470(function(f){var b=f.getCharWidthsArray=function(b,e){e||(e={});var h=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,a=h.fof?h.fof:1,g=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,f=g.fof?g.fof:1,m,k,c,q=0,C=h[0]||a,F=[];m=0;for(k=b.length;m<k;m++)c=b.charCodeAt(m),F.push((h[c]||C)/a+(g[c]&&g[c][q]||0)/f),q=c;return F},k=function(b){for(var e=b.length,h=0;e;)e--,h+=b[e];return h};f.getStringUnitWidth=function(d,e){return k(b.call(this,d,e))};var g=function(d,
3471e,h){h||(h={});var a=b(" ",h)[0],g=d.split(" "),f=[];d=[f];var m=h.textIndent||0,u=0,c=0,q,C,F,H;F=0;for(H=g.length;F<H;F++){q=g[F];C=b(q,h);c=k(C);if(m+u+c>e){if(c>e){for(var c=q,n=C,x=e,z=[],A=0,y=c.length,s=0;A!==y&&s+n[A]<e-(m+u);)s+=n[A],A++;z.push(c.slice(0,A));m=A;for(s=0;A!==y;)s+n[A]>x&&(z.push(c.slice(m,A)),s=0,m=A),s+=n[A],A++;m!==A&&z.push(c.slice(m,A));m=z;f.push(m.shift());for(f=[m.pop()];m.length;)d.push([m.shift()]);c=k(C.slice(q.length-f[0].length))}else f=[q];d.push(f);m=c}else f.push(q),
3472m+=u+c;u=a}e=[];F=0;for(H=d.length;F<H;F++)e.push(d[F].join(" "));return e};f.splitTextToSize=function(b,e,h){h||(h={});var a=h.fontSize||this.internal.getFontSize(),f;var j=h;f={"0":1};var m={};!j.widths||!j.kerning?(j=this.internal.getFont(j.fontName,j.fontStyle),f=j.metadata.Unicode?{widths:j.metadata.Unicode.widths||f,kerning:j.metadata.Unicode.kerning||m}:{widths:f,kerning:m}):f={widths:j.widths,kerning:j.kerning};b=b.match(/[\n\r]/)?b.split(/\r\n|\r|\n/g):[b];e=1*this.internal.scaleFactor*e/
3473a;f.textIndent=h.textIndent?1*h.textIndent*this.internal.scaleFactor/a:0;m=[];h=0;for(a=b.length;h<a;h++)m=m.concat(g(b[h],e,f));return m}})(jsPDF.API);
3474(function(f){var b=function(b){for(var d={},a=0;16>a;a++)d["klmnopqrstuvwxyz"[a]]="0123456789abcdef"[a];for(var g={},f=1,m,k=g,c=[],q,C="",F="",H,n=b.length-1,a=1;a!=n;)q=b[a],a+=1,"'"==q?m?(H=m.join(""),m=void 0):m=[]:m?m.push(q):"{"==q?(c.push([k,H]),k={},H=void 0):"}"==q?(q=c.pop(),q[0][q[1]]=k,H=void 0,k=q[0]):"-"==q?f=-1:void 0===H?d.hasOwnProperty(q)?(C+=d[q],H=parseInt(C,16)*f,f=1,C=""):C+=q:d.hasOwnProperty(q)?(F+=d[q],k[H]=parseInt(F,16)*f,f=1,H=void 0,F=""):F+=q;return g},k={codePages:["WinAnsiEncoding"],
3475WinAnsiEncoding:b("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},g={Unicode:{Courier:k,"Courier-Bold":k,"Courier-BoldOblique":k,"Courier-Oblique":k,Helvetica:k,"Helvetica-Bold":k,"Helvetica-BoldOblique":k,"Helvetica-Oblique":k,"Times-Roman":k,"Times-Bold":k,"Times-BoldItalic":k,"Times-Italic":k}},d={Unicode:{"Courier-Oblique":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":b("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3me
3475k3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),
3476"Helvetica-Bold":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4y
3476dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
3477Courier:b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":b("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),
3478Helvetica:b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4y
3478dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),
3479"Helvetica-BoldOblique":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4y
3479dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
3480"Courier-Bold":b("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":b("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}
3480fv{17su5tu5qs}fw{17su5tu5qs}}}"),
3481"Times-Roman":b("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),
3482"Helvetica-Oblique":b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4y
3482dn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};
3483f.events.push(["addFonts",function(b){var h,a,f,j;for(a in b.fonts)if(b.fonts.hasOwnProperty(a)){h=b.fonts[a];if(f=d.Unicode[h.PostScriptName])j=h.metadata.Unicode?h.metadata.Unicode:h.metadata.Unicode={},j.widths=f.widths,j.kerning=f.kerning;if(f=g.Unicode[h.PostScriptName])j=h.metadata.Unicode?h.metadata.Unicode:h.metadata.Unicode={},j.encoding=f,f.codePages&&f.codePages.length&&(h.encoding=f.codePages[0])}}])})(jsPDF.API);
3484var BlobBuilder=BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder||function(f){var b=function(a){return Object.prototype.toString.call(a).match(/^\[object\s(.*)\]$/)[1]},k=function(){this.data=[]},g=function(a,b,c){this.data=a;this.size=a.length;this.type=b;this.encoding=c},d=k.prototype,e=g.prototype,h=f.FileReaderSync,a=function(a){this.code=this[this.name=a]},p="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),
3485j=p.length,m=f.URL||f.webkitURL||f,u=m.createObjectURL,c=m.revokeObjectURL,q=m,C=f.btoa,F=f.atob,H=!1,n=function(a){H=!a},x=f.ArrayBuffer,z=f.Uint8Array;for(k.fake=e.fake=!0;j--;)a.prototype[p[j]]=j+1;try{z&&n.apply(0,new z(1))}catch(A){}m.createObjectURL||(q=f.URL={});q.createObjectURL=function(a){var b=a.type;null===b&&(b="application/octet-stream");if(a instanceof g)return b="data:"+b,"base64"===a.encoding?b+";base64,"+a.data:"URI"===a.encoding?b+","+decodeURIComponent(a.data):C?b+";base64,"+C(a.data):
3486b+","+encodeURIComponent(a.data);if(u)return u.call(m,a)};q.revokeObjectURL=function(a){"data:"!==a.substring(0,5)&&c&&c.call(m,a)};d.append=function(c){var d=this.data;if(z&&c instanceof x)if(H)d.push(String.fromCharCode.apply(String,new z(c)));else{d="";c=new z(c);for(var e=0,f=c.length;e<f;e++)d+=String.fromCharCode(c[e])}else if("Blob"===b(c)||"File"===b(c))if(h)e=new h,d.push(e.readAsBinaryString(c));else throw new a("NOT_READABLE_ERR");else c instanceof g?"base64"===c.encoding&&F?d.push(F(c.data)):
3487"URI"===c.encoding?d.push(decodeURIComponent(c.data)):"raw"===c.encoding&&d.push(c.data):("string"!==typeof c&&(c+=""),d.push(unescape(encodeURIComponent(c))))};d.getBlob=function(a){arguments.length||(a=null);return new g(this.data.join(""),a,"raw")};d.toString=function(){return"[object BlobBuilder]"};e.slice=function(a,c,b){var d=arguments.length;3>d&&(b=null);return new g(this.data.slice(a,1<d?c:this.data.length),b,this.encoding)};e.toString=function(){return"[object Blob]"};return k}(self),saveAs=
3488saveAs||navigator.msSaveBlob&&navigator.msSaveBlob.bind(navigator)||function(f){var b=f.document,k=f.URL||f.webkitURL||f,g=b.createElementNS("http://www.w3.org/1999/xhtml","a"),d="download"in g,e=f.webkitRequestFileSystem,h=f.requestFileSystem||e||f.mozRequestFileSystem,a=function(a){(f.setImmediate||f.setTimeout)(function(){throw a;},0)},p=0,j=[],m=function(c,b,d){b=[].concat(b);for(var e=b.length;e--;){var f=c["on"+b[e]];if("function"===typeof f)try{f.call(c,d||c)}catch(h){a(h)}}},u=function(a,
3489c){var k=this,u=a.type,n=!1,x,z,A=function(){var c=(f.URL||f.webkitURL||f).createObjectURL(a);j.push(c);return c},y=function(){m(k,["writestart","progress","write","writeend"])}
3489,s=function(){if(n||!x)x=A(a);z&&(z.location.href=x);k.readyState=k.DONE;y()},r=function(a){return function(){if(k.readyState!==k.DONE)return a.apply(this,arguments)}},I={create:!0,exclusive:!1},w;k.readyState=k.INIT;c||(c="download");if(d&&(x=A(a),g.href=x,g.download=c,w=b.createEvent("MouseEvents"),w.initMouseEvent("click",
3490!0,!1,f,0,0,0,0,0,!1,!1,!1,!1,0,null),g.dispatchEvent(w))){k.readyState=k.DONE;y();return}f.chrome&&(u&&"application/octet-stream"!==u)&&(w=a.slice||a.webkitSlice,a=w.call(a,0,a.size,"application/octet-stream"),n=!0);e&&"download"!==c&&(c+=".download");z="application/octet-stream"===u||e?f:f.open();h?(p+=a.size,h(f.TEMPORARY,p,r(function(b){b.root.getDirectory("saved",I,r(function(b){var d=function(){b.getFile(c,I,r(function(c){c.createWriter(r(function(b){b.onwriteend=function(a){z.location.href=
3491c.toURL();j.push(c);k.readyState=k.DONE;m(k,"writeend",a)};b.onerror=function(){var a=b.error;a.code!==a.ABORT_ERR&&s()};["writestart","progress","write","abort"].forEach(function(a){b["on"+a]=k["on"+a]});b.write(a);k.abort=function(){b.abort();k.readyState=k.DONE};k.readyState=k.WRITING}),s)}),s)};b.getFile(c,{create:!1},r(function(a){a.remove();d()}),r(function(a){a.code===a.NOT_FOUND_ERR?d():s()}))}),s)}),s)):s()},c=u.prototype;c.abort=function(){this.readyState=this.DONE;m(this,"abort")};c.readyState=
3492c.INIT=0;c.WRITING=1;c.DONE=2;c.error=c.onwritestart=c.onprogress=c.onwrite=c.onabort=c.onerror=c.onwriteend=null;f.addEventListener("unload",function(){for(var a=j.length;a--;){var c=j[a];"string"===typeof c?k.revokeObjectURL(c):c.remove()}j.length=0},!1);return function(a,c){return new u(a,c)}}(self),MAX_BITS=15,D_CODES=30,BL_CODES=19,LENGTH_CODES=29,LITERALS=256,L_CODES=LITERALS+1+LENGTH_CODES,HEAP_SIZE=2*L_CODES+1,END_BLOCK=256,MAX_BL_BITS=7,REP_3_6=16,REPZ_3_10=17,REPZ_11_138=18,Buf_size=16,
3493Z_DEFAULT_COMPRESSION=-1,Z_FILTERED=1,Z_HUFFMAN_ONLY=2,Z_DEFAULT_STRATEGY=0,Z_NO_FLUSH=0,Z_PARTIAL_FLUSH=1,Z_FULL_FLUSH=3,Z_FINISH=4,Z_OK=0,Z_STREAM_END=1,Z_NEED_DICT=2,Z_STREAM_ERROR=-2,Z_DATA_ERROR=-3,Z_BUF_ERROR=-5,_dist_code=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,
349413,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,
349521,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
349628,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];
3497function Tree(){var f=this;f.build_tree=function(b){var k=f.dyn_tree,g=f.stat_desc.static_tree,d=f.stat_desc.elems,e,h=-1,a;b.heap_len=0;b.heap_max=HEAP_SIZE;for(e=0;e<d;e++)0!==k[2*e]?(b.heap[++b.heap_len]=h=e,b.depth[e]=0):k[2*e+1]=0;for(;2>b.heap_len;)a=b.heap[++b.heap_len]=2>h?++h:0,k[2*a]=1,b.depth[a]=0,b.opt_len--,g&&(b.static_len-=g[2*a+1]);f.max_code=h;for(e=Math.floor(b.heap_len/2);1<=e;e--)b.pqdownheap(k,e);a=d;do e=b.heap[1],b.heap[1]=b.heap[b.heap_len--],b.pqdownheap(k,1),g=b.heap[1],
3498b.heap[--b.heap_max]=e,b.heap[--b.heap_max]=g,k[2*a]=k[2*e]+k[2*g],b.depth[a]=Math.max(b.depth[e],b.depth[g])+1,k[2*e+1]=k[2*g+1]=a,b.heap[1]=a++,b.pqdownheap(k,1);while(2<=b.heap_len);b.heap[--b.heap_max]=b.heap[1];e=f.dyn_tree;for(var h=f.stat_desc.static_tree,p=f.stat_desc.extra_bits,j=f.stat_desc.extra_base,m=f.stat_desc.max_length,u,c,q=0,d=0;d<=MAX_BITS;d++)b.bl_count[d]=0;e[2*b.heap[b.heap_max]+1]=0;for(a=b.heap_max+1;a<HEAP_SIZE;a++)g=b.heap[a],d=e[2*e[2*g+1]+1]+1,d>m&&(d=m,q++),e[2*g+1]=
3499d,g>f.max_code||(b.bl_count[d]++,u=0,g>=j&&(u=p[g-j]),c=e[2*g],b.opt_len+=c*(d+u),h&&(b.static_len+=c*(h[2*g+1]+u)));if(0!==q){do{for(d=m-1;0===b.bl_count[d];)d--;b.bl_count[d]--;b.bl_count[d+1]+=2;b.bl_count[m]--;q-=2}while(0<q);for(d=m;0!==d;d--)for(g=b.bl_count[d];0!==g;)h=b.heap[--a],h>f.max_code||(e[2*h+1]!=d&&(b.opt_len+=(d-e[2*h+1])*e[2*h],e[2*h+1]=d),g--)}e=f.max_code;a=b.bl_count;b=[];g=0;for(d=1;d<=MAX_BITS;d++)b[d]=g=g+a[d-1]<<1;for(a=0;a<=e;a++)if(p=k[2*a+1],0!==p){g=k;d=2*a;h=b[p]++;
3500j=0;do j|=h&1,h>>>=1,j<<=1;while(0<--p);g[d]=j>>>1}}}
3501Tree._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,
350225,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28];Tree.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0];Tree.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576];
3503Tree.d_code=function(f){return 256>f?_dist_code[f]:_dist_code[256+(f>>>7)]};Tree.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];Tree.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];Tree.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];Tree.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];function StaticTree(f,b,k,g,d){this.static_tree=f;this.extra_bits=b;this.extra_base=k;this.elems=g;this.max_length=d}
3504StaticTree.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,
35058,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,
35069,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,
350748,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8];StaticTree.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5];StaticTree.static_l_desc=new StaticTree(StaticTree.static_ltree,Tree.extra_lbits,LITERALS+1,L_CODES,MAX_BITS);
3508StaticTree.static_d_desc=new StaticTree(StaticTree.static_dtree,Tree.extra_dbits,0,D_CODES,MAX_BITS);StaticTree.static_bl_desc=new StaticTree(null,Tree.extra_blbits,0,BL_CODES,MAX_BL_BITS);var MAX_MEM_LEVEL=9,DEF_MEM_LEVEL=8;function Config(f,b,k,g,d){this.good_length=f;this.max_lazy=b;this.nice_length=k;this.max_chain=g;this.func=d}
3509var STORED=0,FAST=1,SLOW=2,config_table=[new Config(0,0,0,0,STORED),new Config(4,4,8,4,FAST),new Config(4,5,16,8,FAST),new Config(4,6,32,32,FAST),new Config(4,4,16,16,SLOW),new Config(8,16,32,32,SLOW),new Config(8,16,128,128,SLOW),new Config(8,32,128,256,SLOW),new Config(32,128,258,1024,SLOW),new Config(32,258,258,4096,SLOW)],z_errmsg="need dictionary;stream end;;;stream error;data error;;buffer error;;".split(";"),NeedMore=0,BlockDone=1,FinishStarted=2,FinishDone=3,PRESET_DICT=32,INIT_STATE=42,BUSY_STATE=
3510113,FINISH_STATE=666,Z_DEFLATED=8,STORED_BLOCK=0,STATIC_TREES=1,DYN_TREES=2,MIN_MATCH=3,MAX_MATCH=258,MIN_LOOKAHEAD=MAX_MATCH+MIN_MATCH+1;function smaller(f,b,k,g){var d=f[2*b];f=f[2*k];return d<f||d==f&&g[b]<=g[k]}
3511function Deflate(){function f(){var a;for(a=0;a<L_CODES;a++)U[2*a]=0;for(a=0;a<D_CODES;a++)X[2*a]=0;for(a=0;a<BL_CODES;a++)O[2*a]=0;U[2*END_BLOCK]=1;S=la=n.opt_len=n.static_len=0}function b(a,c){var b,d=-1,e,f=a[1],h=0,g=7,j=4;0===f&&(g=138,j=3);a[2*(c+1)+1]=65535;for(b=0;b<=c;b++)e=f,f=a[2*(b+1)+1],++h<g&&e==f||(h<j?O[2*e]+=h:0!==e?(e!=d&&O[2*e]++,O[2*REP_3_6]++):10>=h?O[2*REPZ_3_10]++:O[2*REPZ_11_138]++,h=0,d=e,0===f?(g=138,j=3):e==f?(g=6,j=3):(g=7,j=4))}function k(a){n.pending_buf[n.pending++]=
3512a}
3512function g(a){k(a&255);k(a>>>8&255)}function d(a,c){L>Buf_size-c?(P|=a<<L&65535,g(P),P=a>>>Buf_size-L,L+=c-Buf_size):(P|=a<<L&65535,L+=c)}function e(a,c){var b=2*a;d(c[b]&65535,c[b+1]&65535)}function h(a,c){var b,f=-1,h,g=a[1],j=0,k=7,l=4;0===g&&(k=138,l=3);for(b=0;b<=c;b++)if(h=g,g=a[2*(b+1)+1],!(++j<k&&h==g)){if(j<l){do e(h,O);while(0!==--j)}else 0!==h?(h!=f&&(e(h,O),j--),e(REP_3_6,O),d(j-3,2)):10>=j?(e(REPZ_3_10,O),d(j-3,3)):(e(REPZ_11_138,O),d(j-11,7));j=0;f=h;0===g?(k=138,l=3):h==g?(k=6,l=
35133):(k=7,l=4)}}function a(){16==L?(g(P),L=P=0):8<=L&&(k(P&255),P>>>=8,L-=8)}function p(a,c){var b,d,e;n.pending_buf[fa+2*S]=a>>>8&255;n.pending_buf[fa+2*S+1]=a&255;n.pending_buf[ka+S]=c&255;S++;0===a?U[2*c]++:(la++,a--,U[2*(Tree._length_code[c]+LITERALS+1)]++,X[2*Tree.d_code(a)]++);if(0===(S&8191)&&2<M){b=8*S;d=t-Q;for(e=0;e<D_CODES;e++)b+=X[2*e]*(5+Tree.extra_dbits[e]);if(la<Math.floor(S/2)&&b>>>3<Math.floor(d/2))return!0}return S==ba-1}function j(a,c){var b,f,h=0,g,j;if(0!==S){do b=n.pending_buf[fa+
35142*h]<<8&65280|n.pending_buf[fa+2*h+1]&255,f=n.pending_buf[ka+h]&255,h++,0===b?e(f,a):(g=Tree._length_code[f],e(g+LITERALS+1,a),j=Tree.extra_lbits[g],0!==j&&(f-=Tree.base_length[g],d(f,j)),b--,g=Tree.d_code(b),e(g,c),j=Tree.extra_dbits[g],0!==j&&(b-=Tree.base_dist[g],d(b,j)));while(h<S)}e(END_BLOCK,a);ga=a[2*END_BLOCK+1]}function m(){8<L?g(P):0<L&&k(P&255);L=P=0}function u(a,c,b){d((STORED_BLOCK<<1)+(b?1:0),3);m();ga=8;g(c);g(~c);n.pending_buf.set(w.subarray(a,a+c),n.pending);n.pending+=c}function c(a){var c=
35150<=Q?Q:-1,e=t-Q,g,k,l=0;if(0<M){da.build_tree(n);ea.build_tree(n);b(U,da.max_code);b(X,ea.max_code);ja.build_tree(n);for(l=BL_CODES-1;3<=l&&0===O[2*Tree.bl_order[l]+1];l--);n.opt_len+=3*(l+1)+14;g=n.opt_len+3+7>>>3;k=n.static_len+3+7>>>3;k<=g&&(g=k)}else g=k=e+5;if(e+4<=g&&-1!=c)u(c,e,a);else if(k==g)d((STATIC_TREES<<1)+(a?1:0),3),j(StaticTree.static_ltree,StaticTree.static_dtree);else{d((DYN_TREES<<1)+(a?1:0),3);c=da.max_code+1;e=ea.max_code+1;l+=1;d(c-257,5);d(e-1,5);d(l-4,4);for(g=0;g<l;g++)d(O[2*
3516Tree.bl_order[g]+1],3);h(U,c-1);h(X,e-1);j(U,X)}f();a&&m();Q=t;x.flush_pending()}function q(){var a,c,b,d;do{d=aa-E-t;if(0===d&&0===t&&0===E)d=s;else if(-1==d)d--;else if(t>=s+s-MIN_LOOKAHEAD){w.set(w.subarray(s,s+s),0);W-=s;t-=s;Q-=s;b=a=v;do c=G[--b]&65535,G[b]=c>=s?c-s:0;while(0!==--a);b=a=s;do c=D[--b]&65535,D[b]=c>=s?c-s:0;while(0!==--a);d+=s}if(0===x.avail_in)break;a=x.read_buf(w,t+E,d);E+=a;E>=MIN_MATCH&&(B=w[t]&255,B=(B<<N^w[t+1]&255)&l)}while(E<MIN_LOOKAHEAD&&0!==x.avail_in)}function C(a){var b=
351765535,d;for(b>A-5&&(b=A-5);;){if(1>=E){q();if(0===E&&a==Z_NO_FLUSH)return NeedMore;if(0===E)break}t+=E;E=0;d=Q+b;if(0===t||t>=d)if(E=t-d,t=d,c(!1),0===x.avail_out)return NeedMore;if(t-Q>=s-MIN_LOOKAHEAD&&(c(!1),0===x.avail_out))return NeedMore}c(a==Z_FINISH);return 0===x.avail_out?a==Z_FINISH?FinishStarted:NeedMore:a==Z_FINISH?FinishDone:BlockDone}function F(a){var c=Y,b=t,d,e=K,g=t>s-MIN_LOOKAHEAD?t-(s-MIN_LOOKAHEAD):0,f=ia,h=I,j=t+MAX_MATCH,k=w[b+e-1],l=w[b+e];K>=ha&&(c>>=2);f>E&&(f=E);do if(d=
3518a,!(w[d+e]!=l||w[d+e-1]!=k||w[d]!=w[b]||w[++d]!=w[b+1])){b+=2;d++;do;while(w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&w[++b]==w[++d]&&b<j);d=MAX_MATCH-(j-b);b=j-MAX_MATCH;if(d>e){W=a;e=d;if(d>=f)break;k=w[b+e-1];l=w[b+e]}}while((a=D[a&h]&65535)>g&&0!==--c);return e<=E?e:E}function H(a){for(var b=0,d,e;;){if(E<MIN_LOOKAHEAD){q();if(E<MIN_LOOKAHEAD&&a==Z_NO_FLUSH)return NeedMore;if(0===E)break}E>=MIN_MATCH&&(B=(B<<N^w[t+(MIN_MATCH-
35191)]&255)&l,b=G[B]&65535,D[t&I]=G[B],G[B]=t);K=J;ca=W;J=MIN_MATCH-1;if(0!==b&&(K<Z&&(t-b&65535)<=s-MIN_LOOKAHEAD)&&(T!=Z_HUFFMAN_ONLY&&(J=F(b)),5>=J&&(T==Z_FILTERED||J==MIN_MATCH&&4096<t-W)))J=MIN_MATCH-1;if(K>=MIN_MATCH&&J<=K){e=t+E-MIN_MATCH;d=p(t-1-ca,K-MIN_MATCH);E-=K-1;K-=2;do++t<=e&&(B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,b=G[B]&65535,D[t&I]=G[B],G[B]=t);while(0!==--K);R=0;J=MIN_MATCH-1;t++;if(d&&(c(!1),0===x.avail_out))return NeedMore}else if(0!==R){if((d=p(0,w[t-1]&255))&&c(!1),t++,E--,0===x.avail_out)return NeedMore}else R=
35201,t++,E--}0!==R&&(p(0,w[t-1]&255),R=0);c(a==Z_FINISH);return 0===x.avail_out?a==Z_FINISH?FinishStarted:NeedMore:a==Z_FINISH?FinishDone:BlockDone}var n=this,x,z,A,y,s,r,I,w,aa,D,G,B,v,V,l,N,Q,J,ca,R,t,W,E,K,Y,Z,M,T,ha,ia,U,X,O,da=new Tree,ea=new Tree,ja=new Tree;n.depth=[];var ka,ba,S,fa,la,ga,P,L;n.bl_count=[];n.heap=[];U=[];X=[];O=[];n.pqdownheap=function(a,b){for(var c=n.heap,d=c[b],e=b<<1;e<=n.heap_len;){e<n.heap_len&&smaller(a,c[e+1],c[e],n.depth)&&e++;if(smaller(a,d,c[e],n.depth))break;c[b]=
3521c[e];b=e;e<<=1}c[b]=d};n.deflateInit=function(a,b,c,d,e,g){d||(d=Z_DEFLATED);e||(e=DEF_MEM_LEVEL);g||(g=Z_DEFAULT_STRATEGY);a.msg=null;b==Z_DEFAULT_COMPRESSION&&(b=6);if(1>e||e>MAX_MEM_LEVEL||d!=Z_DEFLATED||9>c||15<c||0>b||9<b||0>g||g>Z_HUFFMAN_ONLY)return Z_STREAM_ERROR;a.dstate=n;r=c;s=1<<r;I=s-1;V=e+7;v=1<<V;l=v-1;N=Math.floor((V+MIN_MATCH-1)/MIN_MATCH);w=new Uint8Array(2*s);D=[];G=[];ba=1<<e+6;n.pending_buf=new Uint8Array(4*ba);A=4*ba;fa=Math.floor(ba/2);ka=3*ba;M=b;T=g;a.total_in=a.total_out=
35220;a.msg=null;n.pending=0;n.pending_out=0;z=BUSY_STATE;y=Z_NO_FLUSH;da.dyn_tree=U;da.stat_desc=StaticTree.static_l_desc;ea.dyn_tree=X;ea.stat_desc=StaticTree.static_d_desc;ja.dyn_tree=O;ja.stat_desc=StaticTree.static_bl_desc;L=P=0;ga=8;f();aa=2*s;for(a=G[v-1]=0;a<v-1;a++)G[a]=0;Z=config_table[M].max_lazy;ha=config_table[M].good_length;ia=config_table[M].nice_length;Y=config_table[M].max_chain;E=Q=t=0;J=K=MIN_MATCH-1;B=R=0;return Z_OK};n.deflateEnd=function(){if(z!=INIT_STATE&&z!=BUSY_STATE&&z!=FINISH_STATE)return Z_STREAM_ERROR;
3523w=D=G=n.pending_buf=null;n.dstate=null;return z==BUSY_STATE?Z_DATA_ERROR:Z_OK};n.deflateParams=function(a,b,c){var d=Z_OK;b==Z_DEFAULT_COMPRESSION&&(b=6);if(0>b||9<b||0>c||c>Z_HUFFMAN_ONLY)return Z_STREAM_ERROR;config_table[M].func!=config_table[b].func&&0!==a.total_in&&(d=a.deflate(Z_PARTIAL_FLUSH));M!=b&&(M=b,Z=config_table[M].max_lazy,ha=config_table[M].good_length,ia=config_table[M].nice_length,Y=config_table[M].max_chain);T=c;return d};n.deflateSetDictionary=function(a,b,c){a=c;var d=0;if(!b||
3524z!=INIT_STATE)return Z_STREAM_ERROR;if(a<MIN_MATCH)return Z_OK;a>s-MIN_LOOKAHEAD&&(a=s-MIN_LOOKAHEAD,d=c-a);w.set(b.subarray(d,d+a),0);Q=t=a;B=w[0]&255;B=(B<<N^w[1]&255)&l;for(b=0;b<=a-MIN_MATCH;b++)B=(B<<N^w[b+(MIN_MATCH-1)]&255)&l,D[b&I]=G[B],G[B]=b;return Z_OK};n.deflate=function(b,g){var f,h,j;if(g>Z_FINISH||0>g)return Z_STREAM_ERROR;if(!b.next_out||!b.next_in&&0!==b.avail_in||z==FINISH_STATE&&g!=Z_FINISH)return b.msg=z_errmsg[Z_NEED_DICT-Z_STREAM_ERROR],Z_STREAM_ERROR;if(0===b.avail_out)return b.msg=
3525z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;x=b;f=y;y=g;z==INIT_STATE&&(h=Z_DEFLATED+(r-8<<4)<<8,j=(M-1&255)>>1,3<j&&(j=3),h|=j<<6,0!==t&&(h|=PRESET_DICT),z=BUSY_STATE,h+=31-h%31,k(h>>8&255),k(h&255));if(0!==n.pending){if(x.flush_pending(),0===x.avail_out)return y=-1,Z_OK}else if(0===x.avail_in&&g<=f&&g!=Z_FINISH)return x.msg=z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;if(z==FINISH_STATE&&0!==x.avail_in)return b.msg=z_errmsg[Z_NEED_DICT-Z_BUF_ERROR],Z_BUF_ERROR;if(0!==x.avail_in||0!==E||g!=Z_NO_FLUSH&&
3526z!=FINISH_STATE){f=-1;switch(config_table[M].func){case STORED:f=C(g);break;case FAST:a:{for(f=0;;){if(E<MIN_LOOKAHEAD){q();if(E<MIN_LOOKAHEAD&&g==Z_NO_FLUSH){f=NeedMore;break a}if(0===E)break}E>=MIN_MATCH&&(B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,f=G[B]&65535,D[t&I]=G[B],G[B]=t);0!==f&&(t-f&65535)<=s-MIN_LOOKAHEAD&&T!=Z_HUFFMAN_ONLY&&(J=F(f));if(J>=MIN_MATCH)if(h=p(t-W,J-MIN_MATCH),E-=J,J<=Z&&E>=MIN_MATCH){J--;do t++,B=(B<<N^w[t+(MIN_MATCH-1)]&255)&l,f=G[B]&65535,D[t&I]=G[B],G[B]=t;while(0!==--J);t++}else t+=
3527J,J=0,B=w[t]&255,B=(B<<N^w[t+1]&255)&l;else h=p(0,w[t]&255),E--,t++;if(h&&(c(!1),0===x.avail_out)){f=NeedMore;break a}}c(g==Z_FINISH);f=0===x.avail_out?g==Z_FINISH?FinishStarted:NeedMore:g==Z_FINISH?FinishDone:BlockDone}break;case SLOW:f=H(g)}if(f==FinishStarted||f==FinishDone)z=FINISH_STATE;if(f==NeedMore||f==FinishStarted)return 0===x.avail_out&&(y=-1),Z_OK;if(f==BlockDone){if(g==Z_PARTIAL_FLUSH)d(STATIC_TREES<<1,3),e(END_BLOCK,StaticTree.static_ltree),a(),9>1+ga+10-L&&(d(STATIC_TREES<<1,3),e(END_BLOCK,
3528StaticTree.static_ltree),a()),ga=7;else if(u(0,0,!1),g==Z_FULL_FLUSH)for(f=0;f<v;f++)G[f]=0;x.flush_pending();if(0===x.avail_out)return y=-1,Z_OK}}return g!=Z_FINISH?Z_OK:Z_STREAM_END}}function ZStream(){this.total_out=this.avail_out=this.total_in=this.avail_in=this.next_out_index=this.next_in_index=0}
3529ZStream.prototype={deflateInit:function(f,b){this.dstate=new Deflate;b||(b=MAX_BITS);return this.dstate.deflateInit(this,f,b)},deflate:function(f){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflate(this,f)},deflateEnd:function(){if(!this.dstate)return Z_STREAM_ERROR;var f=this.dstate.deflateEnd();this.dstate=null;return f},deflateParams:function(f,b){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflateParams(this,f,b)},deflateSetDictionary:function(f,b){return!this.dstate?Z_STREAM_ERROR:this.dstate.deflateSetDictionary(this,
3530f,b)},read_buf:function(f,b,k){var g=this.avail_in;g>k&&(g=k);if(0===g)return 0;this.avail_in-=g;f.set(this.next_in.subarray(this.next_in_index,this.next_in_index+g),b);this.next_in_index+=g;this.total_in+=g;return g},flush_pending:function(){var f=this.dstate.pending;f>this.avail_out&&(f=this.avail_out);0!==f&&(this.next_out.set(this.dstate.pending_buf.subarray(this.dstate.pending_out,this.dstate.pending_out+f),this.next_out_index),this.next_out_index+=f,this.dstate.pending_out+=f,this.total_out+=
3531f,this.avail_out-=f,this.dstate.pending-=f,0===this.dstate.pending&&(this.dstate.pending_out=0))}};
3532function Deflater(f){var b=new ZStream,k=Z_NO_FLUSH,g=new Uint8Array(512);"undefined"==typeof f&&(f=Z_DEFAULT_COMPRESSION);b.deflateInit(f);b.next_out=g;this.append=function(d,e){var f,a=[],p=0,j=0,m=0,u;if(d.length){b.next_in_index=0;b.next_in=d;b.avail_in=d.length;do{b.next_out_index=0;b.avail_out=512;f=b.deflate(k);if(f!=Z_OK)throw"deflating: "+b.msg;b.next_out_index&&(512==b.next_out_index?a.push(new Uint8Array(g)):a.push(new Uint8Array(g.subarray(0,b.next_out_index))));m+=b.next_out_index;e&&
3533(0<b.next_in_index&&b.next_in_index!=p)&&(e(b.next_in_index),p=b.next_in_index)}while(0<b.avail_in||0===b.avail_out);u=new Uint8Array(m);a.forEach(function(a){u.set(a,j);j+=a.length});return u}};this.flush=function(){var d,e=[],f=0,a=0,k;do{b.next_out_index=0;b.avail_out=512;d=b.deflate(Z_FINISH);if(d!=Z_STREAM_END&&d!=Z_OK)throw"deflating: "+b.msg;0<512-b.avail_out&&e.push(new Uint8Array(g.subarray(0,b.next_out_index)));a+=b.next_out_index}while(0<b.avail_in||0===b.avail_out);b.deflateEnd();k=new Uint8Array(a);
3534e.forEach(function(a){k.set(a,f);f+=a.length});return k}}
3535void function(f,b){"object"===typeof module?module.exports=b():"function"===typeof define?define(b):f.adler32cs=b()}(this,function(){var f="function"===typeof ArrayBuffer&&"function"===typeof Uint8Array,b=null,k;if(f){try{var g=require("buffer");"function"===typeof g.Buffer&&(b=g.Buffer)}catch(d){}k=function(a){return a instanceof ArrayBuffer||null!==b&&a instanceof b}}else k=function(){return!1};var e;e=null!==b?function(a){return(new b(a,"utf8")).toString("binary")}:function(a){return unescape(encodeURIComponent(a))};
3536var h=function(a,b){for(var d=a&65535,e=a>>>16,f=0,g=b.length;f<g;f++)d=(d+(b.charCodeAt(f)&255))%65521,e=(e+d)%65521;return(e<<16|d)>>>0},a=function(a,b){for(var d=a&65535,e=a>>>16,f=0,g=b.length;f<g;f++)d=(d+b[f])%65521,e=(e+d)%65521;return(e<<16|d)>>>0},g={},p=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(a=null==a?1:+a))throw Error("First arguments needs to be a finite number.");this.checksum=a>>>0},j=p.prototype={};j.constructor=
3537p;var m=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(null==a)throw Error("First argument needs to be a string.");this.checksum=h(1,a.toString())};m.prototype=j;p.from=m;m=function(a){if(!(this instanceof p))throw new TypeError("Constructor cannot called be as a function.");if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());this.checksum=h(1,a)};m.prototype=j;p.fromUtf8=m;f&&(m=function(b){if(!(this instanceof
3538p))throw new TypeError("Constructor cannot called be as a function.");if(!k(b))throw Error("First argument needs to be ArrayBuffer.");b=new Uint8Array(b);return this.checksum=a(1,b)},m.prototype=j,p.fromBuffer=m);j.update=function(a){if(null==a)throw Error("First argument needs to be a string.");a=a.toString();return this.checksum=h(this.checksum,a)};j.updateUtf8=function(a){if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());return this.checksum=h(this.checksum,a)};f&&
3539(j.updateBuffer=function(b){if(!k(b))throw Error("First argument needs to be ArrayBuffer.");b=new Uint8Array(b);return this.checksum=a(this.checksum,b)});j.clone=function(){return new u(this.checksum)};var u=g.Adler32=p;g.from=function(a){if(null==a)throw Error("First argument needs to be a string.");return h(1,a.toString())};g.fromUtf8=function(a){if(null==a)throw Error("First argument needs to be a string.");a=e(a.toString());return h(1,a)};f&&(g.fromBuffer=function(b){if(!k(b))throw Error("First argument need to be ArrayBuffer.");
3540b=new Uint8Array(b);return a(1,b)});return g});
3541
3542!function(t){t.fn.liveEdit=function(e){var n,o,i,a,s,l,u=t.extend({afterSaveAll:function(){},doubleClick:function(){}},t.fn.liveEdit.defaults,e),c=[],d=function(e){t(e).attr("contenteditable","true")},r=function(e){t(e).find("a").click(function(t){t.preventDefault()})},f=function(){var t=window.getSelection(),e=t.getRangeAt(0),n=e.getBoundingClientRect();i.addClass("appear"),i.css("top",n.top-(i.height()+8)+window.pageYOffset+"px"),i.css("left",(n.left+n.right)/2-i.width()/2+"px")},h=function(){i.removeClass("appear"),i.css("top","-999px"),i.css("left","-999px")},g=function(e){t(e.focusNode).closest("b").length>0?i.addClass("bold"):i.removeClass("bold"),t(e.focusNode).closest("i").length>0?i.addClass("italic"):i.removeClass("italic"),t(e.focusNode).closest("li").length>0?i.addClass("unorderedlist"):i.removeClass("unorderedlist"),t(e.focusNode).closest("strike").length>0?i.addClass("strikethrough"):i.removeClass("strikethrough"),t(e.focusNode).closest("a").length>0?i.addClass("url"):i.removeClass("url")},b=function(){var t=document.getSelection().anchorNode,e=t&&3===t.nodeType?t.parentNode:t;return e},m=function(e){var n=window.getSelection();return y(),D(t(n.focusNode).closest("[data-editable=true]")),t(e.target).closest(".text-options").length>0?void g(n):(t(n.focusNode).closest("[data-editable=true]").length>0&&0==t(n.focusNode).closest("figure").length?(0===b().children.length&&t(n.focusNode).closest("[data-text-options=true]").length>0&&0==t(n.focusNode).closest("li").length&&0==t(n.focusNode).closest(".caption").length&&document.execCommand("formatBlock",!1,"p"),n.isCollapsed===!0&&l===!1&&h(),n.isCollapsed===!1?t(n.focusNode).closest("[data-text-options=true]").length>0&&(f(),g(n)):h()):h(),void(l=n.isCollapsed))},v=function(){document.execCommand("strong",!1,null)},C=function(){document.execCommand("italic",!1)},x=function(){document.execCommand("strikethrough",!1)},k=function(){document.execCommand("insertunorderedlist",!1),h(),E()},B=function(){i.hasClass("edit-url")?i.removeClass("edit-url"):(i.addClass("edit-url"),setTimeout(function(){var e=window.getSelection();
3542t(e.focusNode).closest("a").length>0?t(urlField).find("input").val(t(e.focusNode).closest("a").attr("href")):document.execCommand("createLink",!1,"/"),lastSelection=window.getSelection().getRangeAt(0),l=!1,t(urlField).find("input").focus()},100))},w=function(){window.getSelection().addRange(lastSelection)},L=function(t){w(),document.execCommand("unlink",!1),""!==t&&(t.match("^(http|https)://")||(t="http://"+t),document.execCommand("createLink",!1,t))},N=function(e){t(e).on("paste",function(t){if(t.preventDefault(),t.originalEvent.clipboardData&&t.originalEvent.clipboardData.getData){var n="",o=t.originalEvent.clipboardData.getData("text/plain").split(/[\r\n]/g);for(p=0;p<o.length;p+=1)""!==o[p]&&(n+="<p>"+o[p]+"</p>");document.execCommand("insertHTML",!1,n),setTimeout(function(){D(e)},10)}})},S=function(e){t(e).on("dblclick",function(){setTimeout(function(){var t=window.getSelection();return t.isCollapsed===!0?u.doubleClick.call(this,e,t):void 0},10)})},y=function(){t.each(c,function(e,n){t(n).find("[data-editable=true]").each(function(){1==t(this).data("text-options")&&t(this).find("figure").each(function(){0===t(this).next("p").length&&t(this).after("<p><br></p>")})})})},D=function(e){t(e).find("span").each(function(){t(this).hasClass("caption")||t(this).contents().unwrap()})},E=function(){t.each(c,function(e,n){t(n).find("[data-editable=true]").each(function(){t(this).find("ul").each(function(){t(this).parent("p").length&&t(this).parent("p").contents().unwrap()})})})},T=function(){var e=[];return t.each(c,function(n,o){var i={},a=t(o).data("model"),s=t(o).data("id").toString(),l=t(o).data("url");i.model=a,i.id=s,i.url=l,t(o).find("[data-editable=true]").each(function(){var e=t(this).data("name"),n=t(this).html().replace(/\n/g,"").trim();i[e]=n}),e.push(i)}),u.afterSaveAll.call(this,e)},A=function(){sidebarInterface='<div class="live-edit-sidebar" draggable="true"><a href="#" class="save-button">'+u.saveButtonLabel+"</a></div>",textOptionsInterface='<span class="text-options"><button class="url-button">'+u.urlButtonLabel+'</button><span class="input-text"><input type="text" name="liveedit-url" /></span><button class="bold-button">'+u.boldButtonLabel+'</button><button class="italic-button">'+u.italicButtonLabel+'</button><button class="strikethrough-button">'+u.strikethroughButtonLabel+'</button><button class="unorderedlist-button">'+u.unorderedlistButtonLabel+"</button></span>",t("body").append(textOptionsInterface)},F=function(){n=t(".live-edit-sidebar"),o=t(".live-edit-sidebar .save-button"),i=t(".text-options"),urlButton=t(".text-options .url-button"),urlField=t(".text-options span.input-text"),a=t(".text-options .bold-button"),s=t(".text-options .italic-button"),strikethroughButton=t(".text-options .strikethrough-button"),unorderedListButton=t(".text-options .unorderedlist-button")},I=function(){o.on("click",T),urlButton.on("click",B),a.on("click",v),s.on("click",C),strikethroughButton.on("click",x),unorderedListButton.on("click",k),t(urlField).find("input").on("keydown",function(e){13===e.keyCode&&(e.preventDefault(),L(t(this).val()),t(this).blur())}),t(urlField).find("input").on("blur",function(){i.removeClass("edit-url"),L(t(this).val()),t(this).val(""),g(window.getSelection().focusNode)}),t(document).on("keyup",m),t(document).on("mousedown",m),t(document).on("mouseup",function(t){setTimeout(function(){m(t)},1)})};A(),F(),I();var R=function(e){var n=t(e).data("max-length");n&&t(e).on("keypress",function(t){(t.target.innerText.length>n||13===t.keyCode)&&t.preventDefault()})};return t.fn.liveEdit.loadingState=function(t){"on"==t?n.addClass("loading-state"):n.removeClass("loading-state")},this.each(function(){c.push(this),t(this).find("[data-editable=true]").each(function(){d(this),r(this),R(this),N(this),S(this)})})},t.fn.liveEdit.defaults={saveButtonLabel:"S",urlButtonLabel:"U",boldButtonLabel:"B",italicButtonLabel:"I",strikethroughButtonLabel:"ABC",unorderedlistButtonLabel:"L"}}(jQuery);
3543(function(e){"use strict";function t(t){var n=e("");try{n=e(t).clone()}catch(r){n=e("<span />").html(t)}return n}function n(e){return!!(typeof Node==="object"?e instanceof Node:e&&typeof e==="object"&&typeof e.nodeType==="number"&&typeof e.nodeName==="string")}e.print=e.fn.print=function(){var r,i,s=this;if(s instanceof e){s=s.get(0)}if(n(s)){i=e(s);if(arguments.length>0){r=arguments[0]}}else{if(arguments.length>0){i=e(arguments[0]);if(n(i[0])){if(arguments.length>1){r=arguments[1]}}else{r=arguments[0];i=e("html")}}else{i=e("html")}}var o={globalStyles:true,mediaPrint:false,stylesheet:null,noPrintSelector:".no-print",iframe:true,append:null,prepe
3543nd:null};r=e.extend({},o,r||{});var u=e("");if(r.globalStyles){u=e("style, link, meta, title")}else if(r.mediaPrint){u=e("link[media=print]")}if(r.stylesheet){u=e.merge(u,e('<link rel="stylesheet" href="'+r.stylesheet+'">'))}var a=i.clone();a=e("<span/>").append(a);a.find(r.noPrintSelector).remove();a.append(u.clone());a.append(t(r.append));a.prepend(t(r.prepend));var f=a.html();a.remove();var l,c;if(r.iframe){try{var h=e(r.iframe+"");var p=h.length;if(p===0){h=e('<iframe height="0" width="0" border="0" wmode="Opaque"/>').prependTo("body").css({position:"absolute",top:-999,left:-999})}l=h.get(0);l=l.contentWindow||l.contentDocument||l;c=l.document||l.contentDocument||l;c.open();c.write(f);c.close();setTimeout(function(){l.focus();l.print();setTimeout(function(){if(p===0){h.remove()}},100)},250)}catch(d){console.error("Failed to print from iframe",d.stack,d.message);l=window.open();l.document.write(f);l.document.close();l.focus();l.print();l.close()}}else{l=window.open();l.document.write(f);l.document.close();l.focus();l.print();l.close()}return this}})(jQuery);
3544

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.