/* HTML2canvas */

/*
  html2canvas 0.5.0-alpha1 <http://html2canvas.hertzen.com>
  Copyright (c) 2015 Niklas von Hertzen

  Released under MIT License
*/

(function(window, document, exports, global, define, undefined){

/*!
 * @overview es6-promise - a tiny implementation of Promises/A+.
 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
 * @license   Licensed under MIT license
 *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
 * @version   2.0.1
 */

(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;
l=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,
b);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=
null}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,
this.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 constructor cannot be called as a function.");N(this,a)}}var E=Array.isArray?Array.isArray:function(a){return"[object Array]"===
Object.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=
function(){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};
k.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);
q(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
a.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);
if (window) {
    window.ES6Promise.polyfill();
}


if (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") {
    (window || module.exports).html2canvas = function() {
        return Promise.reject("No canvas support");
    };
    return;
}

/*! https://mths.be/punycode v1.3.1 by @mathias */
;(function(root) {

  /** Detect free variables */
  var freeExports = typeof exports == 'object' && exports &&
    !exports.nodeType && exports;
  var freeModule = typeof module == 'object' && module &&
    !module.nodeType && module;
  var freeGlobal = typeof global == 'object' && global;
  if (
    freeGlobal.global === freeGlobal ||
    freeGlobal.window === freeGlobal ||
    freeGlobal.self === freeGlobal
  ) {
    root = freeGlobal;
  }

  /**
   * The `punycode` object.
   * @name punycode
   * @type Object
   */
  var punycode,

  /** Highest positive signed 32-bit float value */
  maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

  /** Bootstring parameters */
  base = 36,
  tMin = 1,
  tMax = 26,
  skew = 38,
  damp = 700,
  initialBias = 72,
  initialN = 128, // 0x80
  delimiter = '-', // '\x2D'

  /** Regular expressions */
  regexPunycode = /^xn--/,
  regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
  regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators

  /** Error messages */
  errors = {
    'overflow': 'Overflow: input needs wider integers to process',
    'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
    'invalid-input': 'Invalid input'
  },

  /** Convenience shortcuts */
  baseMinusTMin = base - tMin,
  floor = Math.floor,
  stringFromCharCode = String.fromCharCode,

  /** Temporary variable */
  key;

  /*--------------------------------------------------------------------------*/

  /**
   * A generic error utility function.
   * @private
   * @param {String} type The error type.
   * @returns {Error} Throws a `RangeError` with the applicable error message.
   */
  function error(type) {
    throw RangeError(errors[type]);
  }

  /**
   * A generic `Array#map` utility function.
   * @private
   * @param {Array} array The array to iterate over.
   * @param {Function} callback The function that gets called for every array
   * item.
   * @returns {Array} A new array of values returned by the callback function.
   */
  function map(array, fn) {
    var length = array.length;
    var result = [];
    while (length--) {
      result[length] = fn(array[length]);
    }
    return result;
  }

  /**
   * A simple `Array#map`-like wrapper to work with domain name strings or email
   * addresses.
   * @private
   * @param {String} domain The domain name or email address.
   * @param {Function} callback The function that gets called for every
   * character.
   * @returns {Array} A new string of characters returned by the callback
   * function.
   */
  function mapDomain(string, fn) {
    var parts = string.split('@');
    var result = '';
    if (parts.length > 1) {
      // In email addresses, only the domain name should be punycoded. Leave
      // the local part (i.e. everything up to `@`) intact.
      result = parts[0] + '@';
      string = parts[1];
    }
    var labels = string.split(regexSeparators);
    var encoded = map(labels, fn).join('.');
    return result + encoded;
  }

  /**
   * Creates an array containing the numeric code points of each Unicode
   * character in the string. While JavaScript uses UCS-2 internally,
   * this function will convert a pair of surrogate halves (each of which
   * UCS-2 exposes as separate characters) into a single code point,
   * matching UTF-16.
   * @see `punycode.ucs2.encode`
   * @see <https://mathiasbynens.be/notes/javascript-encoding>
   * @memberOf punycode.ucs2
   * @name decode
   * @param {String} string The Unicode input string (UCS-2).
   * @returns {Array} The new array of code points.
   */
  function ucs2decode(string) {
    var output = [],
        counter = 0,
        length = string.length,
        value,
        extra;
    while (counter < length) {
      value = string.charCodeAt(counter++);
      if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
        // high surrogate, and there is a next character
        extra = string.charCodeAt(counter++);
        if ((extra & 0xFC00) == 0xDC00) { // low surrogate
          output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
        } else {
          // unmatched surrogate; only append this code unit, in case the next
          // code unit is the high surrogate of a surrogate pair
          output.push(value);
          counter--;
        }
      } else {
        output.push(value);
      }
    }
    return output;
  }

  /**
   * Creates a string based on an array of numeric code points.
   * @see `punycode.ucs2.decode`
   * @memberOf punycode.ucs2
   * @name encode
   * @param {Array} codePoints The array of numeric code points.
   * @returns {String} The new Unicode string (UCS-2).
   */
  function ucs2encode(array) {
    return map(array, function(value) {
      var output = '';
      if (value > 0xFFFF) {
        value -= 0x10000;
        output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
        value = 0xDC00 | value & 0x3FF;
      }
      output += stringFromCharCode(value);
      return output;
    }).join('');
  }

  /**
   * Converts a basic code point into a digit/integer.
   * @see `digitToBasic()`
   * @private
   * @param {Number} codePoint The basic numeric code point value.
   * @returns {Number} The numeric value of a basic code point (for use in
   * representing integers) in the range `0` to `base - 1`, or `base` if
   * the code point does not represent a value.
   */
  function basicToDigit(codePoint) {
    if (codePoint - 48 < 10) {
      return codePoint - 22;
    }
    if (codePoint - 65 < 26) {
      return codePoint - 65;
    }
    if (codePoint - 97 < 26) {
      return codePoint - 97;
    }
    return base;
  }

  /**
   * Converts a digit/integer into a basic code point.
   * @see `basicToDigit()`
   * @private
   * @param {Number} digit The numeric value of a basic code point.
   * @returns {Number} The basic code point whose value (when used for
   * representing integers) is `digit`, which needs to be in the range
   * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
   * used; else, the lowercase form is used. The behavior is undefined
   * if `flag` is non-zero and `digit` has no uppercase form.
   */
  function digitToBasic(digit, flag) {
    //  0..25 map to ASCII a..z or A..Z
    // 26..35 map to ASCII 0..9
    return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
  }

  /**
   * Bias adaptation function as per section 3.4 of RFC 3492.
   * http://tools.ietf.org/html/rfc3492#section-3.4
   * @private
   */
  function adapt(delta, numPoints, firstTime) {
    var k = 0;
    delta = firstTime ? floor(delta / damp) : delta >> 1;
    delta += floor(delta / numPoints);
    for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
      delta = floor(delta / baseMinusTMin);
    }
    return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
  }

  /**
   * Converts a Punycode string of ASCII-only symbols to a string of Unicode
   * symbols.
   * @memberOf punycode
   * @param {String} input The Punycode string of ASCII-only symbols.
   * @returns {String} The resulting string of Unicode symbols.
   */
  function decode(input) {
    // Don't use UCS-2
    var output = [],
        inputLength = input.length,
        out,
        i = 0,
        n = initialN,
        bias = initialBias,
        basic,
        j,
        index,
        oldi,
        w,
        k,
        digit,
        t,
        /** Cached calculation results */
        baseMinusT;

    // Handle the basic code points: let `basic` be the number of input code
    // points before the last delimiter, or `0` if there is none, then copy
    // the first basic code points to the output.

    basic = input.lastIndexOf(delimiter);
    if (basic < 0) {
      basic = 0;
    }

    for (j = 0; j < basic; ++j) {
      // if it's not a basic code point
      if (input.charCodeAt(j) >= 0x80) {
        error('not-basic');
      }
      output.push(input.charCodeAt(j));
    }

    // Main decoding loop: start just after the last delimiter if any basic code
    // points were copied; start at the beginning otherwise.

    for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {

      // `index` is the index of the next character to be consumed.
      // Decode a generalized variable-length integer into `delta`,
      // which gets added to `i`. The overflow checking is easier
      // if we increase `i` as we go, then subtract off its starting
      // value at the end to obtain `delta`.
      for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

        if (index >= inputLength) {
          error('invalid-input');
        }

        digit = basicToDigit(input.charCodeAt(index++));

        if (digit >= base || digit > floor((maxInt - i) / w)) {
          error('overflow');
        }

        i += digit * w;
        t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);

        if (digit < t) {
          break;
        }

        baseMinusT = base - t;
        if (w > floor(maxInt / baseMinusT)) {
          error('overflow');
        }

        w *= baseMinusT;

      }

      out = output.length + 1;
      bias = adapt(i - oldi, out, oldi == 0);

      // `i` was supposed to wrap around from `out` to `0`,
      // incrementing `n` each time, so we'll fix that now:
      if (floor(i / out) > maxInt - n) {
        error('overflow');
      }

      n += floor(i / out);
      i %= out;

      // Insert `n` at position `i` of the output
      output.splice(i++, 0, n);

    }

    return ucs2encode(output);
  }

  /**
   * Converts a string of Unicode symbols (e.g. a domain name label) to a
   * Punycode string of ASCII-only symbols.
   * @memberOf punycode
   * @param {String} input The string of Unicode symbols.
   * @returns {String} The resulting Punycode string of ASCII-only symbols.
   */
  function encode(input) {
    var n,
        delta,
        handledCPCount,
        basicLength,
        bias,
        j,
        m,
        q,
        k,
        t,
        currentValue,
        output = [],
        /** `inputLength` will hold the number of code points in `input`. */
        inputLength,
        /** Cached calculation results */
        handledCPCountPlusOne,
        baseMinusT,
        qMinusT;

    // Convert the input in UCS-2 to Unicode
    input = ucs2decode(input);

    // Cache the length
    inputLength = input.length;

    // Initialize the state
    n = initialN;
    delta = 0;
    bias = initialBias;

    // Handle the basic code points
    for (j = 0; j < inputLength; ++j) {
      currentValue = input[j];
      if (currentValue < 0x80) {
        output.push(stringFromCharCode(currentValue));
      }
    }

    handledCPCount = basicLength = output.length;

    // `handledCPCount` is the number of code points that have been handled;
    // `basicLength` is the number of basic code points.

    // Finish the basic string - if it is not empty - with a delimiter
    if (basicLength) {
      output.push(delimiter);
    }

    // Main encoding loop:
    while (handledCPCount < inputLength) {

      // All non-basic code points < n have been handled already. Find the next
      // larger one:
      for (m = maxInt, j = 0; j < inputLength; ++j) {
        currentValue = input[j];
        if (currentValue >= n && currentValue < m) {
          m = currentValue;
        }
      }

      // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
      // but guard against overflow
      handledCPCountPlusOne = handledCPCount + 1;
      if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
        error('overflow');
      }

      delta += (m - n) * handledCPCountPlusOne;
      n = m;

      for (j = 0; j < inputLength; ++j) {
        currentValue = input[j];

        if (currentValue < n && ++delta > maxInt) {
          error('overflow');
        }

        if (currentValue == n) {
          // Represent delta as a generalized variable-length integer
          for (q = delta, k = base; /* no condition */; k += base) {
            t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
            if (q < t) {
              break;
            }
            qMinusT = q - t;
            baseMinusT = base - t;
            output.push(
              stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
            );
            q = floor(qMinusT / baseMinusT);
          }

          output.push(stringFromCharCode(digitToBasic(q, 0)));
          bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
          delta = 0;
          ++handledCPCount;
        }
      }

      ++delta;
      ++n;

    }
    return output.join('');
  }

  /**
   * Converts a Punycode string representing a domain name or an email address
   * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
   * it doesn't matter if you call it on a string that has already been
   * converted to Unicode.
   * @memberOf punycode
   * @param {String} input The Punycoded domain name or email address to
   * convert to Unicode.
   * @returns {String} The Unicode representation of the given Punycode
   * string.
   */
  function toUnicode(input) {
    return mapDomain(input, function(string) {
      return regexPunycode.test(string)
        ? decode(string.slice(4).toLowerCase())
        : string;
    });
  }

  /**
   * Converts a Unicode string representing a domain name or an email address to
   * Punycode. Only the non-ASCII parts of the domain name will be converted,
   * i.e. it doesn't matter if you call it with a domain that's already in
   * ASCII.
   * @memberOf punycode
   * @param {String} input The domain name or email address to convert, as a
   * Unicode string.
   * @returns {String} The Punycode representation of the given domain name or
   * email address.
   */
  function toASCII(input) {
    return mapDomain(input, function(string) {
      return regexNonASCII.test(string)
        ? 'xn--' + encode(string)
        : string;
    });
  }

  /*--------------------------------------------------------------------------*/

  /** Define the public API */
  punycode = {
    /**
     * A string representing the current Punycode.js version number.
     * @memberOf punycode
     * @type String
     */
    'version': '1.3.1',
    /**
     * An object of methods to convert from JavaScript's internal character
     * representation (UCS-2) to Unicode code points, and back.
     * @see <https://mathiasbynens.be/notes/javascript-encoding>
     * @memberOf punycode
     * @type Object
     */
    'ucs2': {
      'decode': ucs2decode,
      'encode': ucs2encode
    },
    'decode': decode,
    'encode': encode,
    'toASCII': toASCII,
    'toUnicode': toUnicode
  };

  /** Expose `punycode` */
  // Some AMD build optimizers, like r.js, check for specific condition patterns
  // like the following:
  if (
    typeof define == 'function' &&
    typeof define.amd == 'object' &&
    define.amd
  ) {
    define('punycode', function() {
      return punycode;
    });
  } else if (freeExports && freeModule) {
    if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
      freeModule.exports = punycode;
    } else { // in Narwhal or RingoJS v0.7.0-
      for (key in punycode) {
        punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
      }
    }
  } else { // in Rhino or a web browser
    root.punycode = punycode;
  }

}(this));

var html2canvasNodeAttribute = "data-html2canvas-node";
var html2canvasCanvasCloneAttribute = "data-html2canvas-canvas-clone";
var html2canvasCanvasCloneIndex = 0;
var html2canvasCloneIndex = 0;

window.html2canvas = function(nodeList, options) {
    var index = html2canvasCloneIndex++;
    options = options || {};
    if (options.logging) {
        window.html2canvas.logging = true;
        window.html2canvas.start = Date.now();
    }

    options.async = typeof(options.async) === "undefined" ? true : options.async;
    options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
    options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
    options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
    options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
    options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
    options.strict = !!options.strict;

    if (typeof(nodeList) === "string") {
        if (typeof(options.proxy) !== "string") {
            return Promise.reject("Proxy must be used when rendering url");
        }
        var width = options.width != null ? options.width : window.innerWidth;
        var height = options.height != null ? options.height : window.innerHeight;
        return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
            return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
        });
    }

    var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
    node.setAttribute(html2canvasNodeAttribute + index, index);
    return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
        if (typeof(options.onrendered) === "function") {
            log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
            options.onrendered(canvas);
        }
        return canvas;
    });
};

window.html2canvas.punycode = this.punycode;
window.html2canvas.proxy = {};

function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
    return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
        log("Document cloned");
        var attributeName = html2canvasNodeAttribute + html2canvasIndex;
        var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
        document.querySelector(selector).removeAttribute(attributeName);
        var clonedWindow = container.contentWindow;
        var node = clonedWindow.document.querySelector(selector);
        var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
        return oncloneHandler.then(function() {
            return renderWindow(node, container, options, windowWidth, windowHeight);
        });
    });
}

function renderWindow(node, container, options, windowWidth, windowHeight) {
    var clonedWindow = container.contentWindow;
    var support = new Support(clonedWindow.document);
    var imageLoader = new ImageLoader(options, support);
    var bounds = getBounds(node);
    var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
    var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
    var renderer = new options.renderer(width, height, imageLoader, options, document);
    var parser = new NodeParser(node, renderer, support, imageLoader, options);
    return parser.ready.then(function() {
        log("Finished rendering");
        var canvas;

        if (options.type === "view") {
            canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
        } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
            canvas = renderer.canvas;
        } else {
            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});
        }

        cleanupContainer(container, options);
        return canvas;
    });
}

function cleanupContainer(container, options) {
    if (options.removeContainer) {
        container.parentNode.removeChild(container);
        log("Cleaned up container");
    }
}

function crop(canvas, bounds) {
    var croppedCanvas = document.createElement("canvas");
    var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
    var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
    var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
    var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
    croppedCanvas.width = bounds.width;
    croppedCanvas.height =  bounds.height;
    log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", (x2-x1), "height:", (y2-y1));
    log("Resulting crop with width", bounds.width, "and height", bounds.height, " with x", x1, "and y", y1);
    croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, x2-x1, y2-y1, bounds.x, bounds.y, x2-x1, y2-y1);
    return croppedCanvas;
}

function documentWidth (doc) {
    return Math.max(
        Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
        Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
        Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
    );
}

function documentHeight (doc) {
    return Math.max(
        Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
        Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
        Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
    );
}

function smallImage() {
    return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
}

function isIE9() {
    return document.documentMode && document.documentMode <= 9;
}

// https://github.com/niklasvh/html2canvas/issues/503
function cloneNodeIE9(node, javascriptEnabled) {
    var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);

    var child = node.firstChild;
    while(child) {
        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
            clone.appendChild(cloneNodeIE9(child, javascriptEnabled));
        }
        child = child.nextSibling;
    }

    return clone;
}

function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) {
    labelCanvasElements(ownerDocument);
    var documentElement = isIE9() ? cloneNodeIE9(ownerDocument.documentElement, options.javascriptEnabled) : ownerDocument.documentElement.cloneNode(true);
    var container = containerDocument.createElement("iframe");

    container.className = "html2canvas-container";
    container.style.visibility = "hidden";
    container.style.position = "fixed";
    container.style.left = "-10000px";
    container.style.top = "0px";
    container.style.border = "0";
    container.width = width;
    container.height = height;
    container.scrolling = "no"; // ios won't scroll without it
    containerDocument.body.appendChild(container);

    return new Promise(function(resolve) {
        var documentClone = container.contentWindow.document;

        cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea");
        cloneNodeValues(ownerDocument.documentElement, documentElement, "select");

        /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
         if window url is about:blank, we can assign the url to current by writing onto the document
         */
        container.contentWindow.onload = container.onload = function() {
            var interval = setInterval(function() {
                if (documentClone.body.childNodes.length > 0) {
                    cloneCanvasContents(ownerDocument, documentClone);
                    clearInterval(interval);
                    if (options.type === "view") {
                        container.contentWindow.scrollTo(x, y);
                    }
                    resolve(container);
                }
            }, 50);
        };

        documentClone.open();
        documentClone.write("<!DOCTYPE html><html></html>");
        // Chrome scrolls the parent document for some reason after the write to the cloned window???
        restoreOwnerScroll(ownerDocument, x, y);
        documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
        documentClone.close();
    });
}

function cloneNodeValues(document, clone, nodeName) {
    var originalNodes = document.getElementsByTagName(nodeName);
    var clonedNodes = clone.getElementsByTagName(nodeName);
    var count = originalNodes.length;
    for (var i = 0; i < count; i++) {
        clonedNodes[i].value = originalNodes[i].value;
    }
}

function restoreOwnerScroll(ownerDocument, x, y) {
    if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
        ownerDocument.defaultView.scrollTo(x, y);
    }
}

function loadUrlDocument(src, proxy, document, width, height, options) {
    return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
        return createWindowClone(doc, document, width, height, options, 0, 0);
    });
}

function documentFromHTML(src) {
    return function(html) {
        var parser = new DOMParser(), doc;
        try {
            doc = parser.parseFromString(html, "text/html");
        } catch(e) {
            log("DOMParser not supported, falling back to createHTMLDocument");
            doc = document.implementation.createHTMLDocument("");
            try {
                doc.open();
                doc.write(html);
                doc.close();
            } catch(ee) {
                log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
                doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
            }
        }

        var b = doc.querySelector("base");
        if (!b || !b.href.host) {
            var base = doc.createElement("base");
            base.href = src;
            doc.head.insertBefore(base, doc.head.firstChild);
        }

        return doc;
    };
}


function labelCanvasElements(ownerDocument) {
    [].slice.call(ownerDocument.querySelectorAll("canvas"), 0).forEach(function(canvas) {
        canvas.setAttribute(html2canvasCanvasCloneAttribute, "canvas-" + html2canvasCanvasCloneIndex++);
    });
}

function cloneCanvasContents(ownerDocument, documentClone) {
    [].slice.call(ownerDocument.querySelectorAll("[" + html2canvasCanvasCloneAttribute + "]"), 0).forEach(function(canvas) {
        try {
            var clonedCanvas = documentClone.querySelector('[' + html2canvasCanvasCloneAttribute + '="' + canvas.getAttribute(html2canvasCanvasCloneAttribute) + '"]');
            if (clonedCanvas) {
                clonedCanvas.width = canvas.width;
                clonedCanvas.height = canvas.height;
                clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
            }
        } catch(e) {
            log("Unable to copy canvas content from", canvas, e);
        }
        canvas.removeAttribute(html2canvasCanvasCloneAttribute);
    });
}

function removeScriptNodes(parent) {
    [].slice.call(parent.childNodes, 0).filter(isElementNode).forEach(function(node) {
        if (node.tagName === "SCRIPT") {
            parent.removeChild(node);
        } else {
            removeScriptNodes(node);
        }
    });
    return parent;
}

function isElementNode(node) {
    return node.nodeType === Node.ELEMENT_NODE;
}

function absoluteUrl(url) {
    var link = document.createElement("a");
    link.href = url;
    link.href = link.href;
    return link;
}

// http://dev.w3.org/csswg/css-color/

function Color(value) {
    this.r = 0;
    this.g = 0;
    this.b = 0;
    this.a = null;
    var result = this.fromArray(value) ||
        this.namedColor(value) ||
        this.rgb(value) ||
        this.rgba(value) ||
        this.hex6(value) ||
        this.hex3(value);
}

Color.prototype.darken = function(amount) {
    var a = 1 - amount;
    return  new Color([
        Math.round(this.r * a),
        Math.round(this.g * a),
        Math.round(this.b * a),
        this.a
    ]);
};

Color.prototype.isTransparent = function() {
    return this.a === 0;
};

Color.prototype.isBlack = function() {
    return this.r === 0 && this.g === 0 && this.b === 0;
};

Color.prototype.fromArray = function(array) {
    if (Array.isArray(array)) {
        this.r = Math.min(array[0], 255);
        this.g = Math.min(array[1], 255);
        this.b = Math.min(array[2], 255);
        if (array.length > 3) {
            this.a = array[3];
        }
    }

    return (Array.isArray(array));
};

var _hex3 = /^#([a-f0-9]{3})$/i;

Color.prototype.hex3 = function(value) {
    var match = null;
    if ((match = value.match(_hex3)) !== null) {
        this.r = parseInt(match[1][0] + match[1][0], 16);
        this.g = parseInt(match[1][1] + match[1][1], 16);
        this.b = parseInt(match[1][2] + match[1][2], 16);
    }
    return match !== null;
};

var _hex6 = /^#([a-f0-9]{6})$/i;

Color.prototype.hex6 = function(value) {
    var match = null;
    if ((match = value.match(_hex6)) !== null) {
        this.r = parseInt(match[1].substring(0, 2), 16);
        this.g = parseInt(match[1].substring(2, 4), 16);
        this.b = parseInt(match[1].substring(4, 6), 16);
    }
    return match !== null;
};


var _rgb = /^rgb\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3})\)$/;

Color.prototype.rgb = function(value) {
    var match = null;
    if ((match = value.match(_rgb)) !== null) {
        this.r = Number(match[1]);
        this.g = Number(match[2]);
        this.b = Number(match[3]);
    }
    return match !== null;
};

var _rgba = /^rgba\((\d{1,3}) *, *(\d{1,3}) *, *(\d{1,3}) *, *(\d+\.?\d*)\)$/;

Color.prototype.rgba = function(value) {
    var match = null;
    if ((match = value.match(_rgba)) !== null) {
        this.r = Number(match[1]);
        this.g = Number(match[2]);
        this.b = Number(match[3]);
        this.a = Number(match[4]);
    }
    return match !== null;
};

Color.prototype.toString = function() {
    return this.a !== null && this.a !== 1 ?
    "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
    "rgb(" + [this.r, this.g, this.b].join(",") + ")";
};

Color.prototype.namedColor = function(value) {
    var color = colors[value.toLowerCase()];
    if (color) {
        this.r = color[0];
        this.g = color[1];
        this.b = color[2];
    } else if (value.toLowerCase() === "transparent") {
        this.r = this.g = this.b = this.a = 0;
        return true;
    }

    return !!color;
};

Color.prototype.isColor = true;

// 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}, {}))
var colors = {
    "aliceblue": [240, 248, 255],
    "antiquewhite": [250, 235, 215],
    "aqua": [0, 255, 255],
    "aquamarine": [127, 255, 212],
    "azure": [240, 255, 255],
    "beige": [245, 245, 220],
    "bisque": [255, 228, 196],
    "black": [0, 0, 0],
    "blanchedalmond": [255, 235, 205],
    "blue": [0, 0, 255],
    "blueviolet": [138, 43, 226],
    "brown": [165, 42, 42],
    "burlywood": [222, 184, 135],
    "cadetblue": [95, 158, 160],
    "chartreuse": [127, 255, 0],
    "chocolate": [210, 105, 30],
    "coral": [255, 127, 80],
    "cornflowerblue": [100, 149, 237],
    "cornsilk": [255, 248, 220],
    "crimson": [220, 20, 60],
    "cyan": [0, 255, 255],
    "darkblue": [0, 0, 139],
    "darkcyan": [0, 139, 139],
    "darkgoldenrod": [184, 134, 11],
    "darkgray": [169, 169, 169],
    "darkgreen": [0, 100, 0],
    "darkgrey": [169, 169, 169],
    "darkkhaki": [189, 183, 107],
    "darkmagenta": [139, 0, 139],
    "darkolivegreen": [85, 107, 47],
    "darkorange": [255, 140, 0],
    "darkorchid": [153, 50, 204],
    "darkred": [139, 0, 0],
    "darksalmon": [233, 150, 122],
    "darkseagreen": [143, 188, 143],
    "darkslateblue": [72, 61, 139],
    "darkslategray": [47, 79, 79],
    "darkslategrey": [47, 79, 79],
    "darkturquoise": [0, 206, 209],
    "darkviolet": [148, 0, 211],
    "deeppink": [255, 20, 147],
    "deepskyblue": [0, 191, 255],
    "dimgray": [105, 105, 105],
    "dimgrey": [105, 105, 105],
    "dodgerblue": [30, 144, 255],
    "firebrick": [178, 34, 34],
    "floralwhite": [255, 250, 240],
    "forestgreen": [34, 139, 34],
    "fuchsia": [255, 0, 255],
    "gainsboro": [220, 220, 220],
    "ghostwhite": [248, 248, 255],
    "gold": [255, 215, 0],
    "goldenrod": [218, 165, 32],
    "gray": [128, 128, 128],
    "green": [0, 128, 0],
    "greenyellow": [173, 255, 47],
    "grey": [128, 128, 128],
    "honeydew": [240, 255, 240],
    "hotpink": [255, 105, 180],
    "indianred": [205, 92, 92],
    "indigo": [75, 0, 130],
    "ivory": [255, 255, 240],
    "khaki": [240, 230, 140],
    "lavender": [230, 230, 250],
    "lavenderblush": [255, 240, 245],
    "lawngreen": [124, 252, 0],
    "lemonchiffon": [255, 250, 205],
    "lightblue": [173, 216, 230],
    "lightcoral": [240, 128, 128],
    "lightcyan": [224, 255, 255],
    "lightgoldenrodyellow": [250, 250, 210],
    "lightgray": [211, 211, 211],
    "lightgreen": [144, 238, 144],
    "lightgrey": [211, 211, 211],
    "lightpink": [255, 182, 193],
    "lightsalmon": [255, 160, 122],
    "lightseagreen": [32, 178, 170],
    "lightskyblue": [135, 206, 250],
    "lightslategray": [119, 136, 153],
    "lightslategrey": [119, 136, 153],
    "lightsteelblue": [176, 196, 222],
    "lightyellow": [255, 255, 224],
    "lime": [0, 255, 0],
    "limegreen": [50, 205, 50],
    "linen": [250, 240, 230],
    "magenta": [255, 0, 255],
    "maroon": [128, 0, 0],
    "mediumaquamarine": [102, 205, 170],
    "mediumblue": [0, 0, 205],
    "mediumorchid": [186, 85, 211],
    "mediumpurple": [147, 112, 219],
    "mediumseagreen": [60, 179, 113],
    "mediumslateblue": [123, 104, 238],
    "mediumspringgreen": [0, 250, 154],
    "mediumturquoise": [72, 209, 204],
    "mediumvioletred": [199, 21, 133],
    "midnightblue": [25, 25, 112],
    "mintcream": [245, 255, 250],
    "mistyrose": [255, 228, 225],
    "moccasin": [255, 228, 181],
    "navajowhite": [255, 222, 173],
    "navy": [0, 0, 128],
    "oldlace": [253, 245, 230],
    "olive": [128, 128, 0],
    "olivedrab": [107, 142, 35],
    "orange": [255, 165, 0],
    "orangered": [255, 69, 0],
    "orchid": [218, 112, 214],
    "palegoldenrod": [238, 232, 170],
    "palegreen": [152, 251, 152],
    "paleturquoise": [175, 238, 238],
    "palevioletred": [219, 112, 147],
    "papayawhip": [255, 239, 213],
    "peachpuff": [255, 218, 185],
    "peru": [205, 133, 63],
    "pink": [255, 192, 203],
    "plum": [221, 160, 221],
    "powderblue": [176, 224, 230],
    "purple": [128, 0, 128],
    "rebeccapurple": [102, 51, 153],
    "red": [255, 0, 0],
    "rosybrown": [188, 143, 143],
    "royalblue": [65, 105, 225],
    "saddlebrown": [139, 69, 19],
    "salmon": [250, 128, 114],
    "sandybrown": [244, 164, 96],
    "seagreen": [46, 139, 87],
    "seashell": [255, 245, 238],
    "sienna": [160, 82, 45],
    "silver": [192, 192, 192],
    "skyblue": [135, 206, 235],
    "slateblue": [106, 90, 205],
    "slategray": [112, 128, 144],
    "slategrey": [112, 128, 144],
    "snow": [255, 250, 250],
    "springgreen": [0, 255, 127],
    "steelblue": [70, 130, 180],
    "tan": [210, 180, 140],
    "teal": [0, 128, 128],
    "thistle": [216, 191, 216],
    "tomato": [255, 99, 71],
    "turquoise": [64, 224, 208],
    "violet": [238, 130, 238],
    "wheat": [245, 222, 179],
    "white": [255, 255, 255],
    "whitesmoke": [245, 245, 245],
    "yellow": [255, 255, 0],
    "yellowgreen": [154, 205, 50]
};


function DummyImageContainer(src) {
    this.src = src;
    log("DummyImageContainer for", src);
    if (!this.promise || !this.image) {
        log("Initiating DummyImageContainer");
        DummyImageContainer.prototype.image = new Image();
        var image = this.image;
        DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
            image.onload = resolve;
            image.onerror = reject;
            image.src = smallImage();
            if (image.complete === true) {
                resolve(image);
            }
        });
    }
}

function Font(family, size) {
    var container = document.createElement('div'),
        img = document.createElement('img'),
        span = document.createElement('span'),
        sampleText = 'Hidden Text',
        baseline,
        middle;

    container.style.visibility = "hidden";
    container.style.fontFamily = family;
    container.style.fontSize = size;
    container.style.margin = 0;
    container.style.padding = 0;

    document.body.appendChild(container);

    img.src = smallImage();
    img.width = 1;
    img.height = 1;

    img.style.margin = 0;
    img.style.padding = 0;
    img.style.verticalAlign = "baseline";

    span.style.fontFamily = family;
    span.style.fontSize = size;
    span.style.margin = 0;
    span.style.padding = 0;

    span.appendChild(document.createTextNode(sampleText));
    container.appendChild(span);
    container.appendChild(img);
    baseline = (img.offsetTop - span.offsetTop) + 1;

    container.removeChild(span);
    container.appendChild(document.createTextNode(sampleText));

    container.style.lineHeight = "normal";
    img.style.verticalAlign = "super";

    middle = (img.offsetTop-container.offsetTop) + 1;

    document.body.removeChild(container);

    this.baseline = baseline;
    this.lineWidth = 1;
    this.middle = middle;
}

function FontMetrics() {
    this.data = {};
}

FontMetrics.prototype.getMetrics = function(family, size) {
    if (this.data[family + "-" + size] === undefined) {
        this.data[family + "-" + size] = new Font(family, size);
    }
    return this.data[family + "-" + size];
};

function FrameContainer(container, sameOrigin, options) {
    this.image = null;
    this.src = container;
    var self = this;
    var bounds = getBounds(container);
    this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
        if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
            container.contentWindow.onload = container.onload = function() {
                resolve(container);
            };
        } else {
            resolve(container);
        }
    })).then(function(container) {
        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});
    }).then(function(canvas) {
        return self.image = canvas;
    });
}

FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
    var container = this.src;
    return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
};

function GradientContainer(imageData) {
    this.src = imageData.value;
    this.colorStops = [];
    this.type = null;
    this.x0 = 0.5;
    this.y0 = 0.5;
    this.x1 = 0.5;
    this.y1 = 0.5;
    this.promise = Promise.resolve(true);
}

GradientContainer.prototype.TYPES = {
    LINEAR: 1,
    RADIAL: 2
};

function ImageContainer(src, cors) {
    this.src = src;
    this.image = new Image();
    var self = this;
    this.tainted = null;
    this.promise = new Promise(function(resolve, reject) {
        self.image.onload = resolve;
        self.image.onerror = reject;
        if (cors) {
            self.image.crossOrigin = "anonymous";
        }
        self.image.src = src;
        if (self.image.complete === true) {
            resolve(self.image);
        }
    });
}

function ImageLoader(options, support) {
    this.link = null;
    this.options = options;
    this.support = support;
    this.origin = this.getOrigin(window.location.href);
}

ImageLoader.prototype.findImages = function(nodes) {
    var images = [];
    nodes.reduce(function(imageNodes, container) {
        switch(container.node.nodeName) {
        case "IMG":
            return imageNodes.concat([{
                args: [container.node.src],
                method: "url"
            }]);
        case "svg":
        case "IFRAME":
            return imageNodes.concat([{
                args: [container.node],
                method: container.node.nodeName
            }]);
        }
        return imageNodes;
    }, []).forEach(this.addImage(images, this.loadImage), this);
    return images;
};

ImageLoader.prototype.findBackgroundImage = function(images, container) {
    container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
    return images;
};

ImageLoader.prototype.addImage = function(images, callback) {
    return function(newImage) {
        newImage.args.forEach(function(image) {
            if (!this.imageExists(images, image)) {
                images.splice(0, 0, callback.call(this, newImage));
                log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image);
            }
        }, this);
    };
};

ImageLoader.prototype.hasImageBackground = function(imageData) {
    return imageData.method !== "none";
};

ImageLoader.prototype.loadImage = function(imageData) {
    if (imageData.method === "url") {
        var src = imageData.args[0];
        if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {
            return new SVGContainer(src);
        } else if (src.match(/data:image\/.*;base64,/i)) {
            return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
        } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {
            return new ImageContainer(src, false);
        } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
            return new ImageContainer(src, true);
        } else if (this.options.proxy) {
            return new ProxyImageContainer(src, this.options.proxy);
        } else {
            return new DummyImageContainer(src);
        }
    } else if (imageData.method === "linear-gradient") {
        return new LinearGradientContainer(imageData);
    } else if (imageData.method === "gradient") {
        return new WebkitGradientContainer(imageData);
    } else if (imageData.method === "svg") {
        return new SVGNodeContainer(imageData.args[0], this.support.svg);
    } else if (imageData.method === "IFRAME") {
        return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
    } else {
        return new DummyImageContainer(imageData);
    }
};

ImageLoader.prototype.isSVG = function(src) {
    return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src);
};

ImageLoader.prototype.imageExists = function(images, src) {
    return images.some(function(image) {
        return image.src === src;
    });
};

ImageLoader.prototype.isSameOrigin = function(url) {
    return (this.getOrigin(url) === this.origin);
};

ImageLoader.prototype.getOrigin = function(url) {
    var link = this.link || (this.link = document.createElement("a"));
    link.href = url;
    link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
    return link.protocol + link.hostname + link.port;
};

ImageLoader.prototype.getPromise = function(container) {
    return this.timeout(container, this.options.imageTimeout)['catch'](function() {
        var dummy = new DummyImageContainer(container.src);
        return dummy.promise.then(function(image) {
            container.image = image;
        });
    });
};

ImageLoader.prototype.get = function(src) {
    var found = null;
    return this.images.some(function(img) {
        return (found = img).src === src;
    }) ? found : null;
};

ImageLoader.prototype.fetch = function(nodes) {
    this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));
    this.images.forEach(function(image, index) {
        image.promise.then(function() {
            log("Succesfully loaded image #"+ (index+1), image);
        }, function(e) {
            log("Failed loading image #"+ (index+1), image, e);
        });
    });
    this.ready = Promise.all(this.images.map(this.getPromise, this));
    log("Finished searching images");
    return this;
};

ImageLoader.prototype.timeout = function(container, timeout) {
    var timer;
    var promise = Promise.race([container.promise, new Promise(function(res, reject) {
        timer = setTimeout(function() {
            log("Timed out loading image", container);
            reject(container);
        }, timeout);
    })]).then(function(container) {
        clearTimeout(timer);
        return container;
    });
    promise['catch'](function() {
        clearTimeout(timer);
    });
    return promise;
};

function LinearGradientContainer(imageData) {
    GradientContainer.apply(this, arguments);
    this.type = this.TYPES.LINEAR;

    var hasDirection = imageData.args[0].match(this.stepRegExp) === null;

    if (hasDirection) {
        imageData.args[0].split(" ").reverse().forEach(function(position) {
            switch(position) {
            case "left":
                this.x0 = 0;
                this.x1 = 1;
                break;
            case "top":
                this.y0 = 0;
                this.y1 = 1;
                break;
            case "right":
                this.x0 = 1;
                this.x1 = 0;
                break;
            case "bottom":
                this.y0 = 1;
                this.y1 = 0;
                break;
            case "to":
                var y0 = this.y0;
                var x0 = this.x0;
                this.y0 = this.y1;
                this.x0 = this.x1;
                this.x1 = x0;
                this.y1 = y0;
                break;
            }
        }, this);
    } else {
        this.y0 = 0;
        this.y1 = 1;
    }

    this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
        var colorStopMatch = colorStop.match(this.stepRegExp);
        return {
            color: new Color(colorStopMatch[1]),
            stop: colorStopMatch[3] === "%" ? colorStopMatch[2] / 100 : null
        };
    }, this);

    if (this.colorStops[0].stop === null) {
        this.colorStops[0].stop = 0;
    }

    if (this.colorStops[this.colorStops.length - 1].stop === null) {
        this.colorStops[this.colorStops.length - 1].stop = 1;
    }

    this.colorStops.forEach(function(colorStop, index) {
        if (colorStop.stop === null) {
            this.colorStops.slice(index).some(function(find, count) {
                if (find.stop !== null) {
                    colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;
                    return true;
                } else {
                    return false;
                }
            }, this);
        }
    }, this);
}

LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);

LinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/;

function log() {
    if (window.html2canvas.logging && window.console && window.console.log) {
        Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - window.html2canvas.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
    }
}

function NodeContainer(node, parent) {
    this.node = node;
    this.parent = parent;
    this.stack = null;
    this.bounds = null;
    this.borders = null;
    this.clip = [];
    this.backgroundClip = [];
    this.offsetBounds = null;
    this.visible = null;
    this.computedStyles = null;
    this.colors = {};
    this.styles = {};
    this.backgroundImages = null;
    this.transformData = null;
    this.transformMatrix = null;
    this.isPseudoElement = false;
    this.opacity = null;
}

NodeContainer.prototype.cloneTo = function(stack) {
    stack.visible = this.visible;
    stack.borders = this.borders;
    stack.bounds = this.bounds;
    stack.clip = this.clip;
    stack.backgroundClip = this.backgroundClip;
    stack.computedStyles = this.computedStyles;
    stack.styles = this.styles;
    stack.backgroundImages = this.backgroundImages;
    stack.opacity = this.opacity;
};

NodeContainer.prototype.getOpacity = function() {
    return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;
};

NodeContainer.prototype.assignStack = function(stack) {
    this.stack = stack;
    stack.children.push(this);
};

NodeContainer.prototype.isElementVisible = function() {
    return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (
        this.css('display') !== "none" &&
        this.css('visibility') !== "hidden" &&
        !this.node.hasAttribute("data-html2canvas-ignore") &&
        (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden")
    );
};

NodeContainer.prototype.css = function(attribute) {
    if (!this.computedStyles) {
        this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after") : this.computedStyle(null);
    }

    return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);
};

NodeContainer.prototype.prefixedCss = function(attribute) {
    var prefixes = ["webkit", "moz", "ms", "o"];
    var value = this.css(attribute);
    if (value === undefined) {
        prefixes.some(function(prefix) {
            value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));
            return value !== undefined;
        }, this);
    }
    return value === undefined ? null : value;
};

NodeContainer.prototype.computedStyle = function(type) {
    return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
};

NodeContainer.prototype.cssInt = function(attribute) {
    var value = parseInt(this.css(attribute), 10);
    return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
};

NodeContainer.prototype.color = function(attribute) {
    return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
};

NodeContainer.prototype.cssFloat = function(attribute) {
    var value = parseFloat(this.css(attribute));
    return (isNaN(value)) ? 0 : value;
};

NodeContainer.prototype.fontWeight = function() {
    var weight = this.css("fontWeight");
    switch(parseInt(weight, 10)){
    case 401:
        weight = "bold";
        break;
    case 400:
        weight = "normal";
        break;
    }
    return weight;
};

NodeContainer.prototype.parseClip = function() {
    var matches = this.css('clip').match(this.CLIP);
    if (matches) {
        return {
            top: parseInt(matches[1], 10),
            right: parseInt(matches[2], 10),
            bottom: parseInt(matches[3], 10),
            left: parseInt(matches[4], 10)
        };
    }
    return null;
};

NodeContainer.prototype.parseBackgroundImages = function() {
    return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage")));
};

NodeContainer.prototype.cssList = function(property, index) {
    var value = (this.css(property) || '').split(',');
    value = value[index || 0] || value[0] || 'auto';
    value = value.trim().split(' ');
    if (value.length === 1) {
        value = [value[0], value[0]];
    }
    return value;
};

NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {
    var size = this.cssList("backgroundSize", index);
    var width, height;

    if (isPercentage(size[0])) {
        width = bounds.width * parseFloat(size[0]) / 100;
    } else if (/contain|cover/.test(size[0])) {
        var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;
        return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};
    } else {
        width = parseInt(size[0], 10);
    }

    if (size[0] === 'auto' && size[1] === 'auto') {
        height = image.height;
    } else if (size[1] === 'auto') {
        height = width / image.width * image.height;
    } else if (isPercentage(size[1])) {
        height =  bounds.height * parseFloat(size[1]) / 100;
    } else {
        height = parseInt(size[1], 10);
    }

    if (size[0] === 'auto') {
        width = height / image.height * image.width;
    }

    return {width: width, height: height};
};

NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {
    var position = this.cssList('backgroundPosition', index);
    var left, top;

    if (isPercentage(position[0])){
        left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);
    } else {
        left = parseInt(position[0], 10);
    }

    if (position[1] === 'auto') {
        top = left / image.width * image.height;
    } else if (isPercentage(position[1])){
        top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;
    } else {
        top = parseInt(position[1], 10);
    }

    if (position[0] === 'auto') {
        left = top / image.height * image.width;
    }

    return {left: left, top: top};
};

NodeContainer.prototype.parseBackgroundRepeat = function(index) {
    return this.cssList("backgroundRepeat", index)[0];
};

NodeContainer.prototype.parseTextShadows = function() {
    var textShadow = this.css("textShadow");
    var results = [];

    if (textShadow && textShadow !== 'none') {
        var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);
        for (var i = 0; shadows && (i < shadows.length); i++) {
            var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
            results.push({
                color: new Color(s[0]),
                offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
                offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
                blur: s[3] ? s[3].replace('px', '') : 0
            });
        }
    }
    return results;
};

NodeContainer.prototype.parseTransform = function() {
    if (!this.transformData) {
        if (this.hasTransform()) {
            var offset = this.parseBounds();
            var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
            origin[0] += offset.left;
            origin[1] += offset.top;
            this.transformData = {
                origin: origin,
                matrix: this.parseTransformMatrix()
            };
        } else {
            this.transformData = {
                origin: [0, 0],
                matrix: [1, 0, 0, 1, 0, 0]
            };
        }
    }
    return this.transformData;
};

NodeContainer.prototype.parseTransformMatrix = function() {
    if (!this.transformMatrix) {
        var transform = this.prefixedCss("transform");
        var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;
        this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];
    }
    return this.transformMatrix;
};

NodeContainer.prototype.parseBounds = function() {
    return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
};

NodeContainer.prototype.hasTransform = function() {
    return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform());
};

NodeContainer.prototype.getValue = function() {
    var value = this.node.value || "";
    if (this.node.tagName === "SELECT") {
        value = selectionValue(this.node);
    } else if (this.node.type === "password") {
        value = Array(value.length + 1).join('\u2022'); // jshint ignore:line
    }
    return value.length === 0 ? (this.node.placeholder || "") : value;
};

NodeContainer.prototype.MATRIX_PROPERTY = /(matrix)\((.+)\)/;
NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;

function selectionValue(node) {
    var option = node.options[node.selectedIndex || 0];
    return option ? (option.text || "") : "";
}

function parseMatrix(match) {
    if (match && match[1] === "matrix") {
        return match[2].split(",").map(function(s) {
            return parseFloat(s.trim());
        });
    }
}

function isPercentage(value) {
    return value.toString().indexOf("%") !== -1;
}

function parseBackgrounds(backgroundImage) {
    var whitespace = ' \r\n\t',
        method, definition, prefix, prefix_i, block, results = [],
        mode = 0, numParen = 0, quote, args;
    var appendResult = function() {
        if(method) {
            if (definition.substr(0, 1) === '"') {
                definition = definition.substr(1, definition.length - 2);
            }
            if (definition) {
                args.push(definition);
            }
            if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
                prefix = method.substr(0, prefix_i);
                method = method.substr(prefix_i);
            }
            results.push({
                prefix: prefix,
                method: method.toLowerCase(),
                value: block,
                args: args,
                image: null
            });
        }
        args = [];
        method = prefix = definition = block = '';
    };
    args = [];
    method = prefix = definition = block = '';
    backgroundImage.split("").forEach(function(c) {
        if (mode === 0 && whitespace.indexOf(c) > -1) {
            return;
        }
        switch(c) {
        case '"':
            if(!quote) {
                quote = c;
            } else if(quote === c) {
                quote = null;
            }
            break;
        case '(':
            if(quote) {
                break;
            } else if(mode === 0) {
                mode = 1;
                block += c;
                return;
            } else {
                numParen++;
            }
            break;
        case ')':
            if (quote) {
                break;
            } else if(mode === 1) {
                if(numParen === 0) {
                    mode = 0;
                    block += c;
                    appendResult();
                    return;
                } else {
                    numParen--;
                }
            }
            break;

        case ',':
            if (quote) {
                break;
            } else if(mode === 0) {
                appendResult();
                return;
            } else if (mode === 1) {
                if (numParen === 0 && !method.match(/^url$/i)) {
                    args.push(definition);
                    definition = '';
                    block += c;
                    return;
                }
            }
            break;
        }

        block += c;
        if (mode === 0) {
            method += c;
        } else {
            definition += c;
        }
    });

    appendResult();
    return results;
}

function removePx(str) {
    return str.replace("px", "");
}

function asFloat(str) {
    return parseFloat(str);
}

function getBounds(node) {
    if (node.getBoundingClientRect) {
        var clientRect = node.getBoundingClientRect();
        var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
        return {
            top: clientRect.top,
            bottom: clientRect.bottom || (clientRect.top + clientRect.height),
            right: clientRect.left + width,
            left: clientRect.left,
            width:  width,
            height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
        };
    }
    return {};
}

function offsetBounds(node) {
    var parent = node.offsetParent ? offsetBounds(node.offsetParent) : {top: 0, left: 0};

    return {
        top: node.offsetTop + parent.top,
        bottom: node.offsetTop + node.offsetHeight + parent.top,
        right: node.offsetLeft + parent.left + node.offsetWidth,
        left: node.offsetLeft + parent.left,
        width: node.offsetWidth,
        height: node.offsetHeight
    };
}

function NodeParser(element, renderer, support, imageLoader, options) {
    log("Starting NodeParser");
    this.renderer = renderer;
    this.options = options;
    this.range = null;
    this.support = support;
    this.renderQueue = [];
    this.stack = new StackingContext(true, 1, element.ownerDocument, null);
    var parent = new NodeContainer(element, null);
    if (options.background) {
        renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));
    }
    if (element === element.ownerDocument.documentElement) {
        // http://www.w3.org/TR/css3-background/#special-backgrounds
        var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
        renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
    }
    parent.visibile = parent.isElementVisible();
    this.createPseudoHideStyles(element.ownerDocument);
    this.disableAnimations(element.ownerDocument);
    this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {
        return container.visible = container.isElementVisible();
    }).map(this.getPseudoElements, this));
    this.fontMetrics = new FontMetrics();
    log("Fetched nodes, total:", this.nodes.length);
    log("Calculate overflow clips");
    this.calculateOverflowClips();
    log("Start fetching images");
    this.images = imageLoader.fetch(this.nodes.filter(isElement));
    this.ready = this.images.ready.then(bind(function() {
        log("Images loaded, starting parsing");
        log("Creating stacking contexts");
        this.createStackingContexts();
        log("Sorting stacking contexts");
        this.sortStackingContexts(this.stack);
        this.parse(this.stack);
        log("Render queue created with " + this.renderQueue.length + " items");
        return new Promise(bind(function(resolve) {
            if (!options.async) {
                this.renderQueue.forEach(this.paint, this);
                resolve();
            } else if (typeof(options.async) === "function") {
                options.async.call(this, this.renderQueue, resolve);
            } else if (this.renderQueue.length > 0){
                this.renderIndex = 0;
                this.asyncRenderer(this.renderQueue, resolve);
            } else {
                resolve();
            }
        }, this));
    }, this));
}

NodeParser.prototype.calculateOverflowClips = function() {
    this.nodes.forEach(function(container) {
        if (isElement(container)) {
            if (isPseudoElement(container)) {
                container.appendToDOM();
            }
            container.borders = this.parseBorders(container);
            var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : [];
            var cssClip = container.parseClip();
            if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) {
                clip.push([["rect",
                        container.bounds.left + cssClip.left,
                        container.bounds.top + cssClip.top,
                        cssClip.right - cssClip.left,
                        cssClip.bottom - cssClip.top
                ]]);
            }
            container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;
            container.backgroundClip = (container.css('overflow') !== "hidden") ? container.clip.concat([container.borders.clip]) : container.clip;
            if (isPseudoElement(container)) {
                container.cleanDOM();
            }
        } else if (isTextNode(container)) {
            container.clip = hasParentClip(container) ? container.parent.clip : [];
        }
        if (!isPseudoElement(container)) {
            container.bounds = null;
        }
    }, this);
};

function hasParentClip(container) {
    return container.parent && container.parent.clip.length;
}

NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {
    asyncTimer = asyncTimer || Date.now();
    this.paint(queue[this.renderIndex++]);
    if (queue.length === this.renderIndex) {
        resolve();
    } else if (asyncTimer + 20 > Date.now()) {
        this.asyncRenderer(queue, resolve, asyncTimer);
    } else {
        setTimeout(bind(function() {
            this.asyncRenderer(queue, resolve);
        }, this), 0);
    }
};

NodeParser.prototype.createPseudoHideStyles = function(document) {
    this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' +
        '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }');
};

NodeParser.prototype.disableAnimations = function(document) {
    this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +
        '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');
};

NodeParser.prototype.createStyles = function(document, styles) {
    var hidePseudoElements = document.createElement('style');
    hidePseudoElements.innerHTML = styles;
    document.body.appendChild(hidePseudoElements);
};

NodeParser.prototype.getPseudoElements = function(container) {
    var nodes = [[container]];
    if (container.node.nodeType === Node.ELEMENT_NODE) {
        var before = this.getPseudoElement(container, ":before");
        var after = this.getPseudoElement(container, ":after");

        if (before) {
            nodes.push(before);
        }

        if (after) {
            nodes.push(after);
        }
    }
    return flatten(nodes);
};

function toCamelCase(str) {
    return str.replace(/(\-[a-z])/g, function(match){
        return match.toUpperCase().replace('-','');
    });
}

NodeParser.prototype.getPseudoElement = function(container, type) {
    var style = container.computedStyle(type);
    if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") {
        return null;
    }

    var content = stripQuotes(style.content);
    var isImage = content.substr(0, 3) === 'url';
    var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
    var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);

    for (var i = style.length-1; i >= 0; i--) {
        var property = toCamelCase(style.item(i));
        pseudoNode.style[property] = style[property];
    }

    pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;

    if (isImage) {
        pseudoNode.src = parseBackgrounds(content)[0].args[0];
        return [pseudoContainer];
    } else {
        var text = document.createTextNode(content);
        pseudoNode.appendChild(text);
        return [pseudoContainer, new TextContainer(text, pseudoContainer)];
    }
};


NodeParser.prototype.getChildren = function(parentContainer) {
    return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
        var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
        return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
    }, this));
};

NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
    var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);
    container.cloneTo(stack);
    var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;
    parentStack.contexts.push(stack);
    container.stack = stack;
};

NodeParser.prototype.createStackingContexts = function() {
    this.nodes.forEach(function(container) {
        if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
            this.newStackingContext(container, true);
        } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
            this.newStackingContext(container, false);
        } else {
            container.assignStack(container.parent.stack);
        }
    }, this);
};

NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
    return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
};

NodeParser.prototype.isRootElement = function(container) {
    return container.parent === null;
};

NodeParser.prototype.sortStackingContexts = function(stack) {
    stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
    stack.contexts.forEach(this.sortStackingContexts, this);
};

NodeParser.prototype.parseTextBounds = function(container) {
    return function(text, index, textList) {
        if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
            if (this.support.rangeBounds && !container.parent.hasTransform()) {
                var offset = textList.slice(0, index).join("").length;
                return this.getRangeBounds(container.node, offset, text.length);
            } else if (container.node && typeof(container.node.data) === "string") {
                var replacementNode = container.node.splitText(text.length);
                var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
                container.node = replacementNode;
                return bounds;
            }
        } else if(!this.support.rangeBounds || container.parent.hasTransform()){
            container.node = container.node.splitText(text.length);
        }
        return {};
    };
};

NodeParser.prototype.getWrapperBounds = function(node, transform) {
    var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
    var parent = node.parentNode,
        backupText = node.cloneNode(true);

    wrapper.appendChild(node.cloneNode(true));
    parent.replaceChild(wrapper, node);
    var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
    parent.replaceChild(backupText, wrapper);
    return bounds;
};

NodeParser.prototype.getRangeBounds = function(node, offset, length) {
    var range = this.range || (this.range = node.ownerDocument.createRange());
    range.setStart(node, offset);
    range.setEnd(node, offset + length);
    return range.getBoundingClientRect();
};

function ClearTransform() {}

NodeParser.prototype.parse = function(stack) {
    // http://www.w3.org/TR/CSS21/visuren.html#z-index
    var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
    var descendantElements = stack.children.filter(isElement);
    var descendantNonFloats = descendantElements.filter(not(isFloating));
    var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.
    var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.
    var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
    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.
    var text = stack.children.filter(isTextNode).filter(hasText);
    var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).
    negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)
        .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {
            this.renderQueue.push(container);
            if (isStackingContext(container)) {
                this.parse(container);
                this.renderQueue.push(new ClearTransform());
            }
        }, this);
};

NodeParser.prototype.paint = function(container) {
    try {
        if (container instanceof ClearTransform) {
            this.renderer.ctx.restore();
        } else if (isTextNode(container)) {
            if (isPseudoElement(container.parent)) {
                container.parent.appendToDOM();
            }
            this.paintText(container);
            if (isPseudoElement(container.parent)) {
                container.parent.cleanDOM();
            }
        } else {
            this.paintNode(container);
        }
    } catch(e) {
        log(e);
        if (this.options.strict) {
            throw e;
        }
    }
};

NodeParser.prototype.paintNode = function(container) {
    if (isStackingContext(container)) {
        this.renderer.setOpacity(container.opacity);
        this.renderer.ctx.save();
        if (container.hasTransform()) {
            this.renderer.setTransform(container.parseTransform());
        }
    }

    if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") {
        this.paintCheckbox(container);
    } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") {
        this.paintRadio(container);
    } else {
        this.paintElement(container);
    }
};

NodeParser.prototype.paintElement = function(container) {
    var bounds = container.parseBounds();
    this.renderer.clip(container.backgroundClip, function() {
        this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));
    }, this);

    this.renderer.clip(container.clip, function() {
        this.renderer.renderBorders(container.borders.borders);
    }, this);

    this.renderer.clip(container.backgroundClip, function() {
        switch (container.node.nodeName) {
        case "svg":
        case "IFRAME":
            var imgContainer = this.images.get(container.node);
            if (imgContainer) {
                this.renderer.renderImage(container, bounds, container.borders, imgContainer);
            } else {
                log("Error loading <" + container.node.nodeName + ">", container.node);
            }
            break;
        case "IMG":
            var imageContainer = this.images.get(container.node.src);
            if (imageContainer) {
                this.renderer.renderImage(container, bounds, container.borders, imageContainer);
            } else {
                log("Error loading <img>", container.node.src);
            }
            break;
        case "CANVAS":
            this.renderer.renderImage(container, bounds, container.borders, {image: container.node});
            break;
        case "SELECT":
        case "INPUT":
        case "TEXTAREA":
            this.paintFormValue(container);
            break;
        }
    }, this);
};

NodeParser.prototype.paintCheckbox = function(container) {
    var b = container.parseBounds();

    var size = Math.min(b.width, b.height);
    var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};
    var r = [3, 3];
    var radius = [r, r, r, r];
    var borders = [1,1,1,1].map(function(w) {
        return {color: new Color('#A5A5A5'), width: w};
    });

    var borderPoints = calculateCurvePoints(bounds, radius, borders);

    this.renderer.clip(container.backgroundClip, function() {
        this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
        this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
        if (container.node.checked) {
            this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
            this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
        }
    }, this);
};

NodeParser.prototype.paintRadio = function(container) {
    var bounds = container.parseBounds();

    var size = Math.min(bounds.width, bounds.height) - 2;

    this.renderer.clip(container.backgroundClip, function() {
        this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
        if (container.node.checked) {
            this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
        }
    }, this);
};

NodeParser.prototype.paintFormValue = function(container) {
    var value = container.getValue();
    if (value.length > 0) {
        var document = container.node.ownerDocument;
        var wrapper = document.createElement('html2canvaswrapper');
        var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
            'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',
            'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',
            'boxSizing', 'whiteSpace', 'wordWrap'];

        properties.forEach(function(property) {
            try {
                wrapper.style[property] = container.css(property);
            } catch(e) {
                // Older IE has issues with "border"
                log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
            }
        });
        var bounds = container.parseBounds();
        wrapper.style.position = "fixed";
        wrapper.style.left = bounds.left + "px";
        wrapper.style.top = bounds.top + "px";
        wrapper.textContent = value;
        document.body.appendChild(wrapper);
        this.paintText(new TextContainer(wrapper.firstChild, container));
        document.body.removeChild(wrapper);
    }
};

NodeParser.prototype.paintText = function(container) {
    container.applyTextTransform();
    var characters = window.html2canvas.punycode.ucs2.decode(container.node.data);
    var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
        return window.html2canvas.punycode.ucs2.encode([character]);
    });

    var weight = container.parent.fontWeight();
    var size = container.parent.css('fontSize');
    var family = container.parent.css('fontFamily');
    var shadows = container.parent.parseTextShadows();

    this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
    if (shadows.length) {
        // TODO: support multiple text shadows
        this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
    } else {
        this.renderer.clearShadow();
    }

    this.renderer.clip(container.parent.clip, function() {
        textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {
            if (bounds) {
                this.renderer.text(textList[index], bounds.left, bounds.bottom);
                this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));
            }
        }, this);
    }, this);
};

NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {
    switch(container.css("textDecoration").split(" ")[0]) {
    case "underline":
        // Draws a line at the baseline of the font
        // 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
        this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
        break;
    case "overline":
        this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
        break;
    case "line-through":
        // TODO try and find exact position for line-through
        this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
        break;
    }
};

var borderColorTransforms = {
    inset: [
        ["darken", 0.60],
        ["darken", 0.10],
        ["darken", 0.10],
        ["darken", 0.60]
    ]
};

NodeParser.prototype.parseBorders = function(container) {
    var nodeBounds = container.parseBounds();
    var radius = getBorderRadiusData(container);
    var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) {
        var style = container.css('border' + side + 'Style');
        var color = container.color('border' + side + 'Color');
        if (style === "inset" && color.isBlack()) {
            color = new Color([255, 255, 255, color.a]); // this is wrong, but
        }
        var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;
        return {
            width: container.cssInt('border' + side + 'Width'),
            color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,
            args: null
        };
    });
    var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);

    return {
        clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),
        borders: calculateBorders(borders, nodeBounds, borderPoints, radius)
    };
};

function calculateBorders(borders, nodeBounds, borderPoints, radius) {
    return borders.map(function(border, borderSide) {
        if (border.width > 0) {
            var bx = nodeBounds.left;
            var by = nodeBounds.top;
            var bw = nodeBounds.width;
            var bh = nodeBounds.height - (borders[2].width);

            switch(borderSide) {
            case 0:
                // top border
                bh = borders[0].width;
                border.args = drawSide({
                        c1: [bx, by],
                        c2: [bx + bw, by],
                        c3: [bx + bw - borders[1].width, by + bh],
                        c4: [bx + borders[3].width, by + bh]
                    }, radius[0], radius[1],
                    borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
                break;
            case 1:
                // right border
                bx = nodeBounds.left + nodeBounds.width - (borders[1].width);
                bw = borders[1].width;

                border.args = drawSide({
                        c1: [bx + bw, by],
                        c2: [bx + bw, by + bh + borders[2].width],
                        c3: [bx, by + bh],
                        c4: [bx, by + borders[0].width]
                    }, radius[1], radius[2],
                    borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
                break;
            case 2:
                // bottom border
                by = (by + nodeBounds.height) - (borders[2].width);
                bh = borders[2].width;
                border.args = drawSide({
                        c1: [bx + bw, by + bh],
                        c2: [bx, by + bh],
                        c3: [bx + borders[3].width, by],
                        c4: [bx + bw - borders[3].width, by]
                    }, radius[2], radius[3],
                    borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
                break;
            case 3:
                // left border
                bw = borders[3].width;
                border.args = drawSide({
                        c1: [bx, by + bh + borders[2].width],
                        c2: [bx, by],
                        c3: [bx + bw, by + borders[0].width],
                        c4: [bx + bw, by + bh]
                    }, radius[3], radius[0],
                    borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
                break;
            }
        }
        return border;
    });
}

NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {
    var backgroundClip = container.css('backgroundClip'),
        borderArgs = [];

    switch(backgroundClip) {
    case "content-box":
    case "padding-box":
        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
        break;

    default:
        parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
        parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
        parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
        parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
        break;
    }

    return borderArgs;
};

function getCurvePoints(x, y, r1, r2) {
    var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
    var ox = (r1) * kappa, // control point offset horizontal
        oy = (r2) * kappa, // control point offset vertical
        xm = x + r1, // x-middle
        ym = y + r2; // y-middle
    return {
        topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),
        topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),
        bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),
        bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})
    };
}

function calculateCurvePoints(bounds, borderRadius, borders) {
    var x = bounds.left,
        y = bounds.top,
        width = bounds.width,
        height = bounds.height,

        tlh = borderRadius[0][0],
        tlv = borderRadius[0][1],
        trh = borderRadius[1][0],
        trv = borderRadius[1][1],
        brh = borderRadius[2][0],
        brv = borderRadius[2][1],
        blh = borderRadius[3][0],
        blv = borderRadius[3][1];

    var topWidth = width - trh,
        rightHeight = height - brv,
        bottomWidth = width - brh,
        leftHeight = height - blv;

    return {
        topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),
        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),
        topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),
        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),
        bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),
        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),
        bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),
        bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)
    };
}

function bezierCurve(start, startControl, endControl, end) {
    var lerp = function (a, b, t) {
        return {
            x: a.x + (b.x - a.x) * t,
            y: a.y + (b.y - a.y) * t
        };
    };

    return {
        start: start,
        startControl: startControl,
        endControl: endControl,
        end: end,
        subdivide: function(t) {
            var ab = lerp(start, startControl, t),
                bc = lerp(startControl, endControl, t),
                cd = lerp(endControl, end, t),
                abbc = lerp(ab, bc, t),
                bccd = lerp(bc, cd, t),
                dest = lerp(abbc, bccd, t);
            return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
        },
        curveTo: function(borderArgs) {
            borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
        },
        curveToReversed: function(borderArgs) {
            borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
        }
    };
}

function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
    var borderArgs = [];

    if (radius1[0] > 0 || radius1[1] > 0) {
        borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
        outer1[1].curveTo(borderArgs);
    } else {
        borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
    }

    if (radius2[0] > 0 || radius2[1] > 0) {
        borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
        outer2[0].curveTo(borderArgs);
        borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
        inner2[0].curveToReversed(borderArgs);
    } else {
        borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]);
        borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]);
    }

    if (radius1[0] > 0 || radius1[1] > 0) {
        borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
        inner1[1].curveToReversed(borderArgs);
    } else {
        borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]);
    }

    return borderArgs;
}

function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
    if (radius1[0] > 0 || radius1[1] > 0) {
        borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
        corner1[0].curveTo(borderArgs);
        corner1[1].curveTo(borderArgs);
    } else {
        borderArgs.push(["line", x, y]);
    }

    if (radius2[0] > 0 || radius2[1] > 0) {
        borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
    }
}

function negativeZIndex(container) {
    return container.cssInt("zIndex") < 0;
}

function positiveZIndex(container) {
    return container.cssInt("zIndex") > 0;
}

function zIndex0(container) {
    return container.cssInt("zIndex") === 0;
}

function inlineLevel(container) {
    return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
}

function isStackingContext(container) {
    return (container instanceof StackingContext);
}

function hasText(container) {
    return container.node.data.trim().length > 0;
}

function noLetterSpacing(container) {
    return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing")));
}

function getBorderRadiusData(container) {
    return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
        var value = container.css('border' + side + 'Radius');
        var arr = value.split(" ");
        if (arr.length <= 1) {
            arr[1] = arr[0];
        }
        return arr.map(asInt);
    });
}

function renderableNode(node) {
    return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);
}

function isPositionedForStacking(container) {
    var position = container.css("position");
    var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto";
    return zIndex !== "auto";
}

function isPositioned(container) {
    return container.css("position") !== "static";
}

function isFloating(container) {
    return container.css("float") !== "none";
}

function isInlineBlock(container) {
    return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
}

function not(callback) {
    var context = this;
    return function() {
        return !callback.apply(context, arguments);
    };
}

function isElement(container) {
    return container.node.nodeType === Node.ELEMENT_NODE;
}

function isPseudoElement(container) {
    return container.isPseudoElement === true;
}

function isTextNode(container) {
    return container.node.nodeType === Node.TEXT_NODE;
}

function zIndexSort(contexts) {
    return function(a, b) {
        return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length));
    };
}

function hasOpacity(container) {
    return container.getOpacity() < 1;
}

function bind(callback, context) {
    return function() {
        return callback.apply(context, arguments);
    };
}

function asInt(value) {
    return parseInt(value, 10);
}

function getWidth(border) {
    return border.width;
}

function nonIgnoredElement(nodeContainer) {
    return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1);
}

function flatten(arrays) {
    return [].concat.apply([], arrays);
}

function stripQuotes(content) {
    var first = content.substr(0, 1);
    return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content;
}

function getWords(characters) {
    var words = [], i = 0, onWordBoundary = false, word;
    while(characters.length) {
        if (isWordBoundary(characters[i]) === onWordBoundary) {
            word = characters.splice(0, i);
            if (word.length) {
                words.push(window.html2canvas.punycode.ucs2.encode(word));
            }
            onWordBoundary =! onWordBoundary;
            i = 0;
        } else {
            i++;
        }

        if (i >= characters.length) {
            word = characters.splice(0, i);
            if (word.length) {
                words.push(window.html2canvas.punycode.ucs2.encode(word));
            }
        }
    }
    return words;
}

function isWordBoundary(characterCode) {
    return [
        32, // <space>
        13, // \r
        10, // \n
        9, // \t
        45 // -
    ].indexOf(characterCode) !== -1;
}

function hasUnicode(string) {
    return (/[^\u0000-\u00ff]/).test(string);
}

function Proxy(src, proxyUrl, document) {
    if (!proxyUrl) {
        return Promise.reject("No proxy configured");
    }
    var callback = createCallback(supportsCORS);
    var url = createProxyUrl(proxyUrl, src, callback);

    return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {
        return decode64(response.content);
    }));
}
var proxyCount = 0;

var supportsCORS = ('withCredentials' in new XMLHttpRequest());
var supportsCORSImage = ('crossOrigin' in new Image());

function ProxyURL(src, proxyUrl, document) {
    var callback = createCallback(supportsCORSImage);
    var url = createProxyUrl(proxyUrl, src, callback);
    return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
        return "data:" + response.type + ";base64," + response.content;
    }));
}

function jsonp(document, url, callback) {
    return new Promise(function(resolve, reject) {
        var s = document.createElement("script");
        var cleanup = function() {
            delete window.html2canvas.proxy[callback];
            document.body.removeChild(s);
        };
        window.html2canvas.proxy[callback] = function(response) {
            cleanup();
            resolve(response);
        };
        s.src = url;
        s.onerror = function(e) {
            cleanup();
            reject(e);
        };
        document.body.appendChild(s);
    });
}

function createCallback(useCORS) {
    return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : "";
}

function createProxyUrl(proxyUrl, src, callback) {
    return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
}

function ProxyImageContainer(src, proxy) {
    var script = document.createElement("script");
    var link = document.createElement("a");
    link.href = src;
    src = link.href;
    this.src = src;
    this.image = new Image();
    var self = this;
    this.promise = new Promise(function(resolve, reject) {
        self.image.crossOrigin = "Anonymous";
        self.image.onload = resolve;
        self.image.onerror = reject;

        new ProxyURL(src, proxy, document).then(function(url) {
            self.image.src = url;
        })['catch'](reject);
    });
}

function PseudoElementContainer(node, parent, type) {
    NodeContainer.call(this, node, parent);
    this.isPseudoElement = true;
    this.before = type === ":before";
}

PseudoElementContainer.prototype.cloneTo = function(stack) {
    PseudoElementContainer.prototype.cloneTo.call(this, stack);
    stack.isPseudoElement = true;
    stack.before = this.before;
};

PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);

PseudoElementContainer.prototype.appendToDOM = function() {
    if (this.before) {
        this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
    } else {
        this.parent.node.appendChild(this.node);
    }
    this.parent.node.className += " " + this.getHideClass();
};

PseudoElementContainer.prototype.cleanDOM = function() {
    this.node.parentNode.removeChild(this.node);
    this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
};

PseudoElementContainer.prototype.getHideClass = function() {
    return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
};

PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";

function Renderer(width, height, images, options, document) {
    this.width = width;
    this.height = height;
    this.images = images;
    this.options = options;
    this.document = document;
}

Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {
    var paddingLeft = container.cssInt('paddingLeft'),
        paddingTop = container.cssInt('paddingTop'),
        paddingRight = container.cssInt('paddingRight'),
        paddingBottom = container.cssInt('paddingBottom'),
        borders = borderData.borders;

    var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);
    var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);
    this.drawImage(
        imageContainer,
        0,
        0,
        imageContainer.image.width || width,
        imageContainer.image.height || height,
        bounds.left + paddingLeft + borders[3].width,
        bounds.top + paddingTop + borders[0].width,
        width,
        height
    );
};

Renderer.prototype.renderBackground = function(container, bounds, borderData) {
    if (bounds.height > 0 && bounds.width > 0) {
        this.renderBackgroundColor(container, bounds);
        this.renderBackgroundImage(container, bounds, borderData);
    }
};

Renderer.prototype.renderBackgroundColor = function(container, bounds) {
    var color = container.color("backgroundColor");
    if (!color.isTransparent()) {
        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
    }
};

Renderer.prototype.renderBorders = function(borders) {
    borders.forEach(this.renderBorder, this);
};

Renderer.prototype.renderBorder = function(data) {
    if (!data.color.isTransparent() && data.args !== null) {
        this.drawShape(data.args, data.color);
    }
};

Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {
    var backgroundImages = container.parseBackgroundImages();
    backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
        switch(backgroundImage.method) {
        case "url":
            var image = this.images.get(backgroundImage.args[0]);
            if (image) {
                this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
            } else {
                log("Error loading background-image", backgroundImage.args[0]);
            }
            break;
        case "linear-gradient":
        case "gradient":
            var gradientImage = this.images.get(backgroundImage.value);
            if (gradientImage) {
                this.renderBackgroundGradient(gradientImage, bounds, borderData);
            } else {
                log("Error loading background-image", backgroundImage.args[0]);
            }
            break;
        case "none":
            break;
        default:
            log("Unknown background-image type", backgroundImage.args[0]);
        }
    }, this);
};

Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {
    var size = container.parseBackgroundSize(bounds, imageContainer.image, index);
    var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);
    var repeat = container.parseBackgroundRepeat(index);
    switch (repeat) {
    case "repeat-x":
    case "repeat no-repeat":
        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);
        break;
    case "repeat-y":
    case "no-repeat repeat":
        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);
        break;
    case "no-repeat":
        this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);
        break;
    default:
        this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);
        break;
    }
};

function StackingContext(hasOwnStacking, opacity, element, parent) {
    NodeContainer.call(this, element, parent);
    this.ownStacking = hasOwnStacking;
    this.contexts = [];
    this.children = [];
    this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;
}

StackingContext.prototype = Object.create(NodeContainer.prototype);

StackingContext.prototype.getParentStack = function(context) {
    var parentStack = (this.parent) ? this.parent.stack : null;
    return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
};

function Support(document) {
    this.rangeBounds = this.testRangeBounds(document);
    this.cors = this.testCORS();
    this.svg = this.testSVG();
}

Support.prototype.testRangeBounds = function(document) {
    var range, testElement, rangeBounds, rangeHeight, support = false;

    if (document.createRange) {
        range = document.createRange();
        if (range.getBoundingClientRect) {
            testElement = document.createElement('boundtest');
            testElement.style.height = "123px";
            testElement.style.display = "block";
            document.body.appendChild(testElement);

            range.selectNode(testElement);
            rangeBounds = range.getBoundingClientRect();
            rangeHeight = rangeBounds.height;

            if (rangeHeight === 123) {
                support = true;
            }
            document.body.removeChild(testElement);
        }
    }

    return support;
};

Support.prototype.testCORS = function() {
    return typeof((new Image()).crossOrigin) !== "undefined";
};

Support.prototype.testSVG = function() {
    var img = new Image();
    var canvas = document.createElement("canvas");
    var ctx =  canvas.getContext("2d");
    img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";

    try {
        ctx.drawImage(img, 0, 0);
        canvas.toDataURL();
    } catch(e) {
        return false;
    }
    return true;
};

function SVGContainer(src) {
    this.src = src;
    this.image = null;
    var self = this;

    this.promise = this.hasFabric().then(function() {
        return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
    }).then(function(svg) {
        return new Promise(function(resolve) {
            html2canvas.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
        });
    });
}

SVGContainer.prototype.hasFabric = function() {
    return !html2canvas.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
};

SVGContainer.prototype.inlineFormatting = function(src) {
    return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);
};

SVGContainer.prototype.removeContentType = function(src) {
    return src.replace(/^data:image\/svg\+xml(;base64)?,/,'');
};

SVGContainer.prototype.isInline = function(src) {
    return (/^data:image\/svg\+xml/i.test(src));
};

SVGContainer.prototype.createCanvas = function(resolve) {
    var self = this;
    return function (objects, options) {
        var canvas = new html2canvas.fabric.StaticCanvas('c');
        self.image = canvas.lowerCanvasEl;
        canvas
            .setWidth(options.width)
            .setHeight(options.height)
            .add(html2canvas.fabric.util.groupSVGElements(objects, options))
            .renderAll();
        resolve(canvas.lowerCanvasEl);
    };
};

SVGContainer.prototype.decode64 = function(str) {
    return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
};

/*
 * base64-arraybuffer
 * https://github.com/niklasvh/base64-arraybuffer
 *
 * Copyright (c) 2012 Niklas von Hertzen
 * Licensed under the MIT license.
 */

function decode64(base64) {
    var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;

    var output = "";

    for (i = 0; i < len; i+=4) {
        encoded1 = chars.indexOf(base64[i]);
        encoded2 = chars.indexOf(base64[i+1]);
        encoded3 = chars.indexOf(base64[i+2]);
        encoded4 = chars.indexOf(base64[i+3]);

        byte1 = (encoded1 << 2) | (encoded2 >> 4);
        byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
        byte3 = ((encoded3 & 3) << 6) | encoded4;
        if (encoded3 === 64) {
            output += String.fromCharCode(byte1);
        } else if (encoded4 === 64 || encoded4 === -1) {
            output += String.fromCharCode(byte1, byte2);
        } else{
            output += String.fromCharCode(byte1, byte2, byte3);
        }
    }

    return output;
}

function SVGNodeContainer(node, native) {
    this.src = node;
    this.image = null;
    var self = this;

    this.promise = native ? new Promise(function(resolve, reject) {
        self.image = new Image();
        self.image.onload = resolve;
        self.image.onerror = reject;
        self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
        if (self.image.complete === true) {
            resolve(self.image);
        }
    }) : this.hasFabric().then(function() {
        return new Promise(function(resolve) {
            html2canvas.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
        });
    });
}

SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);

function TextContainer(node, parent) {
    NodeContainer.call(this, node, parent);
}

TextContainer.prototype = Object.create(NodeContainer.prototype);

TextContainer.prototype.applyTextTransform = function() {
    this.node.data = this.transform(this.parent.css("textTransform"));
};

TextContainer.prototype.transform = function(transform) {
    var text = this.node.data;
    switch(transform){
        case "lowercase":
            return text.toLowerCase();
        case "capitalize":
            return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
        case "uppercase":
            return text.toUpperCase();
        default:
            return text;
    }
};

function capitalize(m, p1, p2) {
    if (m.length > 0) {
        return p1 + p2.toUpperCase();
    }
}

function WebkitGradientContainer(imageData) {
    GradientContainer.apply(this, arguments);
    this.type = (imageData.args[0] === "linear") ? this.TYPES.LINEAR : this.TYPES.RADIAL;
}

WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);

function XHR(url) {
    return new Promise(function(resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);

        xhr.onload = function() {
            if (xhr.status === 200) {
                resolve(xhr.responseText);
            } else {
                reject(new Error(xhr.statusText));
            }
        };

        xhr.onerror = function() {
            reject(new Error("Network Error"));
        };

        xhr.send();
    });
}

function CanvasRenderer(width, height) {
    Renderer.apply(this, arguments);
    this.canvas = this.options.canvas || this.document.createElement("canvas");
    if (!this.options.canvas) {
        this.canvas.width = width;
        this.canvas.height = height;
    }
    this.ctx = this.canvas.getContext("2d");
    this.taintCtx = this.document.createElement("canvas").getContext("2d");
    this.ctx.textBaseline = "bottom";
    this.variables = {};
    log("Initialized CanvasRenderer with size", width, "x", height);
}

CanvasRenderer.prototype = Object.create(Renderer.prototype);

CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
    this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;
    return this.ctx;
};

CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
    this.setFillStyle(color).fillRect(left, top, width, height);
};

CanvasRenderer.prototype.circle = function(left, top, size, color) {
    this.setFillStyle(color);
    this.ctx.beginPath();
    this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);
    this.ctx.closePath();
    this.ctx.fill();
};

CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {
    this.circle(left, top, size, color);
    this.ctx.strokeStyle = strokeColor.toString();
    this.ctx.stroke();
};

CanvasRenderer.prototype.drawShape = function(shape, color) {
    this.shape(shape);
    this.setFillStyle(color).fill();
};

CanvasRenderer.prototype.taints = function(imageContainer) {
    if (imageContainer.tainted === null) {
        this.taintCtx.drawImage(imageContainer.image, 0, 0);
        try {
            this.taintCtx.getImageData(0, 0, 1, 1);
            imageContainer.tainted = false;
        } catch(e) {
            this.taintCtx = document.createElement("canvas").getContext("2d");
            imageContainer.tainted = true;
        }
    }

    return imageContainer.tainted;
};

CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {
    if (!this.taints(imageContainer) || this.options.allowTaint) {
        this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);
    }
};

CanvasRenderer.prototype.clip = function(shapes, callback, context) {
    this.ctx.save();
    shapes.filter(hasEntries).forEach(function(shape) {
        this.shape(shape).clip();
    }, this);
    callback.call(context);
    this.ctx.restore();
};

CanvasRenderer.prototype.shape = function(shape) {
    this.ctx.beginPath();
    shape.forEach(function(point, index) {
        if (point[0] === "rect") {
            this.ctx.rect.apply(this.ctx, point.slice(1));
        } else {
            this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
        }
    }, this);
    this.ctx.closePath();
    return this.ctx;
};

CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
    this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0];
};

CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {
    this.setVariable("shadowColor", color.toString())
        .setVariable("shadowOffsetY", offsetX)
        .setVariable("shadowOffsetX", offsetY)
        .setVariable("shadowBlur", blur);
};

CanvasRenderer.prototype.clearShadow = function() {
    this.setVariable("shadowColor", "rgba(0,0,0,0)");
};

CanvasRenderer.prototype.setOpacity = function(opacity) {
    this.ctx.globalAlpha = opacity;
};

CanvasRenderer.prototype.setTransform = function(transform) {
    this.ctx.translate(transform.origin[0], transform.origin[1]);
    this.ctx.transform.apply(this.ctx, transform.matrix);
    this.ctx.translate(-transform.origin[0], -transform.origin[1]);
};

CanvasRenderer.prototype.setVariable = function(property, value) {
    if (this.variables[property] !== value) {
        this.variables[property] = this.ctx[property] = value;
    }

    return this;
};

CanvasRenderer.prototype.text = function(text, left, bottom) {
    this.ctx.fillText(text, left, bottom);
};

CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {
    var shape = [
        ["line", Math.round(left), Math.round(top)],
        ["line", Math.round(left + width), Math.round(top)],
        ["line", Math.round(left + width), Math.round(height + top)],
        ["line", Math.round(left), Math.round(height + top)]
    ];
    this.clip([shape], function() {
        this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);
    }, this);
};

CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {
    var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);
    this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat"));
    this.ctx.translate(offsetX, offsetY);
    this.ctx.fill();
    this.ctx.translate(-offsetX, -offsetY);
};

CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
    if (gradientImage instanceof LinearGradientContainer) {
        var gradient = this.ctx.createLinearGradient(
            bounds.left + bounds.width * gradientImage.x0,
            bounds.top + bounds.height * gradientImage.y0,
            bounds.left +  bounds.width * gradientImage.x1,
            bounds.top +  bounds.height * gradientImage.y1);
        gradientImage.colorStops.forEach(function(colorStop) {
            gradient.addColorStop(colorStop.stop, colorStop.color.toString());
        });
        this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);
    }
};

CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
    var image = imageContainer.image;
    if(image.width === size.width && image.height === size.height) {
        return image;
    }

    var ctx, canvas = document.createElement('canvas');
    canvas.width = size.width;
    canvas.height = size.height;
    ctx = canvas.getContext("2d");
    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );
    return canvas;
};

function hasEntries(array) {
    return array.length > 0;
}

}).call({}, typeof(window) !== "undefined" ? window : undefined, typeof(document) !== "undefined" ? document : undefined);
/*!
 * jquery.confirm
 *
 * @version 2.0.1
 *
 * @author My C-Labs
 * @author Matthieu Napoli <matthieu@mnapoli.fr>
 * @author Russel Vela
 *
 * @license MIT
 * @url http://myclabs.github.io/jquery.confirm/
 */
(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);

/*

jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser, jQuery
Copyright (c) 2012 2012 Willow Systems Corporation, willow-systems.com
 jsPDF 0.9.0rc1 ( 2013-04-07T16:52 commit ID d95d8f69915bb999f6704e8021108e2e755bd868 )
Copyright (c) 2010-2012 James Hall, james@snapshotmedia.co.uk, https://github.com/MrRio/jsPDF
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
MIT license.

            -----------------------------------------------------------------------------------------------
            JavaScript PubSub library
            2012 (c) ddotsenko@willowsystems.com
            based on Peter Higgins (dante@dojotoolkit.org)
            Loosely based on Dojo publish/subscribe API, limited in scope. Rewritten blindly.
            Original is (c) Dojo Foundation 2004-2010. Released under either AFL or new BSD, see:
            http://dojofoundation.org/license for more information.
            -----------------------------------------------------------------------------------------------
 
jsPDF addImage plugin (JPEG only at this time)
Copyright (c) 2012 https://github.com/siefkenj/

jsPDF Silly SVG plugin
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
 
jsPDF split_text_to_size plugin
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
MIT license.
 
jsPDF standard_fonts_metrics plugin
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
MIT license.
*/
var 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),
B,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),
!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);
p.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.");
return 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+=
String.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>>"),
l("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("<<");l("/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 ("+
t(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-
a.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));
for(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;
else 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,
" "))},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),
void 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,
h,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};
D.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-
1)*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=
function(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&&
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),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),
v(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");
w=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"===
typeof 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;
for(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(""),
e,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++)),
a="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)&&
d++;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=
this.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}();
(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&&
a("/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;
d.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,",
"")));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");
C=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);
0===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);
(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()],
F=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"]=
k(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,
a);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");
return{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(),
k]);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=
d-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"]||
0))*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()};
b.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",
oblique:"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);$('<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=
new b(this,d,e,h);g(a,d,h.elementHandlers);return d.dispose()}})(jsPDF.API);
(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",
0);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=
h[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);
(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,
e,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),
m+=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/
a;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);
(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"],
WinAnsiEncoding: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'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'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}}}"),
"Helvetica-Bold":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'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}}}"),
Courier: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}}}"),
Helvetica:b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'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}}}"),
"Helvetica-BoldOblique":b("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'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}}}"),
"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}fv{17su5tu5qs}fw{17su5tu5qs}}}"),
"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}}}"),
"Helvetica-Oblique":b("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'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}}}")}};
f.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);
var 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(" "),
j=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):
b+","+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)):
"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=
saveAs||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,
c){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"])},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",
!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=
c.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=
c.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,
Z_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,
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,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,
21,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,
28,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];
function 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],
b.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]=
d,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]++;
j=0;do j|=h&1,h>>>=1,j<<=1;while(0<--p);g[d]=j>>>1}}}
Tree._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,
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,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];
Tree.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}
StaticTree.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,
8,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,
9,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,
48,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);
StaticTree.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}
var 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=
113,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]}
function 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++]=
a}function 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=
3):(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+
2*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=
0<=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*
Tree.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=
65535,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=
a,!(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-
1)]&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=
1,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]=
c[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=
0;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;
w=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||
z!=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=
z_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&&
z!=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+=
J,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,
StaticTree.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}
ZStream.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,
f,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+=
f,this.avail_out-=f,this.dstate.pending-=f,0===this.dstate.pending&&(this.dstate.pending_out=0))}};
function 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&&
(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);
e.forEach(function(a){k.set(a,f);f+=a.length});return k}}
void 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))};
var 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=
p;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
p))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&&
(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.");
b=new Uint8Array(b);return a(1,b)});return g});

!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();t(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);
(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,prepend: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);

