PageSourceSearch

https://www.primariacovasna.ro/fileadmin/templates/js/holder.js?1456604474

js primariacovasna.ro collected 2026-10-02 22:43:26 UTC 139,909 bytes, 4,846 lines download raw bytes

vendor: 57,586 bytes, lines 1-1763
1/*!
2
3Holder - client side image placeholders
4Version 2.9.2+30qun
5© 2016 Ivan Malopinsky - http://imsky.co
6
7Site:     http://holderjs.com
8Issues:   https://github.com/imsky/holder/issues
9License:  MIT
10
11*/
12(function (window) {
13  if (!window.document) return;
14  var document = window.document;
15
16  //https://github.com/inexorabletash/polyfill/blob/master/web.js
17    if (!document.querySelectorAll) {
18      document.querySelectorAll = function (selectors) {
19        var style = document.createElement('style'), elements = [], element;
20        document.documentElement.firstChild.appendChild(style);
21        document._qsa = [];
22
23        style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
24        window.scrollBy(0, 0);
25        style.parentNode.removeChild(style);
26
27        while (document._qsa.length) {
28          element = document._qsa.shift();
29          element.style.removeAttribute('x-qsa');
30          elements.push(element);
31        }
32        document._qsa = null;
33        return elements;
34      };
35    }
36
37    if (!document.querySelector) {
38      document.querySelector = function (selectors) {
39        var elements = document.querySelectorAll(selectors);
40        return (elements.length) ? elements[0] : null;
41      };
42    }
43
44    if (!document.getElementsByClassName) {
45      document.getElementsByClassName = function (classNames) {
46        classNames = String(classNames).replace(/^|\s+/g, '.');
47        return document.querySelectorAll(classNames);
48      };
49    }
50
51  //https://github.com/inexorabletash/polyfill
52  // ES5 15.2.3.14 Object.keys ( O )
53  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys
54  if (!Object.keys) {
55    Object.keys = function (o) {
56      if (o !== Object(o)) { throw TypeError('Object.keys called on non-object'); }
57      var ret = [], p;
58      for (p in o) {
59        if (Object.prototype.hasOwnProperty.call(o, p)) {
60          ret.push(p);
61        }
62      }
63      return ret;
64    };
65  }
66
67  // ES5 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
68  // From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach
69  if (!Array.prototype.forEach) {
70    Array.prototype.forEach = function (fun /*, thisp */) {
71      if (this === void 0 || this === null) { throw TypeError(); }
72
73      var t = Object(this);
74      var len = t.length >>> 0;
75      if (typeof fun !== "function") { throw TypeError(); }
76
77      var thisp = arguments[1], i;
78      for (i = 0; i < len; i++) {
79        if (i in t) {
80          fun.call(thisp, t[i], i, t);
81        }
82      }
83    };
84  }
85
86  //https://github.com/inexorabletash/polyfill/blob/master/web.js
87  (function (global) {
88    var B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
89    global.atob = global.atob || function (input) {
90      input = String(input);
91      var position = 0,
92          output = [],
93          buffer = 0, bits = 0, n;
94
95      input = input.replace(/\s/g, '');
96      if ((input.length % 4) === 0) { input = input.replace(/=+$/, ''); }
97      if ((input.length % 4) === 1) { throw Error('InvalidCharacterError'); }
98      if (/[^+/0-9A-Za-z]/.test(input)) { throw Error('InvalidCharacterError'); }
99
100      while (position < input.length) {
101        n = B64_ALPHABET.indexOf(input.charAt(position));
102        buffer = (buffer << 6) | n;
103        bits += 6;
104
105        if (bits === 24) {
106          output.push(String.fromCharCode((buffer >> 16) & 0xFF));
107          output.push(String.fromCharCode((buffer >>  8) & 0xFF));
108          output.push(String.fromCharCode(buffer & 0xFF));
109          bits = 0;
110          buffer = 0;
111        }
112        position += 1;
113      }
114
115      if (bits === 12) {
116        buffer = buffer >> 4;
117        output.push(String.fromCharCode(buffer & 0xFF));
118      } else if (bits === 18) {
119        buffer = buffer >> 2;
120        output.push(String.fromCharCode((buffer >> 8) & 0xFF));
121        output.push(String.fromCharCode(buffer & 0xFF));
122      }
123
124      return output.join('');
125    };
126
127    global.btoa = global.btoa || function (input) {
128      input = String(input);
129      var position = 0,
130          out = [],
131          o1, o2, o3,
132          e1, e2, e3, e4;
133
134      if (/[^\x00-\xFF]/.test(input)) { throw Error('InvalidCharacterError'); }
135
136      while (position < input.length) {
137        o1 = input.charCodeAt(position++);
138        o2 = input.charCodeAt(position++);
139        o3 = input.charCodeAt(position++);
140
141        // 111111 112222 222233 333333
142        e1 = o1 >> 2;
143        e2 = ((o1 & 0x3) << 4) | (o2 >> 4);
144        e3 = ((o2 & 0xf) << 2) | (o3 >> 6);
145        e4 = o3 & 0x3f;
146
147        if (position === input.length + 2) {
148          e3 = 64; e4 = 64;
149        }
150        else if (position === input.length + 1) {
151          e4 = 64;
152        }
153
154        out.push(B64_ALPHABET.charAt(e1),
155                 B64_ALPHABET.charAt(e2),
156                 B64_ALPHABET.charAt(e3),
157                 B64_ALPHABET.charAt(e4));
158      }
159
160      return out.join('');
161    };
162  }(window));
163
164  //https://gist.github.com/jimeh/332357
165  if (!Object.prototype.hasOwnProperty){
166      /*jshint -W001, -W103 */
167      Object.prototype.hasOwnProperty = function(prop) {
168      var proto = this.__proto__ || this.constructor.prototype;
169      return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]);
170    };
171      /*jshint +W001, +W103 */
172  }
173
174  // @license http://opensource.org/licenses/MIT
175  // copyright Paul Irish 2015
176
177
178  // Date.now() is supported everywhere except IE8. For IE8 we use the Date.now polyfill
179  //   github.com/Financial-Times/polyfill-service/blob/master/polyfills/Date.now/polyfill.js
180  // as Safari 6 doesn't have support for NavigationTiming, we use a Date.now() timestamp for relative values
181
182  // if you want values similar to what you'd get with real perf.now, place this towards the head of the page
183  // but in reality, you're just getting the delta between now() calls, so it's not terribly important where it's placed
184
185
186  (function(){
187
188    if ('performance' in window === false) {
189        window.performance = {};
190    }
191    
192    Date.now = (Date.now || function () {  // thanks IE8
193      return new Date().getTime();
194    });
195
196    if ('now' in window.performance === false){
197      
198      var nowOffset = Date.now();
199      
200      if (performance.timing && performance.timing.navigationStart){
201        nowOffset = performance.timing.navigationStart;
202      }
203
204      window.performance.now = function now(){
205        return Date.now() - nowOffset;
206      };
207    }
208
209  })();
210
211  //requestAnimationFrame polyfill for older Firefox/Chrome versions
212  if (!window.requestAnimationFrame) {
213    if (window.webkitRequestAnimationFrame && window.webkitCancelAnimationFrame) {
214    //https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/requestAnimationFrame/polyfill-webkit.js
215    (function (global) {
216      global.requestAnimationFrame = function (callback) {
217        return webkitRequestAnimationFrame(function () {
218          callback(global.performance.now());
219        });
220      };
221
222      global.cancelAnimationFrame = global.webkitCancelAnimationFrame;
223    }(window));
224    } else if (window.mozRequestAnimationFrame && window.mozCancelAnimationFrame) {
225      //https://github.com/Financial-Times/polyfill-service/blob/master/polyfills/requestAnimationFrame/polyfill-moz.js
226    (function (global) {
227      global.requestAnimationFrame = function (callback) {
228        return mozRequestAnimationFrame(function () {
229          callback(global.performance.now());
230        });
231      };
232
233      global.cancelAnimationFrame = global.mozCancelAnimationFrame;
234    }(window));
235    } else {
236    (function (global) {
237      global.requestAnimationFrame = function (callback) {
238        return global.setTimeout(callback, 1000 / 60);
239      };
240
241      global.cancelAnimationFrame = global.clearTimeout;
242    })(window);
243    }
244  }
245})(this);
246
247(function webpackUniversalModuleDefinition(root, factory) {
248	if(typeof exports === 'object' && typeof module === 'object')
249		module.exports = factory();
250	else if(typeof define === 'function' && define.amd)
251		define([], factory);
252	else if(typeof exports === 'object')
253		exports["Holder"] = factory();
254	else
255		root["Holder"] = factory();
256})(this, function() {
257return /******/ (function(modules) { // webpackBootstrap
258/******/ 	// The module cache
259/******/ 	var installedModules = {};
260
261/******/ 	// The require function
262/******/ 	function __webpack_require__(moduleId) {
263
264/******/ 		// Check if module is in cache
265/******/ 		if(installedModules[moduleId])
266/******/ 			return installedModules[moduleId].exports;
267
268/******/ 		// Create a new module (and put it into the cache)
269/******/ 		var module = installedModules[moduleId] = {
270/******/ 			exports: {},
271/******/ 			id: moduleId,
272/******/ 			loaded: false
273/******/ 		};
274
275/******/ 		// Execute the module function
276/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
277
278/******/ 		// Flag the module as loaded
279/******/ 		module.loaded = true;
280
281/******/ 		// Return the exports of the module
282/******/ 		return module.exports;
283/******/ 	}
284
285
286/******/ 	// expose the modules object (__webpack_modules__)
287/******/ 	__webpack_require__.m = modules;
288
289/******/ 	// expose the module cache
290/******/ 	__webpack_require__.c = installedModules;
291
292/******/ 	// __webpack_public_path__
293/******/ 	__webpack_require__.p = "";
294
295/******/ 	// Load entry module and return exports
296/******/ 	return __webpack_require__(0);
297/******/ })
298/************************************************************************/
299/******/ ([
300/* 0 */
301/***/ function(module, exports, __webpack_require__) {
302
303	/*
304	Holder.js - client side image placeholders
305	(c) 2012-2015 Ivan Malopinsky - http://imsky.co
306	*/
307
308	module.exports = __webpack_require__(1);
309
310
311/***/ },
312/* 1 */
313/***/ function(module, exports, __webpack_require__) {
314
315	/* WEBPACK VAR INJECTION */(function(global) {/*
316	Holder.js - client side image placeholders
317	(c) 2012-2015 Ivan Malopinsky - http://imsky.co
318	*/
319
320	//Libraries and functions
321	var onDomReady = __webpack_require__(2);
322	var querystring = __webpack_require__(3);
323
324	var SceneGraph = __webpack_require__(10);
325	var utils = __webpack_require__(11);
326	var SVG = __webpack_require__(12);
327	var DOM = __webpack_require__(13);
328	var Color = __webpack_require__(14);
329	var constants = __webpack_require__(15);
330
331	var svgRenderer = __webpack_require__(16);
332	var sgCanvasRenderer = __webpack_require__(19);
333
334	var extend = utils.extend;
335	var dimensionCheck = utils.dimensionCheck;
336
337	//Constants and definitions
338	var SVG_NS = constants.svg_ns;
339
340	var Holder = {
341	    version: constants.version,
342
343	    /**
344	     * Adds a theme to default settings
345	     *
346	     * @param {string} name Theme name
347	     * @param {Object} theme Theme object, with foreground, background, size, font, and fontweight properties.
348	     */
349	    addTheme: function(name, theme) {
350	        name != null && theme != null && (App.settings.themes[name] = theme);
351	        delete App.vars.cache.themeKeys;
352	        return this;
353	    },
354
355	    /**
356	     * Appends a placeholder to an element
357	     *
358	     * @param {string} src Placeholder URL string
359	     * @param el A selector or a reference to a DOM node
360	     */
361	    addImage: function(src, el) {
362	        //todo: use jquery fallback if available for all QSA references
363	        var nodes = DOM.getNodeArray(el);
364	        nodes.forEach(function (node) {
365	            var img = DOM.newEl('img');
366	            var domProps = {};
367	            domProps[App.setup.dataAttr] = src;
368	            DOM.setAttr(img, domProps);
369	            node.appendChild(img);
370	        });
371	        return this;
372	    },
373
374	    /**
375	     * Sets whether or not an image is updated on resize.
376	     * If an image is set to be updated, it is immediately rendered.
377	     *
378	     * @param {Object} el Image DOM element
379	     * @param {Boolean} value Resizable update flag value
380	     */
381	    setResizeUpdate: function(el, value) {
382	        if (el.holderData) {
383	            el.holderData.resizeUpdate = !!value;
384	            if (el.holderData.resizeUpdate) {
385	                updateResizableElements(el);
386	            }
387	        }
388	    },
389
390	    /**
391	     * Runs Holder with options. By default runs Holder on all images with "holder.js" in their source attributes.
392	     *
393	     * @param {Object} userOptions Options object, can contain domain, themes, images, and bgnodes properties
394	     */
395	    run: function(userOptions) {
396	        //todo: split processing into separate queues
397	        userOptions = userOptions || {};
398	        var engineSettings = {};
399	        var options = extend(App.settings, userOptions);
400
401	        App.vars.preempted = true;
402	        App.vars.dataAttr = options.dataAttr || App.setup.dataAttr;
403
404	        engineSettings.renderer = options.renderer ? options.renderer : App.setup.renderer;
405	        if (App.setup.renderers.join(',').indexOf(engineSettings.renderer) === -1) {
406	            engineSettings.renderer = App.setup.supportsSVG ? 'svg' : (App.setup.supportsCanvas ? 'canvas' : 'html');
407	        }
408
409	        var images = DOM.getNodeArray(options.images);
410	        var bgnodes = DOM.getNodeArray(options.bgnodes);
411	        var stylenodes = DOM.getNodeArray(options.stylenodes);
412	        var objects = DOM.getNodeArray(options.objects);
413
414	        engineSettings.stylesheets = [];
415	        engineSettings.svgXMLStylesheet = true;
416	        engineSettings.noFontFallback = options.noFontFallback ? options.noFontFallback : false;
417
418	        stylenodes.forEach(function (styleNode) {
419	            if (styleNode.attributes.rel && styleNode.attributes.href && styleNode.attributes.rel.value == 'stylesheet') {
420	                var href = styleNode.attributes.href.value;
421	                //todo: write isomorphic relative-to-absolute URL function
422	                var proxyLink = DOM.newEl('a');
423	                proxyLink.href = href;
424	                var stylesheetURL = proxyLink.protocol + '//' + proxyLink.host + proxyLink.pathname + proxyLink.search;
425	                engineSettings.stylesheets.push(stylesheetURL);
426	            }
427	        });
428
429	        bgnodes.forEach(function (bgNode) {
430	            //Skip processing background nodes if getComputedStyle is unavailable, since only modern browsers would be able to use canvas or SVG to render to background
431	            if (!global.getComputedStyle) return;
432	            var backgroundImage = global.getComputedStyle(bgNode, null).getPropertyValue('background-image');
433	            var dataBackgroundImage = bgNode.getAttribute('data-background-src');
434	            var rawURL = dataBackgroundImage || backgroundImage;
435
436	            var holderURL = null;
437	            var holderString = options.domain + '/';
438	            var holderStringIndex = rawURL.indexOf(holderString);
439
440	            if (holderStringIndex === 0) {
441	                holderURL = rawURL;
442	            } else if (holderStringIndex === 1 && rawURL[0] === '?') {
443	                holderURL = rawURL.slice(1);
444	            } else {
445	                var fragment = rawURL.substr(holderStringIndex).match(/([^\"]*)"?\)/);
446	                if (fragment !== null) {
447	                    holderURL = fragment[1];
448	                } else if (rawURL.indexOf('url(') === 0) {
449	                    throw 'Holder: unable to parse background URL: ' + rawURL;
450	                }
451	            }
452
453	            if (holderURL != null) {
454	                var holderFlags = parseURL(holderURL, options);
455	                if (holderFlags) {
456	                    prepareDOMElement({
457	                        mode: 'background',
458	                        el: bgNode,
459	                        flags: holderFlags,
460	                        engineSettings: engineSettings
461	                    });
462	                }
463	            }
464	        });
465
466	        objects.forEach(function (object) {
467	            var objectAttr = {};
468
469	            try {
470	                objectAttr.data = object.getAttribute('data');
471	                objectAttr.dataSrc = object.getAttribute(App.vars.dataAttr);
472	            } catch (e) {}
473
474	            var objectHasSrcURL = objectAttr.data != null && objectAttr.data.indexOf(options.domain) === 0;
475	            var objectHasDataSrcURL = objectAttr.dataSrc != null && objectAttr.dataSrc.indexOf(options.domain) === 0;
476
477	            if (objectHasSrcURL) {
478	                prepareImageElement(options, engineSettings, objectAttr.data, object);
479	            } else if (objectHasDataSrcURL) {
480	                prepareImageElement(options, engineSettings, objectAttr.dataSrc, object);
481	            }
482	        });
483
484	        images.forEach(function (image) {
485	            var imageAttr = {};
486
487	            try {
488	                imageAttr.src = image.getAttribute('src');
489	                imageAttr.dataSrc = image.getAttribute(App.vars.dataAttr);
490	                imageAttr.rendered = image.getAttribute('data-holder-rendered');
491	            } catch (e) {}
492
493	            var imageHasSrc = imageAttr.src != null;
494	            var imageHasDataSrcURL = imageAttr.dataSrc != null && imageAttr.dataSrc.indexOf(options.domain) === 0;
495	            var imageRendered = imageAttr.rendered != null && imageAttr.rendered == 'true';
496
497	            if (imageHasSrc) {
498	                if (imageAttr.src.indexOf(options.domain) === 0) {
499	                    prepareImageElement(options, engineSettings, imageAttr.src, image);
500	                } else if (imageHasDataSrcURL) {
501	                    //Image has a valid data-src and an invalid src
502	                    if (imageRendered) {
503	                        //If the placeholder has already been render, re-render it
504	                        prepareImageElement(options, engineSettings, imageAttr.dataSrc, image);
505	                    } else {
506	                        //If the placeholder has not been rendered, check if the image exists and render a fallback if it doesn't
507	                        (function(src, options, engineSettings, dataSrc, image) {
508	                            utils.imageExists(src, function(exists) {
509	                                if (!exists) {
510	                                    prepareImageElement(options, engineSettings, dataSrc, image);
511	                                }
512	                            });
513	                        })(imageAttr.src, options, engineSettings, imageAttr.dataSrc, image);
514	                    }
515	                }
516	            } else if (imageHasDataSrcURL) {
517	                prepareImageElement(options, engineSettings, imageAttr.dataSrc, image);
518	            }
519	        });
520
521	        return this;
522	    }
523	};
524
525	var App = {
526	    settings: {
527	        domain: 'holder.js',
528	        images: 'img',
529	        objects: 'object',
530	        bgnodes: 'body .holderjs',
531	        stylenodes: 'head link.holderjs',
532	        themes: {
533	            'gray': {
534	                bg: '#EEEEEE',
535	                fg: '#AAAAAA'
536	            },
537	            'social': {
538	                bg: '#3a5a97',
539	                fg: '#FFFFFF'
540	            },
541	            'industrial': {
542	                bg: '#434A52',
543	                fg: '#C2F200'
544	            },
545	            'sky': {
546	                bg: '#0D8FDB',
547	                fg: '#FFFFFF'
548	            },
549	            'vine': {
550	                bg: '#39DBAC',
551	                fg: '#1E292C'
552	            },
553	            'lava': {
554	                bg: '#F8591A',
555	                fg: '#1C2846'
556	            }
557	        }
558	    },
559	    defaults: {
560	        size: 10,
561	        units: 'pt',
562	        scale: 1 / 16
563	    }
564	};
565
566	/**
567	 * Processes provided source attribute and sets up the appropriate rendering workflow
568	 *
569	 * @private
570	 * @param options Instance options from Holder.run
571	 * @param renderSettings Instance configuration
572	 * @param src Image URL
573	 * @param el Image DOM element
574	 */
575	function prepareImageElement(options, engineSettings, src, el) {
576	    var holderFlags = parseURL(src.substr(src.lastIndexOf(options.domain)), options);
577	    if (holderFlags) {
578	        prepareDOMElement({
579	            mode: null,
580	            el: el,
581	            flags: holderFlags,
582	            engineSettings: engineSettings
583	        });
584	    }
585	}
586
587	/**
588	 * Processes a Holder URL and extracts configuration from query string
589	 *
590	 * @private
591	 * @param url URL
592	 * @param instanceOptions Instance options from Holder.run
593	 */
594	function parseURL(url, instanceOptions) {
595	    var holder = {
596	        theme: extend(App.settings.themes.gray, null),
597	        stylesheets: instanceOptions.stylesheets,
598	        instanceOptions: instanceOptions
599	    };
600
601	    var firstQuestionMark = url.indexOf('?');
602	    var parts = [url];
603
604	    if (firstQuestionMark !== -1) {
605	        parts = [url.slice(0, firstQuestionMark), url.slice(firstQuestionMark + 1)];
606	    }
607
608	    var basics = parts[0].split('/');
609
610	    holder.holderURL = url;
611
612	    var dimensions = basics[1];
613	    var dimensionData = dimensions.match(/([\d]+p?)x([\d]+p?)/);
614
615	    if (!dimensionData) return false;
616
617	    holder.fluid = dimensions.indexOf('p') !== -1;
618
619	    holder.dimensions = {
620	        width: dimensionData[1].replace('p', '%'),
621	        height: dimensionData[2].replace('p', '%')
622	    };
623
624	    if (parts.length === 2) {
625	        var options = querystring.parse(parts[1]);
626
627	        // Colors
628
629	        if (options.bg) {
630	            holder.theme.bg = utils.parseColor(options.bg);
631	        }
632
633	        if (options.fg) {
634	            holder.theme.fg = utils.parseColor(options.fg);
635	        }
636
637	        //todo: add automatic foreground to themes without foreground
638	        if (options.bg && !options.fg) {
639	            holder.autoFg = true;
640	        }
641
642	        if (options.theme && holder.instanceOptions.themes.hasOwnProperty(options.theme)) {
643	            holder.theme = extend(holder.instanceOptions.themes[options.theme], null);
644	        }
645
646	        // Text
647
648	        if (options.text) {
649	            holder.text = options.text;
650	        }
651
652	        if (options.textmode) {
653	            holder.textmode = options.textmode;
654	        }
655
656	        if (options.size) {
657	            holder.size = options.size;
658	        }
659
660	        if (options.font) {
661	            holder.font = options.font;
662	        }
663
664	        if (options.align) {
665	            holder.align = options.align;
666	        }
667
668	        if (options.lineWrap) {
669	            holder.lineWrap = options.lineWrap;
670	        }
671
672	        holder.nowrap = utils.truthy(options.nowrap);
673
674	        // Miscellaneous
675
676	        holder.auto = utils.truthy(options.auto);
677
678	        holder.outline = utils.truthy(options.outline);
679
680	        if (utils.truthy(options.random)) {
681	            App.vars.cache.themeKeys = App.vars.cache.themeKeys || Object.keys(holder.instanceOptions.themes);
682	            var _theme = App.vars.cache.themeKeys[0 | Math.random() * App.vars.cache.themeKeys.length];
683	            holder.theme = extend(holder.instanceOptions.themes[_theme], null);
684	        }
685	    }
686
687	    return holder;
688	}
689
690	/**
691	 * Modifies the DOM to fit placeholders and sets up resizable image callbacks (for fluid and automatically sized placeholders)
692	 *
693	 * @private
694	 * @param settings DOM prep settings
695	 */
696	function prepareDOMElement(prepSettings) {
697	    var mode = prepSettings.mode;
698	    var el = prepSettings.el;
699	    var flags = prepSettings.flags;
700	    var _engineSettings = prepSettings.engineSettings;
701	    var dimensions = flags.dimensions,
702	        theme = flags.theme;
703	    var dimensionsCaption = dimensions.width + 'x' + dimensions.height;
704	    mode = mode == null ? (flags.fluid ? 'fluid' : 'image') : mode;
705	    var holderTemplateRe = /holder_([a-z]+)/g;
706	    var dimensionsInText = false;
707
708	    if (flags.text != null) {
709	        theme.text = flags.text;
710
711	        //<object> SVG embedding doesn't parse Unicode properly
712	        if (el.nodeName.toLowerCase() === 'object') {
713	            var textLines = theme.text.split('\\n');
714	            for (var k = 0; k < textLines.length; k++) {
715	                textLines[k] = utils.encodeHtmlEntity(textLines[k]);
716	            }
717	            theme.text = textLines.join('\\n');
718	        }
719	    }
720
721	    if (theme.text) {
722	        var holderTemplateMatches = theme.text.match(holderTemplateRe);
723
724	        if (holderTemplateMatches !== null) {
725	            //todo: optimize template replacement
726	            holderTemplateMatches.forEach(function (match) {
727	                if (match === 'holder_dimensions') {
728	                    theme.text = theme.text.replace(match, dimensionsCaption);
729	                }
730	            });
731	        }
732	    }
733
734	    var holderURL = flags.holderURL;
735	    var engineSettings = extend(_engineSettings, null);
736
737	    if (flags.font) {
738	        /*
739	        If external fonts are used in a <img> placeholder rendered with SVG, Holder falls back to canvas.
740
741	        This is done because Firefox and Chrome disallow embedded SVGs from referencing external assets.
742	        The workaround is either to change the placeholder tag from <img> to <object> or to use the canvas renderer.
743	        */
744	        theme.font = flags.font;
745	        if (!engineSettings.noFontFallback && el.nodeName.toLowerCase() === 'img' && App.setup.supportsCanvas && engineSettings.renderer === 'svg') {
746	            engineSettings = extend(engineSettings, {
747	                renderer: 'canvas'
748	            });
749	        }
750	    }
751
752	    //Chrome and Opera require a quick 10ms re-render if web fonts are used with canvas
753	    if (flags.font && engineSettings.renderer == 'canvas') {
754	        engineSettings.reRender = true;
755	    }
756
757	    if (mode == 'background') {
758	        if (el.getAttribute('data-background-src') == null) {
759	            DOM.setAttr(el, {
760	                'data-background-src': holderURL
761	            });
762	        }
763	    } else {
764	        var domProps = {};
765	        domProps[App.vars.dataAttr] = holderURL;
766	        DOM.setAttr(el, domProps);
767	    }
768
769	    flags.theme = theme;
770
771	    //todo consider using all renderSettings in holderData
772	    el.holderData = {
773	        flags: flags,
774	        engineSettings: engineSettings
775	    };
776
777	    if (mode == 'image' || mode == 'fluid') {
778	        DOM.setAttr(el, {
779	            'alt': theme.text ? (dimensionsInText ? theme.text : theme.text + ' [' + dimensionsCaption + ']') : dimensionsCaption
780	        });
781	    }
782
783	    var renderSettings = {
784	        mode: mode,
785	        el: el,
786	        holderSettings: {
787	            dimensions: dimensions,
788	            theme: theme,
789	            flags: flags
790	        },
791	        engineSettings: engineSettings
792	    };
793
794	    if (mode == 'image') {
795	        if (!flags.auto) {
796	            el.style.width = dimensions.width + 'px';
797	            el.style.height = dimensions.height + 'px';
798	        }
799
800	        if (engineSettings.renderer == 'html') {
801	            el.style.backgroundColor = theme.bg;
802	        } else {
803	            render(renderSettings);
804
805	            if (flags.textmode == 'exact') {
806	                el.holderData.resizeUpdate = true;
807	                App.vars.resizableImages.push(el);
808	                updateResizableElements(el);
809	            }
810	        }
811	    } else if (mode == 'background' && engineSettings.renderer != 'html') {
812	        render(renderSettings);
813	    } else if (mode == 'fluid') {
814	        el.holderData.resizeUpdate = true;
815
816	        if (dimensions.height.slice(-1) == '%') {
817	            el.style.height = dimensions.height;
818	        } else if (flags.auto == null || !flags.auto) {
819	            el.style.height = dimensions.height + 'px';
820	        }
821	        if (dimensions.width.slice(-1) == '%') {
822	            el.style.width = dimensions.width;
823	        } else if (flags.auto == null || !flags.auto) {
824	            el.style.width = dimensions.width + 'px';
825	        }
826	        if (el.style.display == 'inline' || el.style.display === '' || el.style.display == 'none') {
827	            el.style.display = 'block';
828	        }
829
830	        setInitialDimensions(el);
831
832	        if (engineSettings.renderer == 'html') {
833	            el.style.backgroundColor = theme.bg;
834	        } else {
835	            App.vars.resizableImages.push(el);
836	            updateResizableElements(el);
837	        }
838	    }
839	}
840
841	/**
842	 * Core function that takes output from renderers and sets it as the source or background-image of the target element
843	 *
844	 * @private
845	 * @param renderSettings Renderer settings
846	 */
847	function render(renderSettings) {
848	    var image = null;
849	    var mode = renderSettings.mode;
850	    var el = renderSettings.el;
851	    var holderSettings = renderSettings.holderSettings;
852	    var engineSettings = renderSettings.engineSettings;
853
854	    switch (engineSettings.renderer) {
855	        case 'svg':
856	            if (!App.setup.supportsSVG) return;
857	            break;
858	        case 'canvas':
859	            if (!App.setup.supportsCanvas) return;
860	            break;
861	        default:
862	            return;
863	    }
864
865	    //todo: move generation of scene up to flag generation to reduce extra object creation
866	    var scene = {
867	        width: holderSettings.dimensions.width,
868	        height: holderSettings.dimensions.height,
869	        theme: holderSettings.theme,
870	        flags: holderSettings.flags
871	    };
872
873	    var sceneGraph = buildSceneGraph(scene);
874
875	    function getRenderedImage() {
876	        var image = null;
877	        switch (engineSettings.renderer) {
878	            case 'canvas':
879	                image = sgCanvasRenderer(sceneGraph, renderSettings);
880	                break;
881	            case 'svg':
882	                image = svgRenderer(sceneGraph, renderSettings);
883	                break;
884	            default:
885	                throw 'Holder: invalid renderer: ' + engineSettings.renderer;
886	        }
887
888	        return image;
889	    }
890
891	    image = getRenderedImage();
892
893	    if (image == null) {
894	        throw 'Holder: couldn\'t render placeholder';
895	    }
896
897	    //todo: add <object> canvas rendering
898	    if (mode == 'background') {
899	        el.style.backgroundImage = 'url(' + image + ')';
900	        el.style.backgroundSize = scene.width + 'px ' + scene.height + 'px';
901	    } else {
902	        if (el.nodeName.toLowerCase() === 'img') {
903	            DOM.setAttr(el, {
904	                'src': image
905	            });
906	        } else if (el.nodeName.toLowerCase() === 'object') {
907	            DOM.setAttr(el, {
908	                'data': image,
909	                'type': 'image/svg+xml'
910	            });
911	        }
912	        if (engineSettings.reRender) {
913	            global.setTimeout(function () {
914	                var image = getRenderedImage();
915	                if (image == null) {
916	                    throw 'Holder: couldn\'t render placeholder';
917	                }
918	                //todo: refactor this code into a function
919	                if (el.nodeName.toLowerCase() === 'img') {
920	                    DOM.setAttr(el, {
921	                        'src': image
922	                    });
923	                } else if (el.nodeName.toLowerCase() === 'object') {
924	                    DOM.setAttr(el, {
925	                        'data': image,
926	                        'type': 'image/svg+xml'
927	                    });
928	                }
929	            }, 150);
930	        }
931	    }
932	    //todo: account for re-rendering
933	    DOM.setAttr(el, {
934	        'data-holder-rendered': true
935	    });
936	}
937
938	/**
939	 * Core function that takes a Holder scene description and builds a scene graph
940	 *
941	 * @private
942	 * @param scene Holder scene object
943	 */
944	//todo: make this function reusable
945	//todo: merge app defaults and setup properties into the scene argument
946	function buildSceneGraph(scene) {
947	    var fontSize = App.defaults.size;
948	    if (parseFloat(scene.theme.size)) {
949	        fontSize = scene.theme.size;
950	    } else if (parseFloat(scene.flags.size)) {
951	        fontSize = scene.flags.size;
952	    }
953
954	    scene.font = {
955	        family: scene.theme.font ? scene.theme.font : 'Arial, Helvetica, Open Sans, sans-serif',
956	        size: textSize(scene.width, scene.height, fontSize, App.defaults.scale),
957	        units: scene.theme.units ? scene.theme.units : App.defaults.units,
958	        weight: scene.theme.fontweight ? scene.theme.fontweight : 'bold'
959	    };
960
961	    scene.text = scene.theme.text || Math.floor(scene.width) + 'x' + Math.floor(scene.height);
962
963	    scene.noWrap = scene.theme.nowrap || scene.flags.nowrap;
964
965	    scene.align = scene.theme.align || scene.flags.align || 'center';
966
967	    switch (scene.flags.textmode) {
968	        case 'literal':
969	            scene.text = scene.flags.dimensions.width + 'x' + scene.flags.dimensions.height;
970	            break;
971	        case 'exact':
972	            if (!scene.flags.exactDimensions) break;
973	            scene.text = Math.floor(scene.flags.exactDimensions.width) + 'x' + Math.floor(scene.flags.exactDimensions.height);
974	            break;
975	    }
976
977	    var lineWrap = scene.flags.lineWrap || App.setup.lineWrapRatio;
978	    var sceneMargin = scene.width * lineWrap;
979	    var maxLineWidth = sceneMargin;
980
981	    var sceneGraph = new SceneGraph({
982	        width: scene.width,
983	        height: scene.height
984	    });
985
986	    var Shape = sceneGraph.Shape;
987
988	    var holderBg = new Shape.Rect('holderBg', {
989	        fill: scene.theme.bg
990	    });
991
992	    holderBg.resize(scene.width, scene.height);
993	    sceneGraph.root.add(holderBg);
994
995	    if (scene.flags.outline) {
996	        var outlineColor = new Color(holderBg.properties.fill);
997	        outlineColor = outlineColor.lighten(outlineColor.lighterThan('7f7f7f') ? -0.1 : 0.1);
998	        holderBg.properties.outline = {
999	            fill: outlineColor.toHex(true),
1000	            width: 2
1001	        };
1002	    }
1003
1004	    var holderTextColor = scene.theme.fg;
1005
1006	    if (scene.flags.autoFg) {
1007	        var holderBgColor = new Color(holderBg.properties.fill);
1008	        var lightColor = new Color('fff');
1009	        var darkColor = new Color('000', {
1010	            'alpha': 0.285714
1011	        });
1012
1013	        holderTextColor = holderBgColor.blendAlpha(holderBgColor.lighterThan('7f7f7f') ? darkColor : lightColor).toHex(true);
1014	    }
1015
1016	    var holderTextGroup = new Shape.Group('holderTextGroup', {
1017	        text: scene.text,
1018	        align: scene.align,
1019	        font: scene.font,
1020	        fill: holderTextColor
1021	    });
1022
1023	    holderTextGroup.moveTo(null, null, 1);
1024	    sceneGraph.root.add(holderTextGroup);
1025
1026	    var tpdata = holderTextGroup.textPositionData = stagingRenderer(sceneGraph);
1027	    if (!tpdata) {
1028	        throw 'Holder: staging fallback not supported yet.';
1029	    }
1030	    holderTextGroup.properties.leading = tpdata.boundingBox.height;
1031
1032	    var textNode = null;
1033	    var line = null;
1034
1035	    function finalizeLine(parent, line, width, height) {
1036	        line.width = width;
1037	        line.height = height;
1038	        parent.width = Math.max(parent.width, line.width);
1039	        parent.height += line.height;
1040	    }
1041
1042	    if (tpdata.lineCount > 1) {
1043	        var offsetX = 0;
1044	        var offsetY = 0;
1045	        var lineIndex = 0;
1046	        var lineKey;
1047	        line = new Shape.Group('line' + lineIndex);
1048
1049	        //Double margin so that left/right-aligned next is not flush with edge of image
1050	        if (scene.align === 'left' || scene.align === 'right') {
1051	            maxLineWidth = scene.width * (1 - (1 - lineWrap) * 2);
1052	        }
1053
1054	        for (var i = 0; i < tpdata.words.length; i++) {
1055	            var word = tpdata.words[i];
1056	            textNode = new Shape.Text(word.text);
1057	            var newline = word.text == '\\n';
1058	            if (!scene.noWrap && (offsetX + word.width >= maxLineWidth || newline === true)) {
1059	                finalizeLine(holderTextGroup, line, offsetX, holderTextGroup.properties.leading);
1060	                holderTextGroup.add(line);
1061	                offsetX = 0;
1062	                offsetY += holderTextGroup.properties.leading;
1063	                lineIndex += 1;
1064	                line = new Shape.Group('line' + lineIndex);
1065	                line.y = offsetY;
1066	            }
1067	            if (newline === true) {
1068	                continue;
1069	            }
1070	            textNode.moveTo(offsetX, 0);
1071	            offsetX += tpdata.spaceWidth + word.width;
1072	            line.add(textNode);
1073	        }
1074
1075	        finalizeLine(holderTextGroup, line, offsetX, holderTextGroup.properties.leading);
1076	        holderTextGroup.add(line);
1077
1078	        if (scene.align === 'left') {
1079	            holderTextGroup.moveTo(scene.width - sceneMargin, null, null);
1080	        } else if (scene.align === 'right') {
1081	            for (lineKey in holderTextGroup.children) {
1082	                line = holderTextGroup.children[lineKey];
1083	                line.moveTo(scene.width - line.width, null, null);
1084	            }
1085
1086	            holderTextGroup.moveTo(0 - (scene.width - sceneMargin), null, null);
1087	        } else {
1088	            for (lineKey in holderTextGroup.children) {
1089	                line = holderTextGroup.children[lineKey];
1090	                line.moveTo((holderTextGroup.width - line.width) / 2, null, null);
1091	            }
1092
1093	            holderTextGroup.moveTo((scene.width - holderTextGroup.width) / 2, null, null);
1094	        }
1095
1096	        holderTextGroup.moveTo(null, (scene.height - holderTextGroup.height) / 2, null);
1097
1098	        //If the text exceeds vertical space, move it down so the first line is visible
1099	        if ((scene.height - holderTextGroup.height) / 2 < 0) {
1100	            holderTextGroup.moveTo(null, 0, null);
1101	        }
1102	    } else {
1103	        textNode = new Shape.Text(scene.text);
1104	        line = new Shape.Group('line0');
1105	        line.add(textNode);
1106	        holderTextGroup.add(line);
1107
1108	        if (scene.align === 'left') {
1109	            holderTextGroup.moveTo(scene.width - sceneMargin, null, null);
1110	        } else if (scene.align === 'right') {
1111	            holderTextGroup.moveTo(0 - (scene.width - sceneMargin), null, null);
1112	        } else {
1113	            holderTextGroup.moveTo((scene.width - tpdata.boundingBox.width) / 2, null, null);
1114	        }
1115
1116	        holderTextGroup.moveTo(null, (scene.height - tpdata.boundingBox.height) / 2, null);
1117	    }
1118
1119	    //todo: renderlist
1120	    return sceneGraph;
1121	}
1122
1123	/**
1124	 * Adaptive text sizing function
1125	 *
1126	 * @private
1127	 * @param width Parent width
1128	 * @param height Parent height
1129	 * @param fontSize Requested text size
1130	 * @param scale Proportional scale of text
1131	 */
1132	function textSize(width, height, fontSize, scale) {
1133	    var stageWidth = parseInt(width, 10);
1134	    var stageHeight = parseInt(height, 10);
1135
1136	    var bigSide = Math.max(stageWidth, stageHeight);
1137	    var smallSide = Math.min(stageWidth, stageHeight);
1138
1139	    var newHeight = 0.8 * Math.min(smallSide, bigSide * scale);
1140	    return Math.round(Math.max(fontSize, newHeight));
1141	}
1142
1143	/**
1144	 * Iterates over resizable (fluid or auto) placeholders and renders them
1145	 *
1146	 * @private
1147	 * @param element Optional element selector, specified only if a specific element needs to be re-rendered
1148	 */
1149	function updateResizableElements(element) {
1150	    var images;
1151	    if (element == null || element.nodeType == null) {
1152	        images = App.vars.resizableImages;
1153	    } else {
1154	        images = [element];
1155	    }
1156	    for (var i = 0, l = images.length; i < l; i++) {
1157	        var el = images[i];
1158	        if (el.holderData) {
1159	            var flags = el.holderData.flags;
1160	            var dimensions = dimensionCheck(el);
1161	            if (dimensions) {
1162	                if (!el.holderData.resizeUpdate) {
1163	                    continue;
1164	                }
1165
1166	                if (flags.fluid && flags.auto) {
1167	                    var fluidConfig = el.holderData.fluidConfig;
1168	                    switch (fluidConfig.mode) {
1169	                        case 'width':
1170	                            dimensions.height = dimensions.width / fluidConfig.ratio;
1171	                            break;
1172	                        case 'height':
1173	                            dimensions.width = dimensions.height * fluidConfig.ratio;
1174	                            break;
1175	                    }
1176	                }
1177
1178	                var settings = {
1179	                    mode: 'image',
1180	                    holderSettings: {
1181	                        dimensions: dimensions,
1182	                        theme: flags.theme,
1183	                        flags: flags
1184	                    },
1185	                    el: el,
1186	                    engineSettings: el.holderData.engineSettings
1187	                };
1188
1189	                if (flags.textmode == 'exact') {
1190	                    flags.exactDimensions = dimensions;
1191	                    settings.holderSettings.dimensions = flags.dimensions;
1192	                }
1193
1194	                render(settings);
1195	            } else {
1196	                setInvisible(el);
1197	            }
1198	        }
1199	    }
1200	}
1201
1202	/**
1203	 * Sets up aspect ratio metadata for fluid placeholders, in order to preserve proportions when resizing
1204	 *
1205	 * @private
1206	 * @param el Image DOM element
1207	 */
1208	function setInitialDimensions(el) {
1209	    if (el.holderData) {
1210	        var dimensions = dimensionCheck(el);
1211	        if (dimensions) {
1212	            var flags = el.holderData.flags;
1213
1214	            var fluidConfig = {
1215	                fluidHeight: flags.dimensions.height.slice(-1) == '%',
1216	                fluidWidth: flags.dimensions.width.slice(-1) == '%',
1217	                mode: null,
1218	                initialDimensions: dimensions
1219	            };
1220
1221	            if (fluidConfig.fluidWidth && !fluidConfig.fluidHeight) {
1222	                fluidConfig.mode = 'width';
1223	                fluidConfig.ratio = fluidConfig.initialDimensions.width / parseFloat(flags.dimensions.height);
1224	            } else if (!fluidConfig.fluidWidth && fluidConfig.fluidHeight) {
1225	                fluidConfig.mode = 'height';
1226	                fluidConfig.ratio = parseFloat(flags.dimensions.width) / fluidConfig.initialDimensions.height;
1227	            }
1228
1229	            el.holderData.fluidConfig = fluidConfig;
1230	        } else {
1231	            setInvisible(el);
1232	        }
1233	    }
1234	}
1235
1236	/**
1237	 * Iterates through all current invisible images, and if they're visible, renders them and removes them from further checks. Runs every animation frame.
1238	 *
1239	 * @private
1240	 */
1241	function visibilityCheck() {
1242	    var renderableImages = [];
1243	    var keys = Object.keys(App.vars.invisibleImages);
1244	    var el;
1245
1246	    keys.forEach(function (key) {
1247	        el = App.vars.invisibleImages[key];
1248	        if (dimensionCheck(el) && el.nodeName.toLowerCase() == 'img') {
1249	            renderableImages.push(el);
1250	            delete App.vars.invisibleImages[key];
1251	        }
1252	    });
1253
1254	    if (renderableImages.length) {
1255	        Holder.run({
1256	            images: renderableImages
1257	        });
1258	    }
1259
1260	    // Done to prevent 100% CPU usage via aggressive calling of requestAnimationFrame
1261	    setTimeout(function () {
1262	        global.requestAnimationFrame(visibilityCheck);
1263	    }, 10);
1264	}
1265
1266	/**
1267	 * Starts checking for invisible placeholders if not doing so yet. Does nothing otherwise.
1268	 *
1269	 * @private
1270	 */
1271	function startVisibilityCheck() {
1272	    if (!App.vars.visibilityCheckStarted) {
1273	        global.requestAnimationFrame(visibilityCheck);
1274	        App.vars.visibilityCheckStarted = true;
1275	    }
1276	}
1277
1278	/**
1279	 * Sets a unique ID for an image detected to be invisible and adds it to the map of invisible images checked by visibilityCheck
1280	 *
1281	 * @private
1282	 * @param el Invisible DOM element
1283	 */
1284	function setInvisible(el) {
1285	    if (!el.holderData.invisibleId) {
1286	        App.vars.invisibleId += 1;
1287	        App.vars.invisibleImages['i' + App.vars.invisibleId] = el;
1288	        el.holderData.invisibleId = App.vars.invisibleId;
1289	    }
1290	}
1291
1292	//todo: see if possible to convert stagingRenderer to use HTML only
1293	var stagingRenderer = (function() {
1294	    var svg = null,
1295	        stagingText = null,
1296	        stagingTextNode = null;
1297	    return function(graph) {
1298	        var rootNode = graph.root;
1299	        if (App.setup.supportsSVG) {
1300	            var firstTimeSetup = false;
1301	            var tnode = function(text) {
1302	                return document.createTextNode(text);
1303	            };
1304	            if (svg == null || svg.parentNode !== document.body) {
1305	                firstTimeSetup = true;
1306	            }
1307
1308	            svg = SVG.initSVG(svg, rootNode.properties.width, rootNode.properties.height);
1309	            //Show staging element before staging
1310	            svg.style.display = 'block';
1311
1312	            if (firstTimeSetup) {
1313	                stagingText = DOM.newEl('text', SVG_NS);
1314	                stagingTextNode = tnode(null);
1315	                DOM.setAttr(stagingText, {
1316	                    x: 0
1317	                });
1318	                stagingText.appendChild(stagingTextNode);
1319	                svg.appendChild(stagingText);
1320	                document.body.appendChild(svg);
1321	                svg.style.visibility = 'hidden';
1322	                svg.style.position = 'absolute';
1323	                svg.style.top = '-100%';
1324	                svg.style.left = '-100%';
1325	                //todo: workaround for zero-dimension <svg> tag in Opera 12
1326	                //svg.setAttribute('width', 0);
1327	                //svg.setAttribute('height', 0);
1328	            }
1329
1330	            var holderTextGroup = rootNode.children.holderTextGroup;
1331	            var htgProps = holderTextGroup.properties;
1332	            DOM.setAttr(stagingText, {
1333	                'y': htgProps.font.size,
1334	                'style': utils.cssProps({
1335	                    'font-weight': htgProps.font.weight,
1336	                    'font-size': htgProps.font.size + htgProps.font.units,
1337	                    'font-family': htgProps.font.family
1338	                })
1339	            });
1340
1341	            //Get bounding box for the whole string (total width and height)
1342	            stagingTextNode.nodeValue = htgProps.text;
1343	            var stagingTextBBox = stagingText.getBBox();
1344
1345	            //Get line count and split the string into words
1346	            var lineCount = Math.ceil(stagingTextBBox.width / rootNode.properties.width);
1347	            var words = htgProps.text.split(' ');
1348	            var newlines = htgProps.text.match(/\\n/g);
1349	            lineCount += newlines == null ? 0 : newlines.length;
1350
1351	            //Get bounding box for the string with spaces removed
1352	            stagingTextNode.nodeValue = htgProps.text.replace(/[ ]+/g, '');
1353	            var computedNoSpaceLength = stagingText.getComputedTextLength();
1354
1355	            //Compute average space width
1356	            var diffLength = stagingTextBBox.width - computedNoSpaceLength;
1357	            var spaceWidth = Math.round(diffLength / Math.max(1, words.length - 1));
1358
1359	            //Get widths for every word with space only if there is more than one line
1360	            var wordWidths = [];
1361	            if (lineCount > 1) {
1362	                stagingTextNode.nodeValue = '';
1363	                for (var i = 0; i < words.length; i++) {
1364	                    if (words[i].length === 0) continue;
1365	                    stagingTextNode.nodeValue = utils.decodeHtmlEntity(words[i]);
1366	                    var bbox = stagingText.getBBox();
1367	                    wordWidths.push({
1368	                        text: words[i],
1369	                        width: bbox.width
1370	                    });
1371	                }
1372	            }
1373
1374	            //Hide staging element after staging
1375	            svg.style.display = 'none';
1376
1377	            return {
1378	                spaceWidth: spaceWidth,
1379	                lineCount: lineCount,
1380	                boundingBox: stagingTextBBox,
1381	                words: wordWidths
1382	            };
1383	        } else {
1384	            //todo: canvas fallback for measuring text on android 2.3
1385	            return false;
1386	        }
1387	    };
1388	})();
1389
1390	//Helpers
1391
1392	/**
1393	 * Prevents a function from being called too often, waits until a timer elapses to call it again
1394	 *
1395	 * @param fn Function to call
1396	 */
1397	function debounce(fn) {
1398	    if (!App.vars.debounceTimer) fn.call(this);
1399	    if (App.vars.debounceTimer) global.clearTimeout(App.vars.debounceTimer);
1400	    App.vars.debounceTimer = global.setTimeout(function() {
1401	        App.vars.debounceTimer = null;
1402	        fn.call(this);
1403	    }, App.setup.debounce);
1404	}
1405
1406	/**
1407	 * Holder-specific resize/orientation change callback, debounced to prevent excessive execution
1408	 */
1409	function resizeEvent() {
1410	    debounce(function() {
1411	        updateResizableElements(null);
1412	    });
1413	}
1414
1415	//Set up flags
1416
1417	for (var flag in App.flags) {
1418	    if (!App.flags.hasOwnProperty(flag)) continue;
1419	    App.flags[flag].match = function(val) {
1420	        return val.match(this.regex);
1421	    };
1422	}
1423
1424	//Properties set once on setup
1425
1426	App.setup = {
1427	    renderer: 'html',
1428	    debounce: 100,
1429	    ratio: 1,
1430	    supportsCanvas: false,
1431	    supportsSVG: false,
1432	    lineWrapRatio: 0.9,
1433	    dataAttr: 'data-src',
1434	    renderers: ['html', 'canvas', 'svg']
1435	};
1436
1437	//Properties modified during runtime
1438
1439	App.vars = {
1440	    preempted: false,
1441	    resizableImages: [],
1442	    invisibleImages: {},
1443	    invisibleId: 0,
1444	    visibilityCheckStarted: false,
1445	    debounceTimer: null,
1446	    cache: {}
1447	};
1448
1449	//Pre-flight
1450
1451	(function() {
1452	    var canvas = DOM.newEl('canvas');
1453
1454	    if (canvas.getContext) {
1455	        if (canvas.toDataURL('image/png').indexOf('data:image/png') != -1) {
1456	            App.setup.renderer = 'canvas';
1457	            App.setup.supportsCanvas = true;
1458	        }
1459	    }
1460
1461	    if (!!document.createElementNS && !!document.createElementNS(SVG_NS, 'svg').createSVGRect) {
1462	        App.setup.renderer = 'svg';
1463	        App.setup.supportsSVG = true;
1464	    }
1465	})();
1466
1467	//Starts checking for invisible placeholders
1468	startVisibilityCheck();
1469
1470	if (onDomReady) {
1471	    onDomReady(function() {
1472	        if (!App.vars.preempted) {
1473	            Holder.run();
1474	        }
1475	        if (global.addEventListener) {
1476	            global.addEventListener('resize', resizeEvent, false);
1477	            global.addEventListener('orientationchange', resizeEvent, false);
1478	        } else {
1479	            global.attachEvent('onresize', resizeEvent);
1480	        }
1481
1482	        if (typeof global.Turbolinks == 'object') {
1483	            global.document.addEventListener('page:change', function() {
1484	                Holder.run();
1485	            });
1486	        }
1487	    });
1488	}
1489
1490	module.exports = Holder;
1491
1492	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
1493
1494/***/ },
1495/* 2 */
1496/***/ function(module, exports) {
1497
1498	/*!
1499	 * onDomReady.js 1.4.0 (c) 2013 Tubal Martin - MIT license
1500	 *
1501	 * Specially modified to work with Holder.js
1502	 */
1503
1504	function _onDomReady(win) {
1505	    //Lazy loading fix for Firefox < 3.6
1506	    //http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
1507	    if (document.readyState == null && document.addEventListener) {
1508	        document.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
1509	            document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
1510	            document.readyState = "complete";
1511	        }, false);
1512	        document.readyState = "loading";
1513	    }
1514	    
1515	    var doc = win.document,
1516	        docElem = doc.documentElement,
1517	    
1518	        LOAD = "load",
1519	        FALSE = false,
1520	        ONLOAD = "on"+LOAD,
1521	        COMPLETE = "complete",
1522	        READYSTATE = "readyState",
1523	        ATTACHEVENT = "attachEvent",
1524	        DETACHEVENT = "detachEvent",
1525	        ADDEVENTLISTENER = "addEventListener",
1526	        DOMCONTENTLOADED = "DOMContentLoaded",
1527	        ONREADYSTATECHANGE = "onreadystatechange",
1528	        REMOVEEVENTLISTENER = "removeEventListener",
1529	    
1530	        // W3C Event model
1531	        w3c = ADDEVENTLISTENER in doc,
1532	        _top = FALSE,
1533	    
1534	        // isReady: Is the DOM ready to be used? Set to true once it occurs.
1535	        isReady = FALSE,
1536	    
1537	        // Callbacks pending execution until DOM is ready
1538	        callbacks = [];
1539	    
1540	    // Handle when the DOM is ready
1541	    function ready( fn ) {
1542	        if ( !isReady ) {
1543	    
1544	            // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1545	            if ( !doc.body ) {
1546	                return defer( ready );
1547	            }
1548	    
1549	            // Remember that the DOM is ready
1550	            isReady = true;
1551	    
1552	            // Execute all callbacks
1553	            while ( fn = callbacks.shift() ) {
1554	                defer( fn );
1555	            }
1556	        }
1557	    }
1558	    
1559	    // The ready event handler
1560	    function completed( event ) {
1561	        // readyState === "complete" is good enough for us to call the dom ready in oldIE
1562	        if ( w3c || event.type === LOAD || doc[READYSTATE] === COMPLETE ) {
1563	            detach();
1564	            ready();
1565	        }
1566	    }
1567	    
1568	    // Clean-up method for dom ready events
1569	    function detach() {
1570	        if ( w3c ) {
1571	            doc[REMOVEEVENTLISTENER]( DOMCONTENTLOADED, completed, FALSE );
1572	            win[REMOVEEVENTLISTENER]( LOAD, completed, FALSE );
1573	        } else {
1574	            doc[DETACHEVENT]( ONREADYSTATECHANGE, completed );
1575	            win[DETACHEVENT]( ONLOAD, completed );
1576	        }
1577	    }
1578	    
1579	    // Defers a function, scheduling it to run after the current call stack has cleared.
1580	    function defer( fn, wait ) {
1581	        // Allow 0 to be passed
1582	        setTimeout( fn, +wait >= 0 ? wait : 1 );
1583	    }
1584	    
1585	    // Attach the listeners:
1586	    
1587	    // Catch cases where onDomReady is called after the browser event has already occurred.
1588	    // we once tried to use readyState "interactive" here, but it caused issues like the one
1589	    // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
1590	    if ( doc[READYSTATE] === COMPLETE ) {
1591	        // Handle it asynchronously to allow scripts the opportunity to delay ready
1592	        defer( ready );
1593	    
1594	    // Standards-based browsers support DOMContentLoaded
1595	    } else if ( w3c ) {
1596	        // Use the handy event callback
1597	        doc[ADDEVENTLISTENER]( DOMCONTENTLOADED, completed, FALSE );
1598	    
1599	        // A fallback to window.onload, that will always work
1600	        win[ADDEVENTLISTENER]( LOAD, completed, FALSE );
1601	    
1602	    // If IE event model is used
1603	    } else {
1604	        // Ensure firing before onload, maybe late but safe also for iframes
1605	        doc[ATTACHEVENT]( ONREADYSTATECHANGE, completed );
1606	    
1607	        // A fallback to window.onload, that will always work
1608	        win[ATTACHEVENT]( ONLOAD, completed );
1609	    
1610	        // If IE and not a frame
1611	        // continually check to see if the document is ready
1612	        try {
1613	            _top = win.frameElement == null && docElem;
1614	        } catch(e) {}
1615	    
1616	        if ( _top && _top.doScroll ) {
1617	            (function doScrollCheck() {
1618	                if ( !isReady ) {
1619	                    try {
1620	                        // Use the trick by Diego Perini
1621	                        // http://javascript.nwbox.com/IEContentLoaded/
1622	                        _top.doScroll("left");
1623	                    } catch(e) {
1624	                        return defer( doScrollCheck, 50 );
1625	                    }
1626	    
1627	                    // detach all dom ready events
1628	                    detach();
1629	    
1630	                    // and execute any waiting functions
1631	                    ready();
1632	                }
1633	            })();
1634	        }
1635	    }
1636	    
1637	    function onDomReady( fn ) {
1638	        // If DOM is ready, execute the function (async), otherwise wait
1639	        isReady ? defer( fn ) : callbacks.push( fn );
1640	    }
1641	    
1642	    // Add version
1643	    onDomReady.version = "1.4.0";
1644	    // Add method to check if DOM is ready
1645	    onDomReady.isReady = function(){
1646	        return isReady;
1647	    };
1648
1649	    return onDomReady;
1650	}
1651
1652	module.exports = typeof window !== "undefined" && _onDomReady(window);
1653
1654/***/ },
1655/* 3 */
1656/***/ function(module, exports, __webpack_require__) {
1657
1658	//Modified version of component/querystring
1659	//Changes: updated dependencies, dot notation parsing, JSHint fixes
1660	//Fork at https://github.com/imsky/querystring
1661
1662	/**
1663	 * Module dependencies.
1664	 */
1665
1666	var encode = encodeURIComponent;
1667	var decode = decodeURIComponent;
1668	var trim = __webpack_require__(4);
1669	var type = __webpack_require__(5);
1670
1671	var arrayRegex = /(\w+)\[(\d+)\]/;
1672	var objectRegex = /\w+\.\w+/;
1673
1674	/**
1675	 * Parse the given query `str`.
1676	 *
1677	 * @param {String} str
1678	 * @return {Object}
1679	 * @api public
1680	 */
1681
1682	exports.parse = function(str){
1683	  if ('string' !== typeof str) return {};
1684
1685	  str = trim(str);
1686	  if ('' === str) return {};
1687	  if ('?' === str.charAt(0)) str = str.slice(1);
1688
1689	  var obj = {};
1690	  var pairs = str.split('&');
1691	  for (var i = 0; i < pairs.length; i++) {
1692	    var parts = pairs[i].split('=');
1693	    var key = decode(parts[0]);
1694	    var m, ctx, prop;
1695
1696	    if (m = arrayRegex.exec(key)) {
1697	      obj[m[1]] = obj[m[1]] || [];
1698	      obj[m[1]][m[2]] = decode(parts[1]);
1699	      continue;
1700	    }
1701
1702	    if (m = objectRegex.test(key)) {
1703	      m = key.split('.');
1704	      ctx = obj;
1705	      
1706	      while (m.length) {
1707	        prop = m.shift();
1708
1709	        if (!prop.length) continue;
1710
1711	        if (!ctx[prop]) {
1712	          ctx[prop] = {};
1713	        } else if (ctx[prop] && typeof ctx[prop] !== 'object') {
1714	          break;
1715	        }
1716
1717	        if (!m.length) {
1718	          ctx[prop] = decode(parts[1]);
1719	        }
1720
1721	        ctx = ctx[prop];
1722	      }
1723
1724	      continue;
1725	    }
1726
1727	    obj[parts[0]] = null == parts[1] ? '' : decode(parts[1]);
1728	  }
1729
1730	  return obj;
1731	};
1732
1733	/**
1734	 * Stringify the given `obj`.
1735	 *
1736	 * @param {Object} obj
1737	 * @return {String}
1738	 * @api public
1739	 */
1740
1741	exports.stringify = function(obj){
1742	  if (!obj) return '';
1743	  var pairs = [];
1744
1745	  for (var key in obj) {
1746	    var value = obj[key];
1747
1748	    if ('array' == type(value)) {
1749	      for (var i = 0; i < value.length; ++i) {
1750	        pairs.push(encode(key + '[' + i + ']') + '=' + encode(value[i]));
1751	      }
1752	      continue;
1753	    }
1754
1755	    pairs.push(encode(key) + '=' + encode(obj[key]));
1756	  }
1757
1758	  return pairs.join('&');
1759	};
1760
1761
1762/***/ },
1763/* 4 */
1764/***/ function(module, exports) {
1765
1766	
1767	exports = module.exports = trim;
1768
1769	function trim(str){
1770	  return str.replace(/^\s*|\s*$/g, '');
1771	}
1772
1773	exports.left = function(str){
1774	  return str.replace(/^\s*/, '');
1775	};
1776
1777	exports.right = function(str){
1778	  return str.replace(/\s*$/, '');
1779	};
1780
1781
1782/***/ },
1783/* 5 */
1784/***/ function(module, exports, __webpack_require__) {
1785
1786	/* WEBPACK VAR INJECTION */(function(Buffer) {/**
1787	 * toString ref.
1788	 */
1789
1790	var toString = Object.prototype.toString;
1791
1792	/**
1793	 * Return the type of `val`.
1794	 *
1795	 * @param {Mixed} val
1796	 * @return {String}
1797	 * @api public
1798	 */
1799
1800	module.exports = function(val){
1801	  switch (toString.call(val)) {
1802	    case '[object Date]': return 'date';
1803	    case '[object RegExp]': return 'regexp';
1804	    case '[object Arguments]': return 'arguments';
1805	    case '[object Array]': return 'array';
1806	    case '[object Error]': return 'error';
1807	  }
1808
1809	  if (val === null) return 'null';
1810	  if (val === undefined) return 'undefined';
1811	  if (val !== val) return 'nan';
1812	  if (val && val.nodeType === 1) return 'element';
1813
1814	  if (typeof Buffer != 'undefined' && Buffer.isBuffer(val)) return 'buffer';
1815
1816	  val = val.valueOf
1817	    ? val.valueOf()
1818	    : Object.prototype.valueOf.apply(val)
1819
1820	  return typeof val;
1821	};
1822
1823	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6).Buffer))
1824
1825/***/ },
1826/* 6 */
1827/***/ function(module, exports, __webpack_require__) {
1828
1829	/* WEBPACK VAR INJECTION */(function(Buffer, global) {/*!
1830	 * The buffer module from node.js, for the browser.
1831	 *
1832	 * @author   Feross Aboukhadijeh <[email protected]> <http://feross.org>
1833	 * @license  MIT
1834	 */
1835	/* eslint-disable no-proto */
1836
1837	var base64 = __webpack_require__(7)
1838	var ieee754 = __webpack_require__(8)
1839	var isArray = __webpack_require__(9)
1840
1841	exports.Buffer = Buffer
1842	exports.SlowBuffer = SlowBuffer
1843	exports.INSPECT_MAX_BYTES = 50
1844	Buffer.poolSize = 8192 // not used by this implementation
1845
1846	var rootParent = {}
1847
1848	/**
1849	 * If `Buffer.TYPED_ARRAY_SUPPORT`:
1850	 *   === true    Use Uint8Array implementation (fastest)
1851	 *   === false   Use Object implementation (most compatible, even IE6)
1852	 *
1853	 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
1854	 * Opera 11.6+, iOS 4.2+.
1855	 *
1856	 * Due to various browser bugs, sometimes the Object implementation will be used even
1857	 * when the browser supports typed arrays.
1858	 *
1859	 * Note:
1860	 *
1861	 *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
1862	 *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
1863	 *
1864	 *   - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property
1865	 *     on objects.
1866	 *
1867	 *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
1868	 *
1869	 *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
1870	 *     incorrect length in some situations.
1871
1872	 * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
1873	 * get the Object implementation, which is slower but behaves correctly.
1874	 */
1875	Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
1876	  ? global.TYPED_ARRAY_SUPPORT
1877	  : typedArraySupport()
1878
1879	function typedArraySupport () {
1880	  function Bar () {}
1881	  try {
1882	    var arr = new Uint8Array(1)
1883	    arr.foo = function () { return 42 }
1884	    arr.constructor = Bar
1885	    return arr.foo() === 42 && // typed array instances can be augmented
1886	        arr.constructor === Bar && // constructor can be set
1887	        typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
1888	        arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
1889	  } catch (e) {
1890	    return false
1891	  }
1892	}
1893
1894	function kMaxLength () {
1895	  return Buffer.TYPED_ARRAY_SUPPORT
1896	    ? 0x7fffffff
1897	    : 0x3fffffff
1898	}
1899
1900	/**
1901	 * Class: Buffer
1902	 * =============
1903	 *
1904	 * The Buffer constructor returns instances of `Uint8Array` that are augmented
1905	 * with function properties for all the node `Buffer` API functions. We use
1906	 * `Uint8Array` so that square bracket notation works as expected -- it returns
1907	 * a single octet.
1908	 *
1909	 * By augmenting the instances, we can avoid modifying the `Uint8Array`
1910	 * prototype.
1911	 */
1912	function Buffer (arg) {
1913	  if (!(this instanceof Buffer)) {
1914	    // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
1915	    if (arguments.length > 1) return new Buffer(arg, arguments[1])
1916	    return new Buffer(arg)
1917	  }
1918
1919	  this.length = 0
1920	  this.parent = undefined
1921
1922	  // Common case.
1923	  if (typeof arg === 'number') {
1924	    return fromNumber(this, arg)
1925	  }
1926
1927	  // Slightly less common case.
1928	  if (typeof arg === 'string') {
1929	    return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8')
1930	  }
1931
1932	  // Unusual.
1933	  return fromObject(this, arg)
1934	}
1935
1936	function fromNumber (that, length) {
1937	  that = allocate(that, length < 0 ? 0 : checked(length) | 0)
1938	  if (!Buffer.TYPED_ARRAY_SUPPORT) {
1939	    for (var i = 0; i < length; i++) {
1940	      that[i] = 0
1941	    }
1942	  }
1943	  return that
1944	}
1945
1946	function fromString (that, string, encoding) {
1947	  if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8'
1948
1949	  // Assumption: byteLength() return value is always < kMaxLength.
1950	  var length = byteLength(string, encoding) | 0
1951	  that = allocate(that, length)
1952
1953	  that.write(string, encoding)
1954	  return that
1955	}
1956
1957	function fromObject (that, object) {
1958	  if (Buffer.isBuffer(object)) return fromBuffer(that, object)
1959
1960	  if (isArray(object)) return fromArray(that, object)
1961
1962	  if (object == null) {
1963	    throw new TypeError('must start with number, buffer, array or string')
1964	  }
1965
1966	  if (typeof ArrayBuffer !== 'undefined') {
1967	    if (object.buffer instanceof ArrayBuffer) {
1968	      return fromTypedArray(that, object)
1969	    }
1970	    if (object instanceof ArrayBuffer) {
1971	      return fromArrayBuffer(that, object)
1972	    }
1973	  }
1974
1975	  if (object.length) return fromArrayLike(that, object)
1976
1977	  return fromJsonObject(that, object)
1978	}
1979
1980	function fromBuffer (that, buffer) {
1981	  var length = checked(buffer.length) | 0
1982	  that = allocate(that, length)
1983	  buffer.copy(that, 0, 0, length)
1984	  return that
1985	}
1986
1987	function fromArray (that, array) {
1988	  var length = checked(array.length) | 0
1989	  that = allocate(that, length)
1990	  for (var i = 0; i < length; i += 1) {
1991	    that[i] = array[i] & 255
1992	  }
1993	  return that
1994	}
1995
1996	// Duplicate of fromArray() to keep fromArray() monomorphic.
1997	function fromTypedArray (that, array) {
1998	  var length = checked(array.length) | 0
1999	  that = allocate(that, length)
2000	  // Truncating the elements is probably not what people expect from typed
2001	  // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
2002	  // of the old Buffer constructor.
2003	  for (var i = 0; i < length; i += 1) {
2004	    that[i] = array[i] & 255
2005	  }
2006	  return that
2007	}
2008
2009	function fromArrayBuffer (that, array) {
2010	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2011	    // Return an augmented `Uint8Array` instance, for best performance
2012	    array.byteLength
2013	    that = Buffer._augment(new Uint8Array(array))
2014	  } else {
2015	    // Fallback: Return an object instance of the Buffer class
2016	    that = fromTypedArray(that, new Uint8Array(array))
2017	  }
2018	  return that
2019	}
2020
2021	function fromArrayLike (that, array) {
2022	  var length = checked(array.length) | 0
2023	  that = allocate(that, length)
2024	  for (var i = 0; i < length; i += 1) {
2025	    that[i] = array[i] & 255
2026	  }
2027	  return that
2028	}
2029
2030	// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
2031	// Returns a zero-length buffer for inputs that don't conform to the spec.
2032	function fromJsonObject (that, object) {
2033	  var array
2034	  var length = 0
2035
2036	  if (object.type === 'Buffer' && isArray(object.data)) {
2037	    array = object.data
2038	    length = checked(array.length) | 0
2039	  }
2040	  that = allocate(that, length)
2041
2042	  for (var i = 0; i < length; i += 1) {
2043	    that[i] = array[i] & 255
2044	  }
2045	  return that
2046	}
2047
2048	if (Buffer.TYPED_ARRAY_SUPPORT) {
2049	  Buffer.prototype.__proto__ = Uint8Array.prototype
2050	  Buffer.__proto__ = Uint8Array
2051	}
2052
2053	function allocate (that, length) {
2054	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2055	    // Return an augmented `Uint8Array` instance, for best performance
2056	    that = Buffer._augment(new Uint8Array(length))
2057	    that.__proto__ = Buffer.prototype
2058	  } else {
2059	    // Fallback: Return an object instance of the Buffer class
2060	    that.length = length
2061	    that._isBuffer = true
2062	  }
2063
2064	  var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1
2065	  if (fromPool) that.parent = rootParent
2066
2067	  return that
2068	}
2069
2070	function checked (length) {
2071	  // Note: cannot use `length < kMaxLength` here because that fails when
2072	  // length is NaN (which is otherwise coerced to zero.)
2073	  if (length >= kMaxLength()) {
2074	    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
2075	                         'size: 0x' + kMaxLength().toString(16) + ' bytes')
2076	  }
2077	  return length | 0
2078	}
2079
2080	function SlowBuffer (subject, encoding) {
2081	  if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding)
2082
2083	  var buf = new Buffer(subject, encoding)
2084	  delete buf.parent
2085	  return buf
2086	}
2087
2088	Buffer.isBuffer = function isBuffer (b) {
2089	  return !!(b != null && b._isBuffer)
2090	}
2091
2092	Buffer.compare = function compare (a, b) {
2093	  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
2094	    throw new TypeError('Arguments must be Buffers')
2095	  }
2096
2097	  if (a === b) return 0
2098
2099	  var x = a.length
2100	  var y = b.length
2101
2102	  var i = 0
2103	  var len = Math.min(x, y)
2104	  while (i < len) {
2105	    if (a[i] !== b[i]) break
2106
2107	    ++i
2108	  }
2109
2110	  if (i !== len) {
2111	    x = a[i]
2112	    y = b[i]
2113	  }
2114
2115	  if (x < y) return -1
2116	  if (y < x) return 1
2117	  return 0
2118	}
2119
2120	Buffer.isEncoding = function isEncoding (encoding) {
2121	  switch (String(encoding).toLowerCase()) {
2122	    case 'hex':
2123	    case 'utf8':
2124	    case 'utf-8':
2125	    case 'ascii':
2126	    case 'binary':
2127	    case 'base64':
2128	    case 'raw':
2129	    case 'ucs2':
2130	    case 'ucs-2':
2131	    case 'utf16le':
2132	    case 'utf-16le':
2133	      return true
2134	    default:
2135	      return false
2136	  }
2137	}
2138
2139	Buffer.concat = function concat (list, length) {
2140	  if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.')
2141
2142	  if (list.length === 0) {
2143	    return new Buffer(0)
2144	  }
2145
2146	  var i
2147	  if (length === undefined) {
2148	    length = 0
2149	    for (i = 0; i < list.length; i++) {
2150	      length += list[i].length
2151	    }
2152	  }
2153
2154	  var buf = new Buffer(length)
2155	  var pos = 0
2156	  for (i = 0; i < list.length; i++) {
2157	    var item = list[i]
2158	    item.copy(buf, pos)
2159	    pos += item.length
2160	  }
2161	  return buf
2162	}
2163
2164	function byteLength (string, encoding) {
2165	  if (typeof string !== 'string') string = '' + string
2166
2167	  var len = string.length
2168	  if (len === 0) return 0
2169
2170	  // Use a for loop to avoid recursion
2171	  var loweredCase = false
2172	  for (;;) {
2173	    switch (encoding) {
2174	      case 'ascii':
2175	      case 'binary':
2176	      // Deprecated
2177	      case 'raw':
2178	      case 'raws':
2179	        return len
2180	      case 'utf8':
2181	      case 'utf-8':
2182	        return utf8ToBytes(string).length
2183	      case 'ucs2':
2184	      case 'ucs-2':
2185	      case 'utf16le':
2186	      case 'utf-16le':
2187	        return len * 2
2188	      case 'hex':
2189	        return len >>> 1
2190	      case 'base64':
2191	        return base64ToBytes(string).length
2192	      default:
2193	        if (loweredCase) return utf8ToBytes(string).length // assume utf8
2194	        encoding = ('' + encoding).toLowerCase()
2195	        loweredCase = true
2196	    }
2197	  }
2198	}
2199	Buffer.byteLength = byteLength
2200
2201	// pre-set for values that may exist in the future
2202	Buffer.prototype.length = undefined
2203	Buffer.prototype.parent = undefined
2204
2205	function slowToString (encoding, start, end) {
2206	  var loweredCase = false
2207
2208	  start = start | 0
2209	  end = end === undefined || end === Infinity ? this.length : end | 0
2210
2211	  if (!encoding) encoding = 'utf8'
2212	  if (start < 0) start = 0
2213	  if (end > this.length) end = this.length
2214	  if (end <= start) return ''
2215
2216	  while (true) {
2217	    switch (encoding) {
2218	      case 'hex':
2219	        return hexSlice(this, start, end)
2220
2221	      case 'utf8':
2222	      case 'utf-8':
2223	        return utf8Slice(this, start, end)
2224
2225	      case 'ascii':
2226	        return asciiSlice(this, start, end)
2227
2228	      case 'binary':
2229	        return binarySlice(this, start, end)
2230
2231	      case 'base64':
2232	        return base64Slice(this, start, end)
2233
2234	      case 'ucs2':
2235	      case 'ucs-2':
2236	      case 'utf16le':
2237	      case 'utf-16le':
2238	        return utf16leSlice(this, start, end)
2239
2240	      default:
2241	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
2242	        encoding = (encoding + '').toLowerCase()
2243	        loweredCase = true
2244	    }
2245	  }
2246	}
2247
2248	Buffer.prototype.toString = function toString () {
2249	  var length = this.length | 0
2250	  if (length === 0) return ''
2251	  if (arguments.length === 0) return utf8Slice(this, 0, length)
2252	  return slowToString.apply(this, arguments)
2253	}
2254
2255	Buffer.prototype.equals = function equals (b) {
2256	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
2257	  if (this === b) return true
2258	  return Buffer.compare(this, b) === 0
2259	}
2260
2261	Buffer.prototype.inspect = function inspect () {
2262	  var str = ''
2263	  var max = exports.INSPECT_MAX_BYTES
2264	  if (this.length > 0) {
2265	    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
2266	    if (this.length > max) str += ' ... '
2267	  }
2268	  return '<Buffer ' + str + '>'
2269	}
2270
2271	Buffer.prototype.compare = function compare (b) {
2272	  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
2273	  if (this === b) return 0
2274	  return Buffer.compare(this, b)
2275	}
2276
2277	Buffer.prototype.indexOf = function indexOf (val, byteOffset) {
2278	  if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff
2279	  else if (byteOffset < -0x80000000) byteOffset = -0x80000000
2280	  byteOffset >>= 0
2281
2282	  if (this.length === 0) return -1
2283	  if (byteOffset >= this.length) return -1
2284
2285	  // Negative offsets start from the end of the buffer
2286	  if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0)
2287
2288	  if (typeof val === 'string') {
2289	    if (val.length === 0) return -1 // special case: looking for empty string always fail
2289s
2290	    return String.prototype.indexOf.call(this, val, byteOffset)
2291	  }
2292	  if (Buffer.isBuffer(val)) {
2293	    return arrayIndexOf(this, val, byteOffset)
2294	  }
2295	  if (typeof val === 'number') {
2296	    if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') {
2297	      return Uint8Array.prototype.indexOf.call(this, val, byteOffset)
2298	    }
2299	    return arrayIndexOf(this, [ val ], byteOffset)
2300	  }
2301
2302	  function arrayIndexOf (arr, val, byteOffset) {
2303	    var foundIndex = -1
2304	    for (var i = 0; byteOffset + i < arr.length; i++) {
2305	      if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) {
2306	        if (foundIndex === -1) foundIndex = i
2307	        if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex
2308	      } else {
2309	        foundIndex = -1
2310	      }
2311	    }
2312	    return -1
2313	  }
2314
2315	  throw new TypeError('val must be string, number or Buffer')
2316	}
2317
2318	// `get` is deprecated
2319	Buffer.prototype.get = function get (offset) {
2320	  console.log('.get() is deprecated. Access using array 
vendor: 6,135 bytes, lines 2320-2526
2320indexes instead.')
2321	  return this.readUInt8(offset)
2322	}
2323
2324	// `set` is deprecated
2325	Buffer.prototype.set = function set (v, offset) {
2326	  console.log('.set() is deprecated. Access using array indexes instead.')
2327	  return this.writeUInt8(v, offset)
2328	}
2329
2330	function hexWrite (buf, string, offset, length) {
2331	  offset = Number(offset) || 0
2332	  var remaining = buf.length - offset
2333	  if (!length) {
2334	    length = remaining
2335	  } else {
2336	    length = Number(length)
2337	    if (length > remaining) {
2338	      length = remaining
2339	    }
2340	  }
2341
2342	  // must be an even number of digits
2343	  var strLen = string.length
2344	  if (strLen % 2 !== 0) throw new Error('Invalid hex string')
2345
2346	  if (length > strLen / 2) {
2347	    length = strLen / 2
2348	  }
2349	  for (var i = 0; i < length; i++) {
2350	    var parsed = parseInt(string.substr(i * 2, 2), 16)
2351	    if (isNaN(parsed)) throw new Error('Invalid hex string')
2352	    buf[offset + i] = parsed
2353	  }
2354	  return i
2355	}
2356
2357	function utf8Write (buf, string, offset, length) {
2358	  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
2359	}
2360
2361	function asciiWrite (buf, string, offset, length) {
2362	  return blitBuffer(asciiToBytes(string), buf, offset, length)
2363	}
2364
2365	function binaryWrite (buf, string, offset, length) {
2366	  return asciiWrite(buf, string, offset, length)
2367	}
2368
2369	function base64Write (buf, string, offset, length) {
2370	  return blitBuffer(base64ToBytes(string), buf, offset, length)
2371	}
2372
2373	function ucs2Write (buf, string, offset, length) {
2374	  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
2375	}
2376
2377	Buffer.prototype.write = function write (string, offset, length, encoding) {
2378	  // Buffer#write(string)
2379	  if (offset === undefined) {
2380	    encoding = 'utf8'
2381	    length = this.length
2382	    offset = 0
2383	  // Buffer#write(string, encoding)
2384	  } else if (length === undefined && typeof offset === 'string') {
2385	    encoding = offset
2386	    length = this.length
2387	    offset = 0
2388	  // Buffer#write(string, offset[, length][, encoding])
2389	  } else if (isFinite(offset)) {
2390	    offset = offset | 0
2391	    if (isFinite(length)) {
2392	      length = length | 0
2393	      if (encoding === undefined) encoding = 'utf8'
2394	    } else {
2395	      encoding = length
2396	      length = undefined
2397	    }
2398	  // legacy write(string, encoding, offset, length) - remove in v0.13
2399	  } else {
2400	    var swap = encoding
2401	    encoding = offset
2402	    offset = length | 0
2403	    length = swap
2404	  }
2405
2406	  var remaining = this.length - offset
2407	  if (length === undefined || length > remaining) length = remaining
2408
2409	  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
2410	    throw new RangeError('attempt to write outside buffer bounds')
2411	  }
2412
2413	  if (!encoding) encoding = 'utf8'
2414
2415	  var loweredCase = false
2416	  for (;;) {
2417	    switch (encoding) {
2418	      case 'hex':
2419	        return hexWrite(this, string, offset, length)
2420
2421	      case 'utf8':
2422	      case 'utf-8':
2423	        return utf8Write(this, string, offset, length)
2424
2425	      case 'ascii':
2426	        return asciiWrite(this, string, offset, length)
2427
2428	      case 'binary':
2429	        return binaryWrite(this, string, offset, length)
2430
2431	      case 'base64':
2432	        // Warning: maxLength not taken into account in base64Write
2433	        return base64Write(this, string, offset, length)
2434
2435	      case 'ucs2':
2436	      case 'ucs-2':
2437	      case 'utf16le':
2438	      case 'utf-16le':
2439	        return ucs2Write(this, string, offset, length)
2440
2441	      default:
2442	        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
2443	        encoding = ('' + encoding).toLowerCase()
2444	        loweredCase = true
2445	    }
2446	  }
2447	}
2448
2449	Buffer.prototype.toJSON = function toJSON () {
2450	  return {
2451	    type: 'Buffer',
2452	    data: Array.prototype.slice.call(this._arr || this, 0)
2453	  }
2454	}
2455
2456	function base64Slice (buf, start, end) {
2457	  if (start === 0 && end === buf.length) {
2458	    return base64.fromByteArray(buf)
2459	  } else {
2460	    return base64.fromByteArray(buf.slice(start, end))
2461	  }
2462	}
2463
2464	function utf8Slice (buf, start, end) {
2465	  end = Math.min(buf.length, end)
2466	  var res = []
2467
2468	  var i = start
2469	  while (i < end) {
2470	    var firstByte = buf[i]
2471	    var codePoint = null
2472	    var bytesPerSequence = (firstByte > 0xEF) ? 4
2473	      : (firstByte > 0xDF) ? 3
2474	      : (firstByte > 0xBF) ? 2
2475	      : 1
2476
2477	    if (i + bytesPerSequence <= end) {
2478	      var secondByte, thirdByte, fourthByte, tempCodePoint
2479
2480	      switch (bytesPerSequence) {
2481	        case 1:
2482	          if (firstByte < 0x80) {
2483	            codePoint = firstByte
2484	          }
2485	          break
2486	        case 2:
2487	          secondByte = buf[i + 1]
2488	          if ((secondByte & 0xC0) === 0x80) {
2489	            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
2490	            if (tempCodePoint > 0x7F) {
2491	              codePoint = tempCodePoint
2492	            }
2493	          }
2494	          break
2495	        case 3:
2496	          secondByte = buf[i + 1]
2497	          thirdByte = buf[i + 2]
2498	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
2499	            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
2500	            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
2501	              codePoint = tempCodePoint
2502	            }
2503	          }
2504	          break
2505	        case 4:
2506	          secondByte = buf[i + 1]
2507	          thirdByte = buf[i + 2]
2508	          fourthByte = buf[i + 3]
2509	          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
2510	            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
2511	            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
2512	              codePoint = tempCodePoint
2513	            }
2514	          }
2515	      }
2516	    }
2517
2518	    if (codePoint === null) {
2519	      // we did not generate a valid codePoint so insert a
2520	      // replacement char (U+FFFD) and advance only 1 byte
2521	      codePoint = 0xFFFD
2522	      bytesPerSequence = 1
2523	    } else if (codePoint > 0xFFFF) {
2524	      // encode to utf16 (surrogate pair dance)
2525	      codePoint -= 0x10000
2526	      res.push(codePoint >>>
vendor: 2,558 bytes, lines 2526-2641
2526 10 & 0x3FF | 0xD800)
2527	      codePoint = 0xDC00 | codePoint & 0x3FF
2528	    }
2529
2530	    res.push(codePoint)
2531	    i += bytesPerSequence
2532	  }
2533
2534	  return decodeCodePointsArray(res)
2535	}
2536
2537	// Based on http://stackoverflow.com/a/22747272/680742, the browser with
2538	// the lowest limit is Chrome, with 0x10000 args.
2539	// We go 1 magnitude less, for safety
2540	var MAX_ARGUMENTS_LENGTH = 0x1000
2541
2542	function decodeCodePointsArray (codePoints) {
2543	  var len = codePoints.length
2544	  if (len <= MAX_ARGUMENTS_LENGTH) {
2545	    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
2546	  }
2547
2548	  // Decode in chunks to avoid "call stack size exceeded".
2549	  var res = ''
2550	  var i = 0
2551	  while (i < len) {
2552	    res += String.fromCharCode.apply(
2553	      String,
2554	      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
2555	    )
2556	  }
2557	  return res
2558	}
2559
2560	function asciiSlice (buf, start, end) {
2561	  var ret = ''
2562	  end = Math.min(buf.length, end)
2563
2564	  for (var i = start; i < end; i++) {
2565	    ret += String.fromCharCode(buf[i] & 0x7F)
2566	  }
2567	  return ret
2568	}
2569
2570	function binarySlice (buf, start, end) {
2571	  var ret = ''
2572	  end = Math.min(buf.length, end)
2573
2574	  for (var i = start; i < end; i++) {
2575	    ret += String.fromCharCode(buf[i])
2576	  }
2577	  return ret
2578	}
2579
2580	function hexSlice (buf, start, end) {
2581	  var len = buf.length
2582
2583	  if (!start || start < 0) start = 0
2584	  if (!end || end < 0 || end > len) end = len
2585
2586	  var out = ''
2587	  for (var i = start; i < end; i++) {
2588	    out += toHex(buf[i])
2589	  }
2590	  return out
2591	}
2592
2593	function utf16leSlice (buf, start, end) {
2594	  var bytes = buf.slice(start, end)
2595	  var res = ''
2596	  for (var i = 0; i < bytes.length; i += 2) {
2597	    res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
2598	  }
2599	  return res
2600	}
2601
2602	Buffer.prototype.slice = function slice (start, end) {
2603	  var len = this.length
2604	  start = ~~start
2605	  end = end === undefined ? len : ~~end
2606
2607	  if (start < 0) {
2608	    start += len
2609	    if (start < 0) start = 0
2610	  } else if (start > len) {
2611	    start = len
2612	  }
2613
2614	  if (end < 0) {
2615	    end += len
2616	    if (end < 0) end = 0
2617	  } else if (end > len) {
2618	    end = len
2619	  }
2620
2621	  if (end < start) end = start
2622
2623	  var newBuf
2624	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2625	    newBuf = Buffer._augment(this.subarray(start, end))
2626	  } else {
2627	    var sliceLen = end - start
2628	    newBuf = new Buffer(sliceLen, undefined)
2629	    for (var i = 0; i < sliceLen; i++) {
2630	      newBuf[i] = this[i + start]
2631	    }
2632	  }
2633
2634	  if (newBuf.length) newBuf.parent = this.parent || this
2635
2636	  return newBuf
2637	}
2638
2639	/*
2640	 * Need to make sure that buffer isn't trying to write out of bounds.
2641	 */
vendor: 10,010 bytes, lines 2642-2970
2642	function checkOffset (offset, ext, length) {
2643	  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
2644	  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
2645	}
2646
2647	Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
2648	  offset = offset | 0
2649	  byteLength = byteLength | 0
2650	  if (!noAssert) checkOffset(offset, byteLength, this.length)
2651
2652	  var val = this[offset]
2653	  var mul = 1
2654	  var i = 0
2655	  while (++i < byteLength && (mul *= 0x100)) {
2656	    val += this[offset + i] * mul
2657	  }
2658
2659	  return val
2660	}
2661
2662	Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
2663	  offset = offset | 0
2664	  byteLength = byteLength | 0
2665	  if (!noAssert) {
2666	    checkOffset(offset, byteLength, this.length)
2667	  }
2668
2669	  var val = this[offset + --byteLength]
2670	  var mul = 1
2671	  while (byteLength > 0 && (mul *= 0x100)) {
2672	    val += this[offset + --byteLength] * mul
2673	  }
2674
2675	  return val
2676	}
2677
2678	Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
2679	  if (!noAssert) checkOffset(offset, 1, this.length)
2680	  return this[offset]
2681	}
2682
2683	Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
2684	  if (!noAssert) checkOffset(offset, 2, this.length)
2685	  return this[offset] | (this[offset + 1] << 8)
2686	}
2687
2688	Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
2689	  if (!noAssert) checkOffset(offset, 2, this.length)
2690	  return (this[offset] << 8) | this[offset + 1]
2691	}
2692
2693	Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
2694	  if (!noAssert) checkOffset(offset, 4, this.length)
2695
2696	  return ((this[offset]) |
2697	      (this[offset + 1] << 8) |
2698	      (this[offset + 2] << 16)) +
2699	      (this[offset + 3] * 0x1000000)
2700	}
2701
2702	Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
2703	  if (!noAssert) checkOffset(offset, 4, this.length)
2704
2705	  return (this[offset] * 0x1000000) +
2706	    ((this[offset + 1] << 16) |
2707	    (this[offset + 2] << 8) |
2708	    this[offset + 3])
2709	}
2710
2711	Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
2712	  offset = offset | 0
2713	  byteLength = byteLength | 0
2714	  if (!noAssert) checkOffset(offset, byteLength, this.length)
2715
2716	  var val = this[offset]
2717	  var mul = 1
2718	  var i = 0
2719	  while (++i < byteLength && (mul *= 0x100)) {
2720	    val += this[offset + i] * mul
2721	  }
2722	  mul *= 0x80
2723
2724	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
2725
2726	  return val
2727	}
2728
2729	Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
2730	  offset = offset | 0
2731	  byteLength = byteLength | 0
2732	  if (!noAssert) checkOffset(offset, byteLength, this.length)
2733
2734	  var i = byteLength
2735	  var mul = 1
2736	  var val = this[offset + --i]
2737	  while (i > 0 && (mul *= 0x100)) {
2738	    val += this[offset + --i] * mul
2739	  }
2740	  mul *= 0x80
2741
2742	  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
2743
2744	  return val
2745	}
2746
2747	Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
2748	  if (!noAssert) checkOffset(offset, 1, this.length)
2749	  if (!(this[offset] & 0x80)) return (this[offset])
2750	  return ((0xff - this[offset] + 1) * -1)
2751	}
2752
2753	Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
2754	  if (!noAssert) checkOffset(offset, 2, this.length)
2755	  var val = this[offset] | (this[offset + 1] << 8)
2756	  return (val & 0x8000) ? val | 0xFFFF0000 : val
2757	}
2758
2759	Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
2760	  if (!noAssert) checkOffset(offset, 2, this.length)
2761	  var val = this[offset + 1] | (this[offset] << 8)
2762	  return (val & 0x8000) ? val | 0xFFFF0000 : val
2763	}
2764
2765	Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
2766	  if (!noAssert) checkOffset(offset, 4, this.length)
2767
2768	  return (this[offset]) |
2769	    (this[offset + 1] << 8) |
2770	    (this[offset + 2] << 16) |
2771	    (this[offset + 3] << 24)
2772	}
2773
2774	Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
2775	  if (!noAssert) checkOffset(offset, 4, this.length)
2776
2777	  return (this[offset] << 24) |
2778	    (this[offset + 1] << 16) |
2779	    (this[offset + 2] << 8) |
2780	    (this[offset + 3])
2781	}
2782
2783	Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
2784	  if (!noAssert) checkOffset(offset, 4, this.length)
2785	  return ieee754.read(this, offset, true, 23, 4)
2786	}
2787
2788	Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
2789	  if (!noAssert) checkOffset(offset, 4, this.length)
2790	  return ieee754.read(this, offset, false, 23, 4)
2791	}
2792
2793	Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
2794	  if (!noAssert) checkOffset(offset, 8, this.length)
2795	  return ieee754.read(this, offset, true, 52, 8)
2796	}
2797
2798	Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
2799	  if (!noAssert) checkOffset(offset, 8, this.length)
2800	  return ieee754.read(this, offset, false, 52, 8)
2801	}
2802
2803	function checkInt (buf, value, offset, ext, max, min) {
2804	  if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance')
2805	  if (value > max || value < min) throw new RangeError('value is out of bounds')
2806	  if (offset + ext > buf.length) throw new RangeError('index out of range')
2807	}
2808
2809	Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
2810	  value = +value
2811	  offset = offset | 0
2812	  byteLength = byteLength | 0
2813	  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
2814
2815	  var mul = 1
2816	  var i = 0
2817	  this[offset] = value & 0xFF
2818	  while (++i < byteLength && (mul *= 0x100)) {
2819	    this[offset + i] = (value / mul) & 0xFF
2820	  }
2821
2822	  return offset + byteLength
2823	}
2824
2825	Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
2826	  value = +value
2827	  offset = offset | 0
2828	  byteLength = byteLength | 0
2829	  if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0)
2830
2831	  var i = byteLength - 1
2832	  var mul = 1
2833	  this[offset + i] = value & 0xFF
2834	  while (--i >= 0 && (mul *= 0x100)) {
2835	    this[offset + i] = (value / mul) & 0xFF
2836	  }
2837
2838	  return offset + byteLength
2839	}
2840
2841	Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
2842	  value = +value
2843	  offset = offset | 0
2844	  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
2845	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
2846	  this[offset] = (value & 0xff)
2847	  return offset + 1
2848	}
2849
2850	function objectWriteUInt16 (buf, value, offset, littleEndian) {
2851	  if (value < 0) value = 0xffff + value + 1
2852	  for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) {
2853	    buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
2854	      (littleEndian ? i : 1 - i) * 8
2855	  }
2856	}
2857
2858	Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
2859	  value = +value
2860	  offset = offset | 0
2861	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
2862	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2863	    this[offset] = (value & 0xff)
2864	    this[offset + 1] = (value >>> 8)
2865	  } else {
2866	    objectWriteUInt16(this, value, offset, true)
2867	  }
2868	  return offset + 2
2869	}
2870
2871	Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
2872	  value = +value
2873	  offset = offset | 0
2874	  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
2875	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2876	    this[offset] = (value >>> 8)
2877	    this[offset + 1] = (value & 0xff)
2878	  } else {
2879	    objectWriteUInt16(this, value, offset, false)
2880	  }
2881	  return offset + 2
2882	}
2883
2884	function objectWriteUInt32 (buf, value, offset, littleEndian) {
2885	  if (value < 0) value = 0xffffffff + value + 1
2886	  for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) {
2887	    buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
2888	  }
2889	}
2890
2891	Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
2892	  value = +value
2893	  offset = offset | 0
2894	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
2895	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2896	    this[offset + 3] = (value >>> 24)
2897	    this[offset + 2] = (value >>> 16)
2898	    this[offset + 1] = (value >>> 8)
2899	    this[offset] = (value & 0xff)
2900	  } else {
2901	    objectWriteUInt32(this, value, offset, true)
2902	  }
2903	  return offset + 4
2904	}
2905
2906	Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
2907	  value = +value
2908	  offset = offset | 0
2909	  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
2910	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2911	    this[offset] = (value >>> 24)
2912	    this[offset + 1] = (value >>> 16)
2913	    this[offset + 2] = (value >>> 8)
2914	    this[offset + 3] = (value & 0xff)
2915	  } else {
2916	    objectWriteUInt32(this, value, offset, false)
2917	  }
2918	  return offset + 4
2919	}
2920
2921	Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
2922	  value = +value
2923	  offset = offset | 0
2924	  if (!noAssert) {
2925	    var limit = Math.pow(2, 8 * byteLength - 1)
2926
2927	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
2928	  }
2929
2930	  var i = 0
2931	  var mul = 1
2932	  var sub = value < 0 ? 1 : 0
2933	  this[offset] = value & 0xFF
2934	  while (++i < byteLength && (mul *= 0x100)) {
2935	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
2936	  }
2937
2938	  return offset + byteLength
2939	}
2940
2941	Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
2942	  value = +value
2943	  offset = offset | 0
2944	  if (!noAssert) {
2945	    var limit = Math.pow(2, 8 * byteLength - 1)
2946
2947	    checkInt(this, value, offset, byteLength, limit - 1, -limit)
2948	  }
2949
2950	  var i = byteLength - 1
2951	  var mul = 1
2952	  var sub = value < 0 ? 1 : 0
2953	  this[offset + i] = value & 0xFF
2954	  while (--i >= 0 && (mul *= 0x100)) {
2955	    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
2956	  }
2957
2958	  return offset + byteLength
2959	}
2960
2961	Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
2962	  value = +value
2963	  offset = offset | 0
2964	  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
2965	  if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
2966	  if (value < 0) value = 0xff + value + 1
2967	  this[offset] = (value & 0xff)
2968	  return offset + 1
2969	}
2970
vendor: 4,241 bytes, lines 2971-3094
2971	Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
2972	  value = +value
2973	  offset = offset | 0
2974	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
2975	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2976	    this[offset] = (value & 0xff)
2977	    this[offset + 1] = (value >>> 8)
2978	  } else {
2979	    objectWriteUInt16(this, value, offset, true)
2980	  }
2981	  return offset + 2
2982	}
2983
2984	Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
2985	  value = +value
2986	  offset = offset | 0
2987	  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
2988	  if (Buffer.TYPED_ARRAY_SUPPORT) {
2989	    this[offset] = (value >>> 8)
2990	    this[offset + 1] = (value & 0xff)
2991	  } else {
2992	    objectWriteUInt16(this, value, offset, false)
2993	  }
2994	  return offset + 2
2995	}
2996
2997	Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
2998	  value = +value
2999	  offset = offset | 0
3000	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
3001	  if (Buffer.TYPED_ARRAY_SUPPORT) {
3002	    this[offset] = (value & 0xff)
3003	    this[offset + 1] = (value >>> 8)
3004	    this[offset + 2] = (value >>> 16)
3005	    this[offset + 3] = (value >>> 24)
3006	  } else {
3007	    objectWriteUInt32(this, value, offset, true)
3008	  }
3009	  return offset + 4
3010	}
3011
3012	Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
3013	  value = +value
3014	  offset = offset | 0
3015	  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
3016	  if (value < 0) value = 0xffffffff + value + 1
3017	  if (Buffer.TYPED_ARRAY_SUPPORT) {
3018	    this[offset] = (value >>> 24)
3019	    this[offset + 1] = (value >>> 16)
3020	    this[offset + 2] = (value >>> 8)
3021	    this[offset + 3] = (value & 0xff)
3022	  } else {
3023	    objectWriteUInt32(this, value, offset, false)
3024	  }
3025	  return offset + 4
3026	}
3027
3028	function checkIEEE754 (buf, value, offset, ext, max, min) {
3029	  if (value > max || value < min) throw new RangeError('value is out of bounds')
3030	  if (offset + ext > buf.length) throw new RangeError('index out of range')
3031	  if (offset < 0) throw new RangeError('index out of range')
3032	}
3033
3034	function writeFloat (buf, value, offset, littleEndian, noAssert) {
3035	  if (!noAssert) {
3036	    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
3037	  }
3038	  ieee754.write(buf, value, offset, littleEndian, 23, 4)
3039	  return offset + 4
3040	}
3041
3042	Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
3043	  return writeFloat(this, value, offset, true, noAssert)
3044	}
3045
3046	Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
3047	  return writeFloat(this, value, offset, false, noAssert)
3048	}
3049
3050	function writeDouble (buf, value, offset, littleEndian, noAssert) {
3051	  if (!noAssert) {
3052	    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
3053	  }
3054	  ieee754.write(buf, value, offset, littleEndian, 52, 8)
3055	  return offset + 8
3056	}
3057
3058	Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
3059	  return writeDouble(this, value, offset, true, noAssert)
3060	}
3061
3062	Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
3063	  return writeDouble(this, value, offset, false, noAssert)
3064	}
3065
3066	// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
3067	Buffer.prototype.copy = function copy (target, targetStart, start, end) {
3068	  if (!start) start = 0
3069	  if (!end && end !== 0) end = this.length
3070	  if (targetStart >= target.length) targetStart = target.length
3071	  if (!targetStart) targetStart = 0
3072	  if (end > 0 && end < start) end = start
3073
3074	  // Copy 0 bytes; we're done
3075	  if (end === start) return 0
3076	  if (target.length === 0 || this.length === 0) return 0
3077
3078	  // Fatal error conditions
3079	  if (targetStart < 0) {
3080	    throw new RangeError('targetStart out of bounds')
3081	  }
3082	  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
3083	  if (end < 0) throw new RangeError('sourceEnd out of bounds')
3084
3085	  // Are we oob?
3086	  if (end > this.length) end = this.length
3087	  if (target.length - targetStart < end - start) {
3088	    end = target.length - targetStart + start
3089	  }
3090
3091	  var len = end - start
3092	  var i
3093
3094	  if (this === target && start < targetStart && targetStart < end) {
3095	    // descending copy from end
3096	    for (i = len - 1; i >= 0; i--) {
3097	      target[i + targetStart] = this[i + start]
3098	    }
3099	  } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
3100	    // ascending copy from start
3101	    for (i = 0; i < len; i++) {
3102	      target[i + targetStart] = this[i + start]
3103	    }
3104	  } else {
3105	    target._set(this.subarray(start, start + len), targetStart)
3106	  }
3107
3108	  return len
3109	}
3110
3111	// fill(value, start=0, end=buffer.length)
3112	Buffer.prototype.fill = function fill (value, start, end) {
3113	  if (!value) value = 0
3114	  if (!start) start = 0
3115	  if (!end) end = this.length
3116
3117	  if (end < start) throw new RangeError('end < start')
3118
3119	  // Fill 0 bytes; we're done
3120	  if (end === start) return
3121	  if (this.length === 0) return
3122
3123	  if (start < 0 || start >= this.length) throw new RangeError('start out of bounds')
3124	  if (end < 0 || end > this.length) throw new RangeError('end out of bounds')
3125
3126	  var i
3127	  if (typeof value === 'number') {
3128	    for (i = start; i < end; i++) {
3129	      this[i] = value
3130	    }
3131	  } else {
3132	    var bytes = utf8ToBytes(value.toString())
3133	    var len = bytes.length
3134	    for (i = start; i < end; i++) {
3135	      this[i] = bytes[i % len]
3136	    }
3137	  }
3138
3139	  return this
3140	}
3141
3142	/**
3143	 * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance.
3144	 * Added in Node 0.12. Only available in browsers that support ArrayBuffer.
3145	 */
3146	Buffer.prototype.toArrayBuffer = function toArrayBuffer () {
3147	  if (typeof Uint8Array !== 'undefined') {
3148	    if (Buffer.TYPED_ARRAY_SUPPORT) {
3149	      return (new Buffer(this)).buffer
3150	    } else {
3151	      var buf = new Uint8Array(this.length)
3152	      for (var i = 0, len = buf.length; i < len; i += 1) {
3153	        buf[i] = this[i]
3154	      }
3155	      return buf.buffer
3156	    }
3157	  } else {
3158	    throw new TypeError('Buffer.toArrayBuffer not supported in this browser')
3159	  }
3160	}
3161
3162	// HELPER FUNCTIONS
3163	// ================
3164
3165	var BP = Buffer.prototype
3166
3167	/**
3168	 * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods
3169	 */
3170	Buffer._augment = function _augment (arr) {
3171	  arr.constructor = Buffer
3172	  arr._isBuffer = true
3173
3174	  // save reference to original Uint8Array set method before overwriting
3175	  arr._set = arr.set
3176
3177	  // deprecated
3178	  arr.get = BP.get
3179	  arr.set = BP.set
3180
3181	  arr.write = BP.write
3182	  arr.toString = BP.toString
3183	  arr.toLocaleString = BP.toString
3184	  arr.toJSON = BP.toJSON
3185	  arr.equals = BP.equals
3186	  arr.compare = BP.compare
3187	  arr.indexOf = BP.indexOf
3188	  arr.copy = BP.copy
3189	  arr.slice = BP.slice
3190	  arr.readUIntLE = BP.readUIntLE
3191	  arr.readUIntBE = BP.readUIntBE
3192	  arr.readUInt8 = BP.readUInt8
3193	  arr.readUInt16LE = BP.readUInt16LE
3194	  arr.readUInt16BE = BP.readUInt16BE
3195	  arr.readUInt32LE = BP.readUInt32LE
3196	  arr.readUInt32BE = BP.readUInt32BE
3197	  arr.readIntLE = BP.readIntLE
3198	  arr.readIntBE = BP.readIntBE
3199	  arr.readInt8 = BP.readInt8
3200	  arr.readInt16LE = BP.readInt16LE
3201	  arr.readInt16BE = BP.readInt16BE
3202	  arr.readInt32LE = BP.readInt32LE
3203	  arr.readInt32BE = BP.readInt32BE
3204	  arr.readFloatLE = BP.readFloatLE
3205	  arr.readFloatBE = BP.readFloatBE
3206	  arr.readDoubleLE = BP.readDoubleLE
3207	  arr.readDoubleBE = BP.readDoubleBE
3208	  arr.writeUInt8 = BP.writeUInt8
3209	  arr.writeUIntLE = BP.writeUIntLE
3210	  arr.writeUIntBE = BP.writeUIntBE
3211	  arr.writeUInt16LE = BP.writeUInt16LE
3212	  arr.writeUInt16BE = BP.writeUInt16BE
3213	  arr.writeUInt32LE = BP.writeUInt32LE
3214	  arr.writeUInt32BE = BP.writeUInt32BE
3215	  arr.writeIntLE = BP.writeIntLE
3216	  arr.writeIntBE = BP.writeIntBE
3217	  arr.writeInt8 = BP.writeInt8
3218	  arr.writeInt16LE = BP.writeInt16LE
3219	  arr.writeInt16BE = BP.writeInt16BE
3220	  arr.writeInt32LE = BP.writeInt32LE
3221	  arr.writeInt32BE = BP.writeInt32BE
3222	  arr.writeFloatLE = BP.writeFloatLE
3223	  arr.writeFloatBE = BP.writeFloatBE
3224	  arr.writeDoubleLE = BP.writeDoubleLE
3225	  arr.writeDoubleBE = BP.writeDoubleBE
3226	  arr.fill = BP.fill
3227	  arr.inspect = BP.inspect
3228	  arr.toArrayBuffer = BP.toArrayBuffer
3229
3230	  return arr
3231	}
3232
3233	var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
3234
3235	function base64clean (str) {
3236	  // Node strips out invalid characters like \n and \t from the string, base64-js does not
3237	  str = stringtrim(str).replace(INVALID_BASE64_RE, '')
3238	  // Node converts strings with length < 2 to ''
3239	  if (str.length < 2) return ''
3240	  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
3241	  while (str.length % 4 !== 0) {
3242	    str = str + '='
3243	  }
3244	  return str
3245	}
3246
3247	function stringtrim (str) {
3248	  if (str.trim) return str.trim()
3249	  return str.replace(/^\s+|\s+$/g, '')
3250	}
3251
3252	function toHex (n) {
3253	  if (n < 16) return '0' + n.toString(16)
3254	  return n.toString(16)
3255	}
3256
3257	function utf8ToBytes (string, units) {
3258	  units = units || Infinity
3259	  var codePoint
3260	  var length = string.length
3261	  var leadSurrogate = null
3262	  var bytes = []
3263
3264	  for (var i = 0; i < length; i++) {
3265	    codePoint = string.charCodeAt(i)
3266
3267	    // is surrogate component
3268	    if (codePoint > 0xD7FF && codePoint < 0xE000) {
3269	      // last char was a lead
3270	      if (!leadSurrogate) {
3271	        // no lead yet
3272	        if (codePoint > 0xDBFF) {
3273	          // unexpected trail
3274	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
3275	          continue
3276	        } else if (i + 1 === length) {
3277	          // unpaired lead
3278	          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
3279	          continue
3280	        }
3281
3282	        // valid lead
3283	        leadSurrogate = codePoint
3284
3285	        continue
3286	      }
3287
3288	      // 2 leads in a row
3289	      if (codePoint < 0xDC00) {
3290	        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
3291	        leadSurrogate = codePoint
3292	        continue
3293	      }
3294
3295	      // valid surrogate pair
3296	      codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000
3297	    } else if (leadSurrogate) {
3298	      // valid bmp char, but last char was a lead
3299	      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
3300	    }
3301
3302	    leadSurrogate = null
3303
3304	    // encode utf8
3305	    if (codePoint < 0x80) {
3306	      if ((units -= 1) < 0) break
3307	      bytes.push(codePoint)
3308	    } else if (codePoint < 0x800) {
3309	      if ((units -= 2) < 0) break
3310	      bytes.push(
3311	        codePoint >> 0x6 | 0xC0,
vendor: 5,230 bytes, lines 3312-3503
3312	        codePoint & 0x3F | 0x80
3313	      )
3314	    } else if (codePoint < 0x10000) {
3315	      if ((units -= 3) < 0) break
3316	      bytes.push(
3317	        codePoint >> 0xC | 0xE0,
3318	        codePoint >> 0x6 & 0x3F | 0x80,
3319	        codePoint & 0x3F | 0x80
3320	      )
3321	    } else if (codePoint < 0x110000) {
3322	      if ((units -= 4) < 0) break
3323	      bytes.push(
3324	        codePoint >> 0x12 | 0xF0,
3325	        codePoint >> 0xC & 0x3F | 0x80,
3326	        codePoint >> 0x6 & 0x3F | 0x80,
3327	        codePoint & 0x3F | 0x80
3328	      )
3329	    } else {
3330	      throw new Error('Invalid code point')
3331	    }
3332	  }
3333
3334	  return bytes
3335	}
3336
3337	function asciiToBytes (str) {
3338	  var byteArray = []
3339	  for (var i = 0; i < str.length; i++) {
3340	    // Node's code seems to be doing this and not & 0x7F..
3341	    byteArray.push(str.charCodeAt(i) & 0xFF)
3342	  }
3343	  return byteArray
3344	}
3345
3346	function utf16leToBytes (str, units) {
3347	  var c, hi, lo
3348	  var byteArray = []
3349	  for (var i = 0; i < str.length; i++) {
3350	    if ((units -= 2) < 0) break
3351
3352	    c = str.charCodeAt(i)
3353	    hi = c >> 8
3354	    lo = c % 256
3355	    byteArray.push(lo)
3356	    byteArray.push(hi)
3357	  }
3358
3359	  return byteArray
3360	}
3361
3362	function base64ToBytes (str) {
3363	  return base64.toByteArray(base64clean(str))
3364	}
3365
3366	function blitBuffer (src, dst, offset, length) {
3367	  for (var i = 0; i < length; i++) {
3368	    if ((i + offset >= dst.length) || (i >= src.length)) break
3369	    dst[i + offset] = src[i]
3370	  }
3371	  return i
3372	}
3373
3374	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6).Buffer, (function() { return this; }())))
3375
3376/***/ },
3377/* 7 */
3378/***/ function(module, exports, __webpack_require__) {
3379
3380	var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
3381
3382	;(function (exports) {
3383		'use strict';
3384
3385	  var Arr = (typeof Uint8Array !== 'undefined')
3386	    ? Uint8Array
3387	    : Array
3388
3389		var PLUS   = '+'.charCodeAt(0)
3390		var SLASH  = '/'.charCodeAt(0)
3391		var NUMBER = '0'.charCodeAt(0)
3392		var LOWER  = 'a'.charCodeAt(0)
3393		var UPPER  = 'A'.charCodeAt(0)
3394		var PLUS_URL_SAFE = '-'.charCodeAt(0)
3395		var SLASH_URL_SAFE = '_'.charCodeAt(0)
3396
3397		function decode (elt) {
3398			var code = elt.charCodeAt(0)
3399			if (code === PLUS ||
3400			    code === PLUS_URL_SAFE)
3401				return 62 // '+'
3402			if (code === SLASH ||
3403			    code === SLASH_URL_SAFE)
3404				return 63 // '/'
3405			if (code < NUMBER)
3406				return -1 //no match
3407			if (code < NUMBER + 10)
3408				return code - NUMBER + 26 + 26
3409			if (code < UPPER + 26)
3410				return code - UPPER
3411			if (code < LOWER + 26)
3412				return code - LOWER + 26
3413		}
3414
3415		function b64ToByteArray (b64) {
3416			var i, j, l, tmp, placeHolders, arr
3417
3418			if (b64.length % 4 > 0) {
3419				throw new Error('Invalid string. Length must be a multiple of 4')
3420			}
3421
3422			// the number of equal signs (place holders)
3423			// if there are two placeholders, than the two characters before it
3424			// represent one byte
3425			// if there is only one, then the three characters before it represent 2 bytes
3426			// this is just a cheap hack to not do indexOf twice
3427			var len = b64.length
3428			placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0
3429
3430			// base64 is 4/3 + up to two characters of the original data
3431			arr = new Arr(b64.length * 3 / 4 - placeHolders)
3432
3433			// if there are placeholders, only get up to the last complete 4 chars
3434			l = placeHolders > 0 ? b64.length - 4 : b64.length
3435
3436			var L = 0
3437
3438			function push (v) {
3439				arr[L++] = v
3440			}
3441
3442			for (i = 0, j = 0; i < l; i += 4, j += 3) {
3443				tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3))
3444				push((tmp & 0xFF0000) >> 16)
3445				push((tmp & 0xFF00) >> 8)
3446				push(tmp & 0xFF)
3447			}
3448
3449			if (placeHolders === 2) {
3450				tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4)
3451				push(tmp & 0xFF)
3452			} else if (placeHolders === 1) {
3453				tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2)
3454				push((tmp >> 8) & 0xFF)
3455				push(tmp & 0xFF)
3456			}
3457
3458			return arr
3459		}
3460
3461		function uint8ToBase64 (uint8) {
3462			var i,
3463				extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes
3464				output = "",
3465				temp, length
3466
3467			function encode (num) {
3468				return lookup.charAt(num)
3469			}
3470
3471			function tripletToBase64 (num) {
3472				return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F)
3473			}
3474
3475			// go through the array every three bytes, we'll deal with trailing stuff later
3476			for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) {
3477				temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
3478				output += tripletToBase64(temp)
3479			}
3480
3481			// pad the end with zeros, but make sure to not forget the extra bytes
3482			switch (extraBytes) {
3483				case 1:
3484					temp = uint8[uint8.length - 1]
3485					output += encode(temp >> 2)
3486					output += encode((temp << 4) & 0x3F)
3487					output += '=='
3488					break
3489				case 2:
3490					temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1])
3491					output += encode(temp >> 10)
3492					output += encode((temp >> 4) & 0x3F)
3493					output += encode((temp << 2) & 0x3F)
3494					output += '='
3495					break
3496			}
3497
3498			return output
3499		}
3500
3501		exports.toByteArray = b64ToByteArray
3502		exports.fromByteArray = uint8ToBase64
3503	}( false ? (this.base64js = {}
3503) : exports))
3504
3505
3506/***/ },
3507/* 8 */
3508/***/ function(module, exports) {
3509
3510	exports.read = function (buffer, offset, isLE, mLen, nBytes) {
3511	  var e, m
3512	  var eLen = nBytes * 8 - mLen - 1
3513	  var eMax = (1 << eLen) - 1
3514	  var eBias = eMax >> 1
3515	  var nBits = -7
3516	  var i = isLE ? (nBytes - 1) : 0
3517	  var d = isLE ? -1 : 1
3518	  var s = buffer[offset + i]
3519
3520	  i += d
3521
3522	  e = s & ((1 << (-nBits)) - 1)
3523	  s >>= (-nBits)
3524	  nBits += eLen
3525	  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
3526
3527	  m = e & ((1 << (-nBits)) - 1)
3528	  e >>= (-nBits)
3529	  nBits += mLen
3530	  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
3531
3532	  if (e === 0) {
3533	    e = 1 - eBias
3534	  } else if (e === eMax) {
3535	    return m ? NaN : ((s ? -1 : 1) * Infinity)
3536	  } else {
3537	    m = m + Math.pow(2, mLen)
3538	    e = e - eBias
3539	  }
3540	  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
3541	}
3542
3543	exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
3544	  var e, m, c
3545	  var eLen = nBytes * 8 - mLen - 1
3546	  var eMax = (1 << eLen) - 1
3547	  var eBias = eMax >> 1
3548	  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
3549	  var i = isLE ? 0 : (nBytes - 1)
3550	  var d = isLE ? 1 : -1
3551	  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
3552
3553	  value = Math.abs(value)
3554
3555	  if (isNaN(value) || value === Infinity) {
3556	    m = isNaN(value) ? 1 : 0
3557	    e = eMax
3558	  } else {
3559	    e = Math.floor(Math.log(value) / Math.LN2)
3560	    if (value * (c = Math.pow(2, -e)) < 1) {
3561	      e--
3562	      c *= 2
3563	    }
3564	    if (e + eBias >= 1) {
3565	      value += rt / c
3566	    } else {
3567	      value += rt * Math.pow(2, 1 - eBias)
3568	    }
3569	    if (value * c >= 2) {
3570	      e++
3571	      c /= 2
3572	    }
3573
3574	    if (e + eBias >= eMax) {
3575	      m = 0
3576	      e = eMax
3577	    } else if (e + eBias >= 1) {
3578	      m = (value * c - 1) * Math.pow(2, mLen)
3579	      e = e + eBias
3580	    } else {
3581	      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
3582	      e = 0
3583	    }
3584	  }
3585
3586	  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
3587
3588	  e = (e << mLen) | m
3589	  eLen += mLen
3590	  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
3591
3592	  buffer[offset + i - d] |= s * 128
3593	}
3594
3595
3596/***/ },
3597/* 9 */
3598/***/ function(module, exports) {
3599
3600	
3601	/**
3602	 * isArray
3603	 */
3604
3605	var isArray = Array.isArray;
3606
3607	/**
3608	 * toString
3609	 */
3610
3611	var str = Object.prototype.toString;
3612
3613	/**
3614	 * Whether or not the given `val`
3615	 * is an array.
3616	 *
3617	 * example:
3618	 *
3619	 *        isArray([]);
3620	 *        // > true
3621	 *        isArray(arguments);
3622	 *        // > false
3623	 *        isArray('');
3624	 *        // > false
3625	 *
3626	 * @param {mixed} val
3627	 * @return {bool}
3628	 */
3629
3630	module.exports = isArray || function (val) {
3631	  return !! val && '[object Array]' == str.call(val);
3632	};
3633
3634
3635/***/ },
3636/* 10 */
3637/***/ function(module, exports) {
3638
3639	var SceneGraph = function(sceneProperties) {
3640	    var nodeCount = 1;
3641
3642	    //todo: move merge to helpers section
3643	    function merge(parent, child) {
3644	        for (var prop in child) {
3645	            parent[prop] = child[prop];
3646	        }
3647	        return parent;
3648	    }
3649
3650	    var SceneNode = function(name) {
3651	        nodeCount++;
3652	        this.parent = null;
3653	        this.children = {};
3654	        this.id = nodeCount;
3655	        this.name = 'n' + nodeCount;
3656	        if (typeof name !== 'undefined') {
3657	            this.name = name;
3658	        }
3659	        this.x = this.y = this.z = 0;
3660	        this.width = this.height = 0;
3661	    };
3662
3663	    SceneNode.prototype.resize = function(width, height) {
3664	        if (width != null) {
3665	            this.width = width;
3666	        }
3667	        if (height != null) {
3668	            this.height = height;
3669	        }
3670	    };
3671
3672	    SceneNode.prototype.moveTo = function(x, y, z) {
3673	        this.x = x != null ? x : this.x;
3674	        this.y = y != null ? y : this.y;
3675	        this.z = z != null ? z : this.z;
3676	    };
3677
3678	    SceneNode.prototype.add = function(child) {
3679	        var name = child.name;
3680	        if (typeof this.children[name] === 'undefined') {
3681	            this.children[name] = child;
3682	            child.parent = this;
3683	        } else {
vendor: 19,580 bytes, lines 3684-4449
3684	            throw 'SceneGraph: child already exists: ' + name;
3685	        }
3686	    };
3687
3688	    var RootNode = function() {
3689	        SceneNode.call(this, 'root');
3690	        this.properties = sceneProperties;
3691	    };
3692
3693	    RootNode.prototype = new SceneNode();
3694
3695	    var Shape = function(name, props) {
3696	        SceneNode.call(this, name);
3697	        this.properties = {
3698	            'fill': '#000000'
3699	        };
3700	        if (typeof props !== 'undefined') {
3701	            merge(this.properties, props);
3702	        } else if (typeof name !== 'undefined' && typeof name !== 'string') {
3703	            throw 'SceneGraph: invalid node name';
3704	        }
3705	    };
3706
3707	    Shape.prototype = new SceneNode();
3708
3709	    var Group = function() {
3710	        Shape.apply(this, arguments);
3711	        this.type = 'group';
3712	    };
3713
3714	    Group.prototype = new Shape();
3715
3716	    var Rect = function() {
3717	        Shape.apply(this, arguments);
3718	        this.type = 'rect';
3719	    };
3720
3721	    Rect.prototype = new Shape();
3722
3723	    var Text = function(text) {
3724	        Shape.call(this);
3725	        this.type = 'text';
3726	        this.properties.text = text;
3727	    };
3728
3729	    Text.prototype = new Shape();
3730
3731	    var root = new RootNode();
3732
3733	    this.Shape = {
3734	        'Rect': Rect,
3735	        'Text': Text,
3736	        'Group': Group
3737	    };
3738
3739	    this.root = root;
3740	    return this;
3741	};
3742
3743	module.exports = SceneGraph;
3744
3745
3746/***/ },
3747/* 11 */
3748/***/ function(module, exports) {
3749
3750	/* WEBPACK VAR INJECTION */(function(global) {/**
3751	 * Shallow object clone and merge
3752	 *
3753	 * @param a Object A
3754	 * @param b Object B
3755	 * @returns {Object} New object with all of A's properties, and all of B's properties, overwriting A's properties
3756	 */
3757	exports.extend = function(a, b) {
3758	    var c = {};
3759	    for (var x in a) {
3760	        if (a.hasOwnProperty(x)) {
3761	            c[x] = a[x];
3762	        }
3763	    }
3764	    if (b != null) {
3765	        for (var y in b) {
3766	            if (b.hasOwnProperty(y)) {
3767	                c[y] = b[y];
3768	            }
3769	        }
3770	    }
3771	    return c;
3772	};
3773
3774	/**
3775	 * Takes a k/v list of CSS properties and returns a rule
3776	 *
3777	 * @param props CSS properties object
3778	 */
3779	exports.cssProps = function(props) {
3780	    var ret = [];
3781	    for (var p in props) {
3782	        if (props.hasOwnProperty(p)) {
3783	            ret.push(p + ':' + props[p]);
3784	        }
3785	    }
3786	    return ret.join(';');
3787	};
3788
3789	/**
3790	 * Encodes HTML entities in a string
3791	 *
3792	 * @param str Input string
3793	 */
3794	exports.encodeHtmlEntity = function(str) {
3795	    var buf = [];
3796	    var charCode = 0;
3797	    for (var i = str.length - 1; i >= 0; i--) {
3798	        charCode = str.charCodeAt(i);
3799	        if (charCode > 128) {
3800	            buf.unshift(['&#', charCode, ';'].join(''));
3801	        } else {
3802	            buf.unshift(str[i]);
3803	        }
3804	    }
3805	    return buf.join('');
3806	};
3807
3808	/**
3809	 * Checks if an image exists
3810	 *
3811	 * @param src URL of image
3812	 * @param callback Callback to call once image status has been found
3813	 */
3814	exports.imageExists = function(src, callback) {
3815	    var image = new Image();
3816	    image.onerror = function() {
3817	        callback.call(this, false);
3818	    };
3819	    image.onload = function() {
3820	        callback.call(this, true);
3821	    };
3822	    image.src = src;
3823	};
3824
3825	/**
3826	 * Decodes HTML entities in a string
3827	 *
3828	 * @param str Input string
3829	 */
3830	exports.decodeHtmlEntity = function(str) {
3831	    return str.replace(/&#(\d+);/g, function(match, dec) {
3832	        return String.fromCharCode(dec);
3833	    });
3834	};
3835
3836
3837	/**
3838	 * Returns an element's dimensions if it's visible, `false` otherwise.
3839	 *
3840	 * @param el DOM element
3841	 */
3842	exports.dimensionCheck = function(el) {
3843	    var dimensions = {
3844	        height: el.clientHeight,
3845	        width: el.clientWidth
3846	    };
3847
3848	    if (dimensions.height && dimensions.width) {
3849	        return dimensions;
3850	    } else {
3851	        return false;
3852	    }
3853	};
3854
3855
3856	/**
3857	 * Returns true if value is truthy or if it is "semantically truthy"
3858	 * @param val
3859	 */
3860	exports.truthy = function(val) {
3861	    if (typeof val === 'string') {
3862	        return val === 'true' || val === 'yes' || val === '1' || val === 'on' || val === '✓';
3863	    }
3864	    return !!val;
3865	};
3866
3867	/**
3868	 * Parses input into a well-formed CSS color
3869	 * @param val
3870	 */
3871	exports.parseColor = function(val) {
3872	    var hexre = /(^(?:#?)[0-9a-f]{6}$)|(^(?:#?)[0-9a-f]{3}$)/i;
3873	    var rgbre = /^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
3874	    var rgbare = /^rgba\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0\.\d{1,}|1)\)$/;
3875
3876	    var match = val.match(hexre);
3877	    var retval;
3878
3879	    if (match !== null) {
3880	        retval = match[1] || match[2];
3881	        if (retval[0] !== '#') {
3882	            return '#' + retval;
3883	        } else {
3884	            return retval;
3885	        }
3886	    }
3887
3888	    match = val.match(rgbre);
3889
3890	    if (match !== null) {
3891	        retval = 'rgb(' + match.slice(1).join(',') + ')';
3892	        return retval;
3893	    }
3894
3895	    match = val.match(rgbare);
3896
3897	    if (match !== null) {
3898	        retval = 'rgba(' + match.slice(1).join(',') + ')';
3899	        return retval;
3900	    }
3901
3902	    return null;
3903	};
3904
3905	/**
3906	 * Provides the correct scaling ratio for canvas drawing operations on HiDPI screens (e.g. Retina displays)
3907	 */
3908	exports.canvasRatio = function () {
3909	    var devicePixelRatio = 1;
3910	    var backingStoreRatio = 1;
3911
3912	    if (global.document) {
3913	        var canvas = global.document.createElement('canvas');
3914	        if (canvas.getContext) {
3915	            var ctx = canvas.getContext('2d');
3916	            devicePixelRatio = global.devicePixelRatio || 1;
3917	            backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
3918	        }
3919	    }
3920
3921	    return devicePixelRatio / backingStoreRatio;
3922	};
3923	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
3924
3925/***/ },
3926/* 12 */
3927/***/ function(module, exports, __webpack_require__) {
3928
3929	/* WEBPACK VAR INJECTION */(function(global) {var DOM = __webpack_require__(13);
3930
3931	var SVG_NS = 'http://www.w3.org/2000/svg';
3932	var NODE_TYPE_COMMENT = 8;
3933
3934	/**
3935	 * Generic SVG element creation function
3936	 *
3937	 * @param svg SVG context, set to null if new
3938	 * @param width Document width
3939	 * @param height Document height
3940	 */
3941	exports.initSVG = function(svg, width, height) {
3942	    var defs, style, initialize = false;
3943
3944	    if (svg && svg.querySelector) {
3945	        style = svg.querySelector('style');
3946	        if (style === null) {
3947	            initialize = true;
3948	        }
3949	    } else {
3950	        svg = DOM.newEl('svg', SVG_NS);
3951	        initialize = true;
3952	    }
3953
3954	    if (initialize) {
3955	        defs = DOM.newEl('defs', SVG_NS);
3956	        style = DOM.newEl('style', SVG_NS);
3957	        DOM.setAttr(style, {
3958	            'type': 'text/css'
3959	        });
3960	        defs.appendChild(style);
3961	        svg.appendChild(defs);
3962	    }
3963
3964	    //IE throws an exception if this is set and Chrome requires it to be set
3965	    if (svg.webkitMatchesSelector) {
3966	        svg.setAttribute('xmlns', SVG_NS);
3967	    }
3968
3969	    //Remove comment nodes
3970	    for (var i = 0; i < svg.childNodes.length; i++) {
3971	        if (svg.childNodes[i].nodeType === NODE_TYPE_COMMENT) {
3972	            svg.removeChild(svg.childNodes[i]);
3973	        }
3974	    }
3975
3976	    //Remove CSS
3977	    while (style.childNodes.length) {
3978	        style.removeChild(style.childNodes[0]);
3979	    }
3980
3981	    DOM.setAttr(svg, {
3982	        'width': width,
3983	        'height': height,
3984	        'viewBox': '0 0 ' + width + ' ' + height,
3985	        'preserveAspectRatio': 'none'
3986	    });
3987
3988	    return svg;
3989	};
3990
3991	/**
3992	 * Converts serialized SVG to a string suitable for data URI use
3993	 * @param svgString Serialized SVG string
3994	 * @param [base64] Use base64 encoding for data URI
3995	 */
3996	exports.svgStringToDataURI = function() {
3997	    var rawPrefix = 'data:image/svg+xml;charset=UTF-8,';
3998	    var base64Prefix = 'data:image/svg+xml;charset=UTF-8;base64,';
3999
4000	    return function(svgString, base64) {
4001	        if (base64) {
4002	            return base64Prefix + btoa(global.unescape(encodeURIComponent(svgString)));
4003	        } else {
4004	            return rawPrefix + encodeURIComponent(svgString);
4005	        }
4006	    };
4007	}();
4008
4009	/**
4010	 * Returns serialized SVG with XML processing instructions
4011	 *
4012	 * @param svg SVG context
4013	 * @param stylesheets CSS stylesheets to include
4014	 */
4015	exports.serializeSVG = function(svg, engineSettings) {
4016	    if (!global.XMLSerializer) return;
4017	    var serializer = new XMLSerializer();
4018	    var svgCSS = '';
4019	    var stylesheets = engineSettings.stylesheets;
4020
4021	    //External stylesheets: Processing Instruction method
4022	    if (engineSettings.svgXMLStylesheet) {
4023	        var xml = DOM.createXML();
4024	        //Add <?xml-stylesheet ?> directives
4025	        for (var i = stylesheets.length - 1; i >= 0; i--) {
4026	            var csspi = xml.createProcessingInstruction('xml-stylesheet', 'href="' + stylesheets[i] + '" rel="stylesheet"');
4027	            xml.insertBefore(csspi, xml.firstChild);
4028	        }
4029
4030	        xml.removeChild(xml.documentElement);
4031	        svgCSS = serializer.serializeToString(xml);
4032	    }
4033
4034	    var svgText = serializer.serializeToString(svg);
4035	    svgText = svgText.replace(/\&amp;(\#[0-9]{2,}\;)/g, '&$1');
4036	    return svgCSS + svgText;
4037	};
4038
4039	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
4040
4041/***/ },
4042/* 13 */
4043/***/ function(module, exports) {
4044
4045	/* WEBPACK VAR INJECTION */(function(global) {/**
4046	 * Generic new DOM element function
4047	 *
4048	 * @param tag Tag to create
4049	 * @param namespace Optional namespace value
4050	 */
4051	exports.newEl = function(tag, namespace) {
4052	    if (!global.document) return;
4053
4054	    if (namespace == null) {
4055	        return global.document.createElement(tag);
4056	    } else {
4057	        return global.document.createElementNS(namespace, tag);
4058	    }
4059	};
4060
4061	/**
4062	 * Generic setAttribute function
4063	 *
4064	 * @param el Reference to DOM element
4065	 * @param attrs Object with attribute keys and values
4066	 */
4067	exports.setAttr = function (el, attrs) {
4068	    for (var a in attrs) {
4069	        el.setAttribute(a, attrs[a]);
4070	    }
4071	};
4072
4073	/**
4074	 * Creates a XML document
4075	 * @private
4076	 */
4077	exports.createXML = function() {
4078	    if (!global.DOMParser) return;
4079	    return new DOMParser().parseFromString('<xml />', 'application/xml');
4080	};
4081
4082	/**
4083	 * Converts a value into an array of DOM nodes
4084	 *
4085	 * @param val A string, a NodeList, a Node, or an HTMLCollection
4086	 */
4087	exports.getNodeArray = function(val) {
4088	    var retval = null;
4089	    if (typeof(val) == 'string') {
4090	        retval = document.querySelectorAll(val);
4091	    } else if (global.NodeList && val instanceof global.NodeList) {
4092	        retval = val;
4093	    } else if (global.Node && val instanceof global.Node) {
4094	        retval = [val];
4095	    } else if (global.HTMLCollection && val instanceof global.HTMLCollection) {
4096	        retval = val;
4097	    } else if (val instanceof Array) {
4098	        retval = val;
4099	    } else if (val === null) {
4100	        retval = [];
4101	    }
4102
4103	    retval = Array.prototype.slice.call(retval);
4104
4105	    return retval;
4106	};
4107
4108	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
4109
4110/***/ },
4111/* 14 */
4112/***/ function(module, exports) {
4113
4114	var Color = function(color, options) {
4115	    //todo: support rgba, hsla, and rrggbbaa notation
4116	    //todo: use CIELAB internally
4117	    //todo: add clamp function (with sign)
4118	    if (typeof color !== 'string') return;
4119
4120	    this.original = color;
4121
4122	    if (color.charAt(0) === '#') {
4123	        color = color.slice(1);
4124	    }
4125
4126	    if (/[^a-f0-9]+/i.test(color)) return;
4127
4128	    if (color.length === 3) {
4129	        color = color.replace(/./g, '$&$&');
4130	    }
4131
4132	    if (color.length !== 6) return;
4133
4134	    this.alpha = 1;
4135
4136	    if (options && options.alpha) {
4137	        this.alpha = options.alpha;
4138	    }
4139
4140	    this.set(parseInt(color, 16));
4141	};
4142
4143	//todo: jsdocs
4144	Color.rgb2hex = function(r, g, b) {
4145	    function format (decimal) {
4146	        var hex = (decimal | 0).toString(16);
4147	        if (decimal < 16) {
4148	            hex = '0' + hex;
4149	        }
4150	        return hex;
4151	    }
4152
4153	    return [r, g, b].map(format).join('');
4154	};
4155
4156	//todo: jsdocs
4157	Color.hsl2rgb = function (h, s, l) {
4158	    var H = h / 60;
4159	    var C = (1 - Math.abs(2 * l - 1)) * s;
4160	    var X = C * (1 - Math.abs(parseInt(H) % 2 - 1));
4161	    var m = l - (C / 2);
4162
4163	    var r = 0, g = 0, b = 0;
4164
4165	    if (H >= 0 && H < 1) {
4166	        r = C;
4167	        g = X;
4168	    } else if (H >= 1 && H < 2) {
4169	        r = X;
4170	        g = C;
4171	    } else if (H >= 2 && H < 3) {
4172	        g = C;
4173	        b = X;
4174	    } else if (H >= 3 && H < 4) {
4175	        g = X;
4176	        b = C;
4177	    } else if (H >= 4 && H < 5) {
4178	        r = X;
4179	        b = C;
4180	    } else if (H >= 5 && H < 6) {
4181	        r = C;
4182	        b = X;
4183	    }
4184
4185	    r += m;
4186	    g += m;
4187	    b += m;
4188
4189	    r = parseInt(r * 255);
4190	    g = parseInt(g * 255);
4191	    b = parseInt(b * 255);
4192
4193	    return [r, g, b];
4194	};
4195
4196	/**
4197	 * Sets the color from a raw RGB888 integer
4198	 * @param raw RGB888 representation of color
4199	 */
4200	//todo: refactor into a static method
4201	//todo: factor out individual color spaces
4202	//todo: add HSL, CIELAB, and CIELUV
4203	Color.prototype.set = function (val) {
4204	    this.raw = val;
4205
4206	    var r = (this.raw & 0xFF0000) >> 16;
4207	    var g = (this.raw & 0x00FF00) >> 8;
4208	    var b = (this.raw & 0x0000FF);
4209
4210	    // BT.709
4211	    var y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
4212	    var u = -0.09991 * r - 0.33609 * g + 0.436 * b;
4213	    var v = 0.615 * r - 0.55861 * g - 0.05639 * b;
4214
4215	    this.rgb = {
4216	        r: r,
4217	        g: g,
4218	        b: b
4219	    };
4220
4221	    this.yuv = {
4222	        y: y,
4223	        u: u,
4224	        v: v
4225	    };
4226
4227	    return this;
4228	};
4229
4230	/**
4231	 * Lighten or darken a color
4232	 * @param multiplier Amount to lighten or darken (-1 to 1)
4233	 */
4234	Color.prototype.lighten = function(multiplier) {
4235	    var cm = Math.min(1, Math.max(0, Math.abs(multiplier))) * (multiplier < 0 ? -1 : 1);
4236	    var bm = (255 * cm) | 0;
4237	    var cr = Math.min(255, Math.max(0, this.rgb.r + bm));
4238	    var cg = Math.min(255, Math.max(0, this.rgb.g + bm));
4239	    var cb = Math.min(255, Math.max(0, this.rgb.b + bm));
4240	    var hex = Color.rgb2hex(cr, cg, cb);
4241	    return new Color(hex);
4242	};
4243
4244	/**
4245	 * Output color in hex format
4246	 * @param addHash Add a hash character to the beginning of the output
4247	 */
4248	Color.prototype.toHex = function(addHash) {
4249	    return (addHash ? '#' : '') + this.raw.toString(16);
4250	};
4251
4252	/**
4253	 * Returns whether or not current color is lighter than another color
4254	 * @param color Color to compare against
4255	 */
4256	Color.prototype.lighterThan = function(color) {
4257	    if (!(color instanceof Color)) {
4258	        color = new Color(color);
4259	    }
4260
4261	    return this.yuv.y > color.yuv.y;
4262	};
4263
4264	/**
4265	 * Returns the result of mixing current color with another color
4266	 * @param color Color to mix with
4267	 * @param multiplier How much to mix with the other color
4268	 */
4269	/*
4270	Color.prototype.mix = function (color, multiplier) {
4271	    if (!(color instanceof Color)) {
4272	        color = new Color(color);
4273	    }
4274
4275	    var r = this.rgb.r;
4276	    var g = this.rgb.g;
4277	    var b = this.rgb.b;
4278	    var a = this.alpha;
4279
4280	    var m = typeof multiplier !== 'undefined' ? multiplier : 0.5;
4281
4282	    //todo: write a lerp function
4283	    r = r + m * (color.rgb.r - r);
4284	    g = g + m * (color.rgb.g - g);
4285	    b = b + m * (color.rgb.b - b);
4286	    a = a + m * (color.alpha - a);
4287
4288	    return new Color(Color.rgbToHex(r, g, b), {
4289	        'alpha': a
4290	    });
4291	};
4292	*/
4293
4294	/**
4295	 * Returns the result of blending another color on top of current color with alpha
4296	 * @param color Color to blend on top of current color, i.e. "Ca"
4297	 */
4298	//todo: see if .blendAlpha can be merged into .mix
4299	Color.prototype.blendAlpha = function(color) {
4300	    if (!(color instanceof Color)) {
4301	        color = new Color(color);
4302	    }
4303
4304	    var Ca = color;
4305	    var Cb = this;
4306
4307	    //todo: write alpha blending function
4308	    var r = Ca.alpha * Ca.rgb.r + (1 - Ca.alpha) * Cb.rgb.r;
4309	    var g = Ca.alpha * Ca.rgb.g + (1 - Ca.alpha) * Cb.rgb.g;
4310	    var b = Ca.alpha * Ca.rgb.b + (1 - Ca.alpha) * Cb.rgb.b;
4311
4312	    return new Color(Color.rgb2hex(r, g, b));
4313	};
4314
4315	module.exports = Color;
4316
4317
4318/***/ },
4319/* 15 */
4320/***/ function(module, exports) {
4321
4322	module.exports = {
4323	  'version': '2.9.2',
4324	  'svg_ns': 'http://www.w3.org/2000/svg'
4325	};
4326
4327/***/ },
4328/* 16 */
4329/***/ function(module, exports, __webpack_require__) {
4330
4331	var shaven = __webpack_require__(17);
4332
4333	var SVG = __webpack_require__(12);
4334	var constants = __webpack_require__(15);
4335	var utils = __webpack_require__(11);
4336
4337	var SVG_NS = constants.svg_ns;
4338
4339	var templates = {
4340	  'element': function (options) {
4341	    var tag = options.tag;
4342	    var content = options.content || '';
4343	    delete options.tag;
4344	    delete options.content;
4345	    return  [tag, content, options];
4346	  }
4347	};
4348
4349	//todo: deprecate tag arg, infer tag from shape object
4350	function convertShape (shape, tag) {
4351	  return templates.element({
4352	    'tag': tag,
4353	    'width': shape.width,
4354	    'height': shape.height,
4355	    'fill': shape.properties.fill
4356	  });
4357	}
4358
4359	function textCss (properties) {
4360	  return utils.cssProps({
4361	    'fill': properties.fill,
4362	    'font-weight': properties.font.weight,
4363	    'font-family': properties.font.family + ', monospace',
4364	    'font-size': properties.font.size + properties.font.units
4365	  });
4366	}
4367
4368	function outlinePath (bgWidth, bgHeight, outlineWidth) {
4369	  var outlineOffsetWidth = outlineWidth / 2;
4370
4371	  return [
4372	    'M', outlineOffsetWidth, outlineOffsetWidth,
4373	    'H', bgWidth - outlineOffsetWidth,
4374	    'V', bgHeight - outlineOffsetWidth,
4375	    'H', outlineOffsetWidth,
4376	    'V', 0,
4377	    'M', 0, outlineOffsetWidth,
4378	    'L', bgWidth, bgHeight - outlineOffsetWidth,
4379	    'M', 0, bgHeight - outlineOffsetWidth,
4380	    'L', bgWidth, outlineOffsetWidth
4381	  ].join(' ');
4382	}
4383
4384	module.exports = function (sceneGraph, renderSettings) {
4385	  var engineSettings = renderSettings.engineSettings;
4386	  var stylesheets = engineSettings.stylesheets;
4387	  var stylesheetXml = stylesheets.map(function (stylesheet) {
4388	    return '<?xml-stylesheet rel="stylesheet" href="' + stylesheet + '"?>';
4389	  }).join('\n');
4390
4391	  var holderId = 'holder_' + Number(new Date()).toString(16);
4392
4393	  var root = sceneGraph.root;
4394	  var textGroup = root.children.holderTextGroup;
4395
4396	  var css = '#' + holderId + ' text { ' + textCss(textGroup.properties) + ' } ';
4397
4398	  // push text down to be equally vertically aligned with canvas renderer
4399	  textGroup.y += textGroup.textPositionData.boundingBox.height * 0.8;
4400
4401	  var wordTags = [];
4402
4403	  Object.keys(textGroup.children).forEach(function (lineKey) {
4404	    var line = textGroup.children[lineKey];
4405
4406	    Object.keys(line.children).forEach(function (wordKey) {
4407	      var word = line.children[wordKey];
4408	      var x = textGroup.x + line.x + word.x;
4409	      var y = textGroup.y + line.y + word.y;
4410
4411	      var wordTag = templates.element({
4412	        'tag': 'text',
4413	        'content': word.properties.text,
4414	        'x': x,
4415	        'y': y
4416	      });
4417
4418	      wordTags.push(wordTag);
4419	    });
4420	  });
4421
4422	  var text = templates.element({
4423	    'tag': 'g',
4424	    'content': wordTags
4425	  });
4426
4427	  var outline = null;
4428
4429	  if (root.children.holderBg.properties.outline) {
4430	    var outlineProperties = root.children.holderBg.properties.outline;
4431	    outline = templates.element({
4432	      'tag': 'path',
4433	      'd': outlinePath(root.children.holderBg.width, root.children.holderBg.height, outlineProperties.width),
4434	      'stroke-width': outlineProperties.width,
4435	      'stroke': outlineProperties.fill,
4436	      'fill': 'none'
4437	    });
4438	  }
4439
4440	  var bg = convertShape(root.children.holderBg, 'rect');
4441
4442	  var sceneContent = [];
4443
4444	  sceneContent.push(bg);
4445	  if (outlineProperties) {
4446	    sceneContent.push(outline);
4447	  }
4448	  sceneContent.push(text);
4449
4450	  var scene = templates.element({
4451	    'tag': 'g',
4452	    'id': holderId,
4453	    'content': sceneContent
4454	  });
4455
4456	  var style = templates.element({
4457	    'tag': 'style',
4458	    //todo: figure out how to add CDATA directive
4459	    'content': css,
4460	    'type': 'text/css'
4461	  });
4462
4463	  var defs = templates.element({
4464	    'tag': 'defs',
4465	    'content': style
4466	  });
4467
4468	  var svg = templates.element({
4469	    'tag': 'svg',
4470	    'content': [defs, scene],
4471	    'width': root.properties.width,
4472	    'height': root.properties.height,
4473	    'xmlns': SVG_NS,
4474	    'viewBox': [0, 0, root.properties.width, root.properties.height].join(' '),
4475	    'preserveAspectRatio': 'none'
4476	  });
4477
4478	  var output = shaven(svg);
4479	  
4480	  output = stylesheetXml + output[0];
4481
4482	  var svgString = SVG.svgStringToDataURI(output, renderSettings.mode === 'background');
4483	  return svgString;
4484	};
4485
4486/***/ },
4487/* 17 */
4488/***/ function(module, exports, __webpack_require__) {
4489
4490	var escape = __webpack_require__(18)
4491
4492	// TODO: remove namespace
4493
4494	module.exports = function shaven (array, namespace, returnObject) {
4495
4496		'use strict'
4497
4498		var i = 1
4499		var doesEscape = true
4500		var HTMLString
4501		var attributeKey
4502		var callback
4503		var key
4504
4505
4506		returnObject = returnObject || {}
4507
4508
4509		function createElement (sugarString) {
4510
4511			var tags = sugarString.match(/^[\w-]+/)
4512			var element = {
4513				tag: tags ? tags[0] : 'div',
4514				attr: {},
4515				children: []
4516			}
4517			var id = sugarString.match(/#([\w-]+)/)
4518			var reference = sugarString.match(/\$([\w-]+)/)
4519			var classNames = sugarString.match(/\.[\w-]+/g)
4520
4521
4522			// Assign id if is set
4523			if (id) {
4524				element.attr.id = id[1]
4525
4526				// Add element to the return object
4527				returnObject[id[1]] = element
4528			}
4529
4530			if (reference)
4531				returnObject[reference[1]] = element
4532
4533			if (classNames)
4534				element.attr.class = classNames.join(' ').replace(/\./g, '')
4535
4536			if (sugarString.match(/&$/g))
4537				doesEscape = false
4538
4539			return element
4540		}
4541
4542		function replacer (key, value) {
4543
4544			if (value === null || value === false || value === undefined)
4545				return
4546
4547			if (typeof value !== 'string' && typeof value !== 'object')
4548				return String(value)
4549
4550			return value
4551		}
4552
4553		function escapeAttribute (string) {
4554			return (string || string === 0) ?
4555				String(string)
4556					.replace(/&/g, '&amp;')
4557					.replace(/"/g, '&quot;') :
4558				''
4559		}
4560
4561		function escapeHTML (string) {
4562			return String(string)
4563				.replace(/&/g, '&amp;')
4564				.replace(/"/g, '&quot;')
4565				.replace(/'/g, '&apos;')
4566				.replace(/</g, '&lt;')
4567				.replace(/>/g, '&gt;')
4568		}
4569
4570
4571		if (typeof array[0] === 'string')
4572			array[0] = createElement(array[0])
4573
4574		else if (Array.isArray(array[0]))
4575			i = 0
4576
4577		else
4578			throw new Error(
4579				'First element of array must be a string, ' +
4580				'or an array and not ' + JSON.stringify(array[0])
4581			)
4582
4583
4584		for (; i < array.length; i++) {
4585
4586			// Don't render element if value is false or null
4587			if (array[i] === false || array[i] === null) {
4588				array[0] = false
4589				break
4590			}
4591
4592			// Continue with next array value if current value is undefined or true
4593			else if (array[i] === undefined || array[i] === true) {
4594				continue
4595			}
4596
4597			else if (typeof array[i] === 'string') {
4598				if (doesEscape)
4599					array[i] = escapeHTML(array[i])
4600
4601				array[0].children.push(array[i])
4602			}
4603
4604			else if (typeof array[i] === 'number') {
4605
4606				array[0].children.push(array[i])
4607			}
4608
4609			else if (Array.isArray(array[i])) {
4610
4611				if (Array.isArray(array[i][0])) {
4612					array[i].reverse().forEach(function (subArray) {
4613						array.splice(i + 1, 0, subArray)
4614					})
4615
4616					if (i !== 0)
4617						continue
4618					i++
4619				}
4620
4621				shaven(array[i], namespace, returnObject)
4622
4623				if (array[i][0])
4624					array[0].children.push(array[i][0])
4625			}
4626
4627			else if (typeof array[i] === 'function')
4628				callback = array[i]
4629
4630
4631			else if (typeof array[i] === 'object') {
4632				for (attributeKey in array[i])
4633					if (array[i].hasOwnProperty(attributeKey))
4634						if (array[i][attributeKey] !== null &&
4635							array[i][attributeKey] !== false)
4636							if (attributeKey === 'style' &&
4637								typeof array[i][attributeKey] === 'object')
4638								array[0].attr[attributeKey] = JSON
4639									.stringify(array[i][attributeKey], replacer)
4640									.slice(2, -2)
4641									.replace(/","/g, ';')
4642									.replace(/":"/g, ':')
4643									.replace(/\\"/g, '\'')
4644
4645							else
4646								array[0].attr[attributeKey] = array[i][attributeKey]
4647			}
4648
4649			else
4650				throw new TypeError('"' + array[i] + '" is not allowed as a value.')
4651		}
4652
4653
4654		if (array[0] !== false) {
4655
4656			HTMLString = '<' + array[0].tag
4657
4658			for (key in array[0].attr)
4659				if (array[0].attr.hasOwnProperty(key))
4660					HTMLString += ' ' + key + '="' +
4661						escapeAttribute(array[0].attr[key]) + '"'
4662
4663			HTMLString += '>'
4664
4665			array[0].children.forEach(function (child) {
4666				HTMLString += child
4667			})
4668
4669			HTMLString += '</' + array[0].tag + '>'
4670
4671			array[0] = HTMLString
4672		}
4673
4674		// Return root element on index 0
4675		returnObject[0] = array[0]
4676
4677		if (callback)
4678			callback(array[0])
4679
4680		// returns object containing all elements with an id and the root element
4681		return returnObject
4682	}
4683
4684
4685/***/ },
4686/* 18 */
4687/***/ function(module, exports) {
4688
4689	/*!
4690	 * escape-html
4691	 * Copyright(c) 2012-2013 TJ Holowaychuk
4692	 * Copyright(c) 2015 Andreas Lubbe
4693	 * Copyright(c) 2015 Tiancheng "Timothy" Gu
4694	 * MIT Licensed
4695	 */
4696
4697	'use strict';
4698
4699	/**
4700	 * Module variables.
4701	 * @private
4702	 */
4703
4704	var matchHtmlRegExp = /["'&<>]/;
4705
4706	/**
4707	 * Module exports.
4708	 * @public
4709	 */
4710
4711	module.exports = escapeHtml;
4712
4713	/**
4714	 * Escape special characters in the given string of html.
4715	 *
4716	 * @param  {string} string The string to escape for inserting into HTML
4717	 * @return {string}
4718	 * @public
4719	 */
4720
4721	function escapeHtml(string) {
4722	  var str = '' + string;
4723	  var match = matchHtmlRegExp.exec(str);
4724
4725	  if (!match) {
4726	    return str;
4727	  }
4728
4729	  var escape;
4730	  var html = '';
4731	  var index = 0;
4732	  var lastIndex = 0;
4733
4734	  for (index = match.index; index < str.length; index++) {
4735	    switch (str.charCodeAt(index)) {
4736	      case 34: // "
4737	        escape = '&quot;';
4738	        break;
4739	      case 38: // &
4740	        escape = '&amp;';
4741	        break;
4742	      case 39: // '
4743	        escape = '&#39;';
4744	        break;
4745	      case 60: // <
4746	        escape = '&lt;';
4747	        break;
4748	      case 62: // >
4749	        escape = '&gt;';
4750	        break;
4751	      default:
4752	        continue;
4753	    }
4754
4755	    if (lastIndex !== index) {
4756	      html += str.substring(lastIndex, index);
4757	    }
4758
4759	    lastIndex = index + 1;
4760	    html += escape;
4761	  }
4762
4763	  return lastIndex !== index
4764	    ? html + str.substring(lastIndex, index)
4765	    : html;
4766	}
4767
4768
4769/***/ },
4770/* 19 */
4771/***/ function(module, exports, __webpack_require__) {
4772
4773	var DOM = __webpack_require__(13);
4774	var utils = __webpack_require__(11);
4775
4776	module.exports = (function() {
4777	    var canvas = DOM.newEl('canvas');
4778	    var ctx = null;
4779
4780	    return function(sceneGraph) {
4781	        if (ctx == null) {
4782	            ctx = canvas.getContext('2d');
4783	        }
4784
4785	        var dpr = utils.canvasRatio();
4786	        var root = sceneGraph.root;
4787	        canvas.width = dpr * root.properties.width;
4788	        canvas.height = dpr * root.properties.height ;
4789	        ctx.textBaseline = 'middle';
4790
4791	        var bg = root.children.holderBg;
4792	        var bgWidth = dpr * bg.width;
4793	        var bgHeight = dpr * bg.height;
4794	        //todo: parametrize outline width (e.g. in scene object)
4795	        var outlineWidth = 2;
4796	        var outlineOffsetWidth = outlineWidth / 2;
4797
4798	        ctx.fillStyle = bg.properties.fill;
4799	        ctx.fillRect(0, 0, bgWidth, bgHeight);
4800
4801	        if (bg.properties.outline) {
4802	            //todo: abstract this into a method
4803	            ctx.strokeStyle = bg.properties.outline.fill;
4804	            ctx.lineWidth = bg.properties.outline.width;
4805	            ctx.moveTo(outlineOffsetWidth, outlineOffsetWidth);
4806	            // TL, TR, BR, BL
4807	            ctx.lineTo(bgWidth - outlineOffsetWidth, outlineOffsetWidth);
4808	            ctx.lineTo(bgWidth - outlineOffsetWidth, bgHeight - outlineOffsetWidth);
4809	            ctx.lineTo(outlineOffsetWidth, bgHeight - outlineOffsetWidth);
4810	            ctx.lineTo(outlineOffsetWidth, outlineOffsetWidth);
4811	            // Diagonals
4812	            ctx.moveTo(0, outlineOffsetWidth);
4813	            ctx.lineTo(bgWidth, bgHeight - outlineOffsetWidth);
4814	            ctx.moveTo(0, bgHeight - outlineOffsetWidth);
4815	            ctx.lineTo(bgWidth, outlineOffsetWidth);
4816	            ctx.stroke();
4817	        }
4818
4819	        var textGroup = root.children.holderTextGroup;
4820	        ctx.font = textGroup.properties.font.weight + ' ' + (dpr * textGroup.properties.font.size) + textGroup.properties.font.units + ' ' + textGroup.properties.font.family + ', monospace';
4821	        ctx.fillStyle = textGroup.properties.fill;
4822
4823	        for (var lineKey in textGroup.children) {
4824	            var line = textGroup.children[lineKey];
4825	            for (var wordKey in line.children) {
4826	                var word = line.children[wordKey];
4827	                var x = dpr * (textGroup.x + line.x + word.x);
4828	                var y = dpr * (textGroup.y + line.y + word.y + (textGroup.properties.leading / 2));
4829
4830	                ctx.fillText(word.properties.text, x, y);
4831	            }
4832	        }
4833
4834	        return canvas.toDataURL('image/png');
4835	    };
4836	})();
4837
4838/***/ }
4839/******/ ])
4840});
4841;
4842(function(ctx, isMeteorPackage) {
4843    if (isMeteorPackage) {
4844        Holder = ctx.Holder;
4845    }
4846})(this, typeof Meteor !== 'undefined' && typeof Package !== 'undefined');

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