PageSourceSearch

https://www.yellowpagesalbania.com/js/plugins/picturefill/picturefill.js

js yellowpagesalbania.com collected 2026-10-04 20:07:32 UTC 42,604 bytes, 1,471 lines download raw bytes

vendor: 42,604 bytes, lines 1-1471
1/*! Picturefill - v3.0.2
2 * http://scottjehl.github.io/picturefill
3 * Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt;
4 *  License: MIT
5 */
6
7(function( window, document, undefined ) {
8	// Enable strict mode
9	"use strict";
10
11	// HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround)
12	document.createElement( "picture" );
13
14	var warn, eminpx, alwaysCheckWDescriptor, evalId;
15	// local object for method references and testing exposure
16	var pf = {};
17	var isSupportTestReady = false;
18	var noop = function() {};
19	var image = document.createElement( "img" );
20	var getImgAttr = image.getAttribute;
21	var setImgAttr = image.setAttribute;
22	var removeImgAttr = image.removeAttribute;
23	var docElem = document.documentElement;
24	var types = {};
25	var cfg = {
26		//resource selection:
27		algorithm: ""
28	};
29	var srcAttr = "data-pfsrc";
30	var srcsetAttr = srcAttr + "set";
31	// ua sniffing is done for undetectable img loading features,
32	// to do some non crucial perf optimizations
33	var ua = navigator.userAgent;
34	var supportAbort = (/rident/).test(ua) || ((/ecko/).test(ua) && ua.match(/rv\:(\d+)/) && RegExp.$1 > 35 );
35	var curSrcProp = "currentSrc";
36	var regWDesc = /\s+\+?\d+(e\d+)?w/;
37	var regSize = /(\([^)]+\))?\s*(.+)/;
38	var setOptions = window.picturefillCFG;
39	/**
40	 * Shortcut property for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests )
41	 */
42	// baseStyle also used by getEmValue (i.e.: width: 1em is important)
43	var baseStyle = "position:absolute;left:0;visibility:hidden;display:block;padding:0;border:none;font-size:1em;width:1em;overflow:hidden;clip:rect(0px, 0px, 0px, 0px)";
44	var fsCss = "font-size:100%!important;";
45	var isVwDirty = true;
46
47	var cssCache = {};
48	var sizeLengthCache = {};
49	var DPR = window.devicePixelRatio;
50	var units = {
51		px: 1,
52		"in": 96
53	};
54	var anchor = document.createElement( "a" );
55	/**
56	 * alreadyRun flag used for setOptions. is it true setOptions will reevaluate
57	 * @type {boolean}
58	 */
59	var alreadyRun = false;
60
61	// Reusable, non-"g" Regexes
62
63	// (Don't use \s, to avoid matching non-breaking space.)
64	var regexLeadingSpaces = /^[ \t\n\r\u000c]+/,
65	    regexLeadingCommasOrSpaces = /^[, \t\n\r\u000c]+/,
66	    regexLeadingNotSpaces = /^[^ \t\n\r\u000c]+/,
67	    regexTrailingCommas = /[,]+$/,
68	    regexNonNegativeInteger = /^\d+$/,
69
70	    // ( Positive or negative or unsigned integers or decimals, without or without exponents.
71	    // Must include at least one digit.
72	    // According to spec tests any decimal point must be followed by a digit.
73	    // No leading plus sign is allowed.)
74	    // https://html.spec.whatwg.org/multipage/infrastructure.html#valid-floating-point-number
75	    regexFloatingPoint = /^-?(?:[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
76
77	var on = function(obj, evt, fn, capture) {
78		if ( obj.addEventListener ) {
79			obj.addEventListener(evt, fn, capture || false);
80		} else if ( obj.attachEvent ) {
81			obj.attachEvent( "on" + evt, fn);
82		}
83	};
84
85	/**
86	 * simple memoize function:
87	 */
88
89	var memoize = function(fn) {
90		var cache = {};
91		return function(input) {
92			if ( !(input in cache) ) {
93				cache[ input ] = fn(input);
94			}
95			return cache[ input ];
96		};
97	};
98
99	// UTILITY FUNCTIONS
100
101	// Manual is faster than RegEx
102	// http://jsperf.com/whitespace-character/5
103	function isSpace(c) {
104		return (c === "\u0020" || // space
105		        c === "\u0009" || // horizontal tab
106		        c === "\u000A" || // new line
107		        c === "\u000C" || // form feed
108		        c === "\u000D");  // carriage return
109	}
110
111	/**
112	 * gets a mediaquery and returns a boolean or gets a css length and returns a number
113	 * @param css mediaqueries or css length
114	 * @returns {boolean|number}
115	 *
116	 * based on: https://gist.github.com/jonathantneal/db4f77009b155f083738
117	 */
118	var evalCSS = (function() {
119
120		var regLength = /^([\d\.]+)(em|vw|px)$/;
121		var replace = function() {
122			var args = arguments, index = 0, string = args[0];
123			while (++index in args) {
124				string = string.replace(args[index], args[++index]);
125			}
126			return string;
127		};
128
129		var buildStr = memoize(function(css) {
130
131			return "return " + replace((css || "").toLowerCase(),
132				// interpret `and`
133				/\band\b/g, "&&",
134
135				// interpret `,`
136				/,/g, "||",
137
138				// interpret `min-` as >=
139				/min-([a-z-\s]+):/g, "e.$1>=",
140
141				// interpret `max-` as <=
142				/max-([a-z-\s]+):/g, "e.$1<=",
143
144				//calc value
145				/calc([^)]+)/g, "($1)",
146
147				// interpret css values
148				/(\d+[\.]*[\d]*)([a-z]+)/g, "($1 * e.$2)",
149				//make eval less evil
150				/^(?!(e.[a-z]|[0-9\.&=|><\+\-\*\(\)\/])).*/ig, ""
151			) + ";";
152		});
153
154		return function(css, length) {
155			var parsedLength;
156			if (!(css in cssCache)) {
157				cssCache[css] = false;
158				if (length && (parsedLength = css.match( regLength ))) {
159					cssCache[css] = parsedLength[ 1 ] * units[parsedLength[ 2 ]];
160				} else {
161					/*jshint evil:true */
162					try{
163						cssCache[css] = new Function("e", buildStr(css))(units);
164					} catch(e) {}
165					/*jshint evil:false */
166				}
167			}
168			return cssCache[css];
169		};
170	})();
171
172	var setResolution = function( candidate, sizesattr ) {
173		if ( candidate.w ) { // h = means height: || descriptor.type === 'h' do not handle yet...
174			candidate.cWidth = pf.calcListLength( sizesattr || "100vw" );
175			candidate.res = candidate.w / candidate.cWidth ;
176		} else {
177			candidate.res = candidate.d;
178		}
179		return candidate;
180	};
181
182	/**
183	 *
184	 * @param opt
185	 */
186	var picturefill = function( opt ) {
187
188		if (!isSupportTestReady) {return;}
189
190		var elements, i, plen;
191
192		var options = opt || {};
193
194		if ( options.elements && options.elements.nodeType === 1 ) {
195			if ( options.elements.nodeName.toUpperCase() === "IMG" ) {
196				options.elements =  [ options.elements ];
197			} else {
198				options.context = options.elements;
199				options.elements =  null;
200			}
201		}
202
203		elements = options.elements || pf.qsa( (options.context || document), ( options.reevaluate || options.reselect ) ? pf.sel : pf.selShort );
204
205		if ( (plen = elements.length) ) {
206
207			pf.setupRun( options );
208			alreadyRun = true;
209
210			// Loop through all elements
211			for ( i = 0; i < plen; i++ ) {
212				pf.fillImg(elements[ i ], options);
213			}
214
215			pf.teardownRun( options );
216		}
217	};
218
219	/**
220	 * outputs a warning for the developer
221	 * @param {message}
222	 * @type {Function}
223	 */
224	warn = ( window.console && console.warn ) ?
225		function( message ) {
226			console.warn( message );
227		} :
228		noop
229	;
230
231	if ( !(curSrcProp in image) ) {
232		curSrcProp = "src";
233	}
234
235	// Add support for standard mime types.
236	types[ "image/jpeg" ] = true;
237	types[ "image/gif" ] = true;
238	types[ "image/png" ] = true;
239
240	function detectTypeSupport( type, typeUri ) {
241		// based on Modernizr's lossless img-webp test
242		// note: asynchronous
243		var image = new window.Image();
244		image.onerror = function() {
245			types[ type ] = false;
246			picturefill();
247		};
248		image.onload = function() {
249			types[ type ] = image.width === 1;
250			picturefill();
251		};
252		image.src = typeUri;
253		return "pending";
254	}
255
256	// test svg support
257	types[ "image/svg+xml" ] = document.implementation.hasFeature( "http://www.w3.org/TR/SVG11/feature#Image", "1.1" );
258
259	/**
260	 * updates the internal vW property with the current viewport width in px
261	 */
262	function updateMetrics() {
263
264		isVwDirty = false;
265		DPR = window.devicePixelRatio;
266		cssCache = {};
267		sizeLengthCache = {};
268
269		pf.DPR = DPR || 1;
270
271		units.width = Math.max(window.innerWidth || 0, docElem.clientWidth);
272		units.height = Math.max(window.innerHeight || 0, docElem.clientHeight);
273
274		units.vw = units.width / 100;
275		units.vh = units.height / 100;
276
277		evalId = [ units.height, units.width, DPR ].join("-");
278
279		units.em = pf.getEmValue();
280		units.rem = units.em;
281	}
282
283	function chooseLowRes( lowerValue, higherValue, dprValue, isCached ) {
284		var bonusFactor, tooMuch, bonus, meanDensity;
285
286		//experimental
287		if (cfg.algorithm === "saveData" ){
288			if ( lowerValue > 2.7 ) {
289				meanDensity = dprValue + 1;
290			} else {
291				tooMuch = higherValue - dprValue;
292				bonusFactor = Math.pow(lowerValue - 0.6, 1.5);
293
294				bonus = tooMuch * bonusFactor;
295
296				if (isCached) {
297					bonus += 0.1 * bonusFactor;
298				}
299
300				meanDensity = lowerValue + bonus;
301			}
302		} else {
303			meanDensity = (dprValue > 1) ?
304				Math.sqrt(lowerValue * higherValue) :
305				lowerValue;
306		}
307
308		return meanDensity > dprValue;
309	}
310
311	function applyBestCandidate( img ) {
312		var srcSetCandidates;
313		var matchingSet = pf.getSet( img );
314		var evaluated = false;
315		if ( matchingSet !== "pending" ) {
316			evaluated = evalId;
317			if ( matchingSet ) {
318				srcSetCandidates = pf.setRes( matchingSet );
319				pf.applySetCandidate( srcSetCandidates, img );
320			}
321		}
322		img[ pf.ns ].evaled = evaluated;
323	}
324
325	function ascendingSort( a, b ) {
326		return a.res - b.res;
327	}
328
329	function setSrcToCur( img, src, set ) {
330		var candidate;
331		if ( !set && src ) {
332			set = img[ pf.ns ].sets;
333			set = set && set[set.length - 1];
334		}
335
336		candidate = getCandidateForSrc(src, set);
337
338		if ( candidate ) {
339			src = pf.makeUrl(src);
340			img[ pf.ns ].curSrc = src;
341			img[ pf.ns ].curCan = candidate;
342
343			if ( !candidate.res ) {
344				setResolution( candidate, candidate.set.sizes );
345			}
346		}
347		return candidate;
348	}
349
350	function getCandidateForSrc( src, set ) {
351		var i, candidate, candidates;
352		if ( src && set ) {
353			candidates = pf.parseSet( set );
354			src = pf.makeUrl(src);
355			for ( i = 0; i < candidates.length; i++ ) {
356				if ( src === pf.makeUrl(candidates[ i ].url) ) {
357					candidate = candidates[ i ];
358					break;
359				}
360			}
361		}
362		return candidate;
363	}
364
365	function getAllSourceElements( picture, candidates ) {
366		var i, len, source, srcset;
367
368		// SPEC mismatch intended for size and perf:
369		// actually only source elements preceding the img should be used
370		// also note: don't use qsa here, because IE8 sometimes doesn't like source as the key part in a selector
371		var sources = picture.getElementsByTagName( "source" );
372
373		for ( i = 0, len = sources.length; i < len; i++ ) {
374			source = sources[ i ];
375			source[ pf.ns ] = true;
376			srcset = source.getAttribute( "srcset" );
377
378			// if source does not have a srcset attribute, skip
379			if ( srcset ) {
380				candidates.push( {
381					srcset: srcset,
382					media: source.getAttribute( "media" ),
383					type: source.getAttribute( "type" ),
384					sizes: source.getAttribute( "sizes" )
385				} );
386			}
387		}
388	}
389
390	/**
391	 * Srcset Parser
392	 * By Alex Bell |  MIT License
393	 *
394	 * @returns Array [{url: _, d: _, w: _, h:_, set:_(????)}, ...]
395	 *
396	 * Based super duper closely on the reference algorithm at:
397	 * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute
398	 */
399
400	// 1. Let input be the value passed to this algorithm.
401	// (TO-DO : Explain what "set" argument is here. Maybe choose a more
402	// descriptive & more searchable name.  Since passing the "set" in really has
403	// nothing to do with parsing proper, I would prefer this assignment eventually
404	// go in an external fn.)
405	function parseSrcset(input, set) {
406
407		function collectCharacters(regEx) {
408			var chars,
409			    match = regEx.exec(input.substring(pos));
410			if (match) {
411				chars = match[ 0 ];
412				pos += chars.length;
413				return chars;
414			}
415		}
416
417		var inputLength = input.length,
418		    url,
419		    descriptors,
420		    currentDescriptor,
421		    state,
422		    c,
423
424		    // 2. Let position be a pointer into input, initially pointing at the start
425		    //    of the string.
426		    pos = 0,
427
428		    // 3. Let candidates be an initially empty source set.
429		    candidates = [];
430
431		/**
432		* Adds descriptor properties to a candidate, pushes to the candidates array
433		* @return undefined
434		*/
435		// (Declared outside of the while loop so that it's only created once.
436		// (This fn is defined before it is used, in order to pass JSHINT.
437		// Unfortunately this breaks the sequencing of the spec comments. :/ )
438		function parseDescriptors() {
439
440			// 9. Descriptor parser: Let error be no.
441			var pError = false,
442
443			// 10. Let width be absent.
444			// 11. Let density be absent.
445			// 12. Let future-compat-h be absent. (We're implementing it now as h)
446			    w, d, h, i,
447			    candidate = {},
448			    desc, lastChar, value, intVal, floatVal;
449
450			// 13. For each descriptor in descriptors, run the appropriate set of steps
451			// from the following list:
452			for (i = 0 ; i < descriptors.length; i++) {
453				desc = descriptors[ i ];
454
455				lastChar = desc[ desc.length - 1 ];
456				value = desc.substring(0, desc.length - 1);
457				intVal = parseInt(value, 10);
458				floatVal = parseFloat(value);
459
460				// If the descriptor consists of a valid non-negative integer followed by
461				// a U+0077 LATIN SMALL LETTER W character
462				if (regexNonNegativeInteger.test(value) && (lastChar === "w")) {
463
464					// If width and density are not both absent, then let error be yes.
465					if (w || d) {pError = true;}
466
467					// Apply the rules for parsing non-negative integers to the descriptor.
468					// If the result is zero, let error be yes.
469					// Otherwise, let width be the result.
470					if (intVal === 0) {pError = true;} else {w = intVal;}
471
472				// If the descriptor consists of a valid floating-point number followed by
473				// a U+0078 LATIN SMALL LETTER X character
474				} else if (regexFloatingPoint.test(value) && (lastChar === "x")) {
475
476					// If width, density and future-compat-h are not all absent, then let error
477					// be yes.
478					if (w || d || h) {pError = true;}
479
480					// Apply the rules for parsing floating-point number values to the descriptor.
481					// If the result is less than zero, let error be yes. Otherwise, let density
482					// be the result.
483					if (floatVal < 0) {pError = true;} else {d = floatVal;}
484
485				// If the descriptor consists of a valid non-negative integer followed by
486				// a U+0068 LATIN SMALL LETTER H character
487				} else if (regexNonNegativeInteger.test(value) && (lastChar === "h")) {
488
489					// If height and density are not both absent, then let error be yes.
490					if (h || d) {pError = true;}
491
492					// Apply the rules for parsing non-negative integers to the descriptor.
493					// If the result is zero, let error be yes. Otherwise, let future-compat-h
494					// be the result.
495					if (intVal === 0) {pError = true;} else {h = intVal;}
496
497				// Anything else, Let error be yes.
498				} else {pError = true;}
499			} // (close step 13 for loop)
500
501			// 15. If error is still no, then append a new image source to candidates whose
502			// URL is url, associated with a width width if not absent and a pixel
503			// density density if not absent. Otherwise, there is a parse error.
504			if (!pError) {
505				candidate.url = url;
506
507				if (w) { candidate.w = w;}
508				if (d) { candidate.d = d;}
509				if (h) { candidate.h = h;}
510				if (!h && !d && !w) {candidate.d = 1;}
511				if (candidate.d === 1) {set.has1x = true;}
512				candidate.set = set;
513
514				candidates.push(candidate);
515			}
516		} // (close parseDescriptors fn)
517
518		/**
519		* Tokenizes descriptor properties prior to parsing
520		* Returns undefined.
521		* (Again, this fn is defined before it is used, in order to pass JSHINT.
522		* Unfortunately this breaks the logical sequencing of the spec comments. :/ )
523		*/
524		function tokenize() {
525
526			// 8.1. Descriptor tokeniser: Skip whitespace
527			collectCharacters(regexLeadingSpaces);
528
529			// 8.2. Let current descriptor be the empty string.
530			currentDescriptor = "";
531
532			// 8.3. Let state be in descriptor.
533			state = "in descriptor";
534
535			while (true) {
536
537				// 8.4. Let c be the character at position.
538				c = input.charAt(pos);
539
540				//  Do the following depending on the value of state.
541				//  For the purpose of this step, "EOF" is a special character representing
542				//  that position is past the end of input.
543
544				// In descriptor
545				if (state === "in descriptor") {
546					// Do the following, depending on the value of c:
547
548				  // Space character
549				  // If current descriptor is not empty, append current descriptor to
550				  // descriptors and let current descriptor be the empty string.
551				  // Set state to after descriptor.
552					if (isSpace(c)) {
553						if (currentDescriptor) {
554							descriptors.push(currentDescriptor);
555							currentDescriptor = "";
556							state = "after descriptor";
557						}
558
559					// U+002C COMMA (,)
560					// Advance position to the next character in input. If current descriptor
561					// is not empty, append current descriptor to descriptors. Jump to the step
562					// labeled descriptor parser.
563					} else if (c === ",") {
564						pos += 1;
565						if (currentDescriptor) {
566							descriptors.push(currentDescriptor);
567						}
568						parseDescriptors();
569						return;
570
571					// U+0028 LEFT PARENTHESIS (()
572					// Append c to current descriptor. Set state to in parens.
573					} else if (c === "\u0028") {
574						currentDescriptor = currentDescriptor + c;
575						state = "in parens";
576
577					// EOF
578					// If current descriptor is not empty, append current descriptor to
579					// descriptors. Jump to the step labeled descriptor parser.
580					} else if (c === "") {
581						if (currentDescriptor) {
582							descriptors.push(currentDescriptor);
583						}
584						parseDescriptors();
585						return;
586
587					// Anything else
588					// Append c to current descriptor.
589					} else {
590						currentDescriptor = currentDescriptor + c;
591					}
592				// (end "in descriptor"
593
594				// In parens
595				} else if (state === "in parens") {
596
597					// U+0029 RIGHT PARENTHESIS ())
598					// Append c to current descriptor. Set state to in descriptor.
599					if (c === ")") {
600						currentDescriptor = currentDescriptor + c;
601						state = "in descriptor";
602
603					// EOF
604					// Append current descriptor to descriptors. Jump to the step labeled
605					// descriptor parser.
606					} else if (c === "") {
607						descriptors.push(currentDescriptor);
608						parseDescriptors();
609						return;
610
611					// Anything else
612					// Append c to current descriptor.
613					} else {
614						currentDescriptor = currentDescriptor + c;
615					}
616
617				// After descriptor
618				} else if (state === "after descriptor") {
619
620					// Do the following, depending on the value of c:
621					// Space character: Stay in this state.
622					if (isSpace(c)) {
623
624					// EOF: Jump to the step labeled descriptor parser.
625					} else if (c === "") {
626						parseDescriptors();
627						return;
628
629					// Anything else
630					// Set state to in descriptor. Set position to the previous character in input.
631					} else {
632						state = "in descriptor";
633						pos -= 1;
634
635					}
636				}
637
638				// Advance position to the next character in input.
639				pos += 1;
640
641			// Repeat this step.
642			} // (close while true loop)
643		}
644
645		// 4. Splitting loop: Collect a sequence of characters that are space
646		//    characters or U+002C COMMA characters. If any U+002C COMMA characters
647		//    were collected, that is a parse error.
648		while (true) {
649			collectCharacters(regexLeadingCommasOrSpaces);
650
651			// 5. If position is past the end of input, return candidates and abort these steps.
652			if (pos >= inputLength) {
653				return candidates; // (we're done, this is the sole return path)
654			}
655
656			// 6. Collect a sequence of characters that are not space characters,
657			//    and let that be url.
658			url = collectCharacters(regexLeadingNotSpaces);
659
660			// 7. Let descriptors be a new empty list.
661			descriptors = [];
662
663			// 8. If url ends with a U+002C COMMA character (,), follow these substeps:
664			//		(1). Remove all trailing U+002C COMMA characters from url. If this removed
665			//         more than one character, that is a parse error.
666			if (url.slice(-1) === ",") {
667				url = url.replace(regexTrailingCommas, "");
668				// (Jump ahead to step 9 to skip tokenization and just push the candidate).
669				parseDescriptors();
670
671			//	Otherwise, follow these substeps:
672			} else {
673				tokenize();
674			} // (close else of step 8)
675
676		// 16. Return to the step labeled splitting loop.
677		} // (Close of big while loop.)
678	}
679
680	/*
681	 * Sizes Parser
682	 *
683	 * By Alex Bell |  MIT License
684	 *
685	 * Non-strict but accurate and lightweight JS Parser for the string value <img sizes="here">
686	 *
687	 * Reference algorithm at:
688	 * https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-sizes-attribute
689	 *
690	 * Most comments are copied in directly from the spec
691	 * (except for comments in parens).
692	 *
693	 * Grammar is:
694	 * <source-size-list> = <source-size># [ , <source-size-value> ]? | <source-size-value>
695	 * <source-size> = <media-condition> <source-size-value>
696	 * <source-size-value> = <length>
697	 * http://www.w3.org/html/wg/drafts/html/master/embedded-content.html#attr-img-sizes
698	 *
699	 * E.g. "(max-width: 30em) 100vw, (max-width: 50em) 70vw, 100vw"
700	 * or "(min-width: 30em), calc(30vw - 15px)" or just "30vw"
701	 *
702	 * Returns the first valid <css-length> with a media condition that evaluates to true,
703	 * or "100vw" if all valid media conditions evaluate to false.
704	 *
705	 */
706
707	function parseSizes(strValue) {
708
709		// (Percentage CSS lengths are not allowed in this case, to avoid confusion:
710		// https://html.spec.whatwg.org/multipage/embedded-content.html#valid-source-size-list
711		// CSS allows a single optional plus or minus sign:
712		// http://www.w3.org/TR/CSS2/syndata.html#numbers
713		// CSS is ASCII case-insensitive:
714		// http://www.w3.org/TR/CSS2/syndata.html#characters )
715		// Spec allows exponential notation for <number> type:
716		// http://dev.w3.org/csswg/css-values/#numbers
717		var regexCssLengthWithUnits = /^(?:[+-]?[0-9]+|[0-9]*\.[0-9]+)(?:[eE][+-]?[0-9]+)?(?:ch|cm|em|ex|in|mm|pc|pt|px|rem|vh|vmin|vmax|vw)$/i;
718
719		// (This is a quick and lenient test. Because of optional unlimited-depth internal
720		// grouping parens and strict spacing rules, this could get very complicated.)
721		var regexCssCalc = /^calc\((?:[0-9a-z \.\+\-\*\/\(\)]+)\)$/i;
722
723		var i;
724		var unparsedSizesList;
725		var unparsedSizesListLength;
726		var unparsedSize;
727		var lastComponentValue;
728		var size;
729
730		// UTILITY FUNCTIONS
731
732		//  (Toy CSS parser. The goals here are:
733		//  1) expansive test coverage without the weight of a full CSS parser.
734		//  2) Avoiding regex wherever convenient.
735		//  Quick tests: http://jsfiddle.net/gtntL4gr/3/
736		//  Returns an array of arrays.)
737		function parseComponentValues(str) {
738			var chrctr;
739			var component = "";
740			var componentArray = [];
741			var listArray = [];
742			var parenDepth = 0;
743			var pos = 0;
744			var inComment = false;
745
746			function pushComponent() {
747				if (component) {
748					componentArray.push(component);
749					component = "";
750				}
751			}
752
753			function pushComponentArray() {
754				if (componentArray[0]) {
755					listArray.push(componentArray);
756					componentArray = [];
757				}
758			}
759
760			// (Loop forwards from the beginning of the string.)
761			while (true) {
762				chrctr = str.charAt(pos);
763
764				if (chrctr === "") { // ( End of string reached.)
765					pushComponent();
766					pushComponentArray();
767					return listArray;
768				} else if (inComment) {
769					if ((chrctr === "*") && (str[pos + 1] === "/")) { // (At end of a comment.)
770						inComment = false;
771						pos += 2;
772						pushComponent();
773						continue;
774					} else {
775						pos += 1; // (Skip all characters inside comments.)
776						continue;
777					}
778				} else if (isSpace(chrctr)) {
779					// (If previous character in loop was also a space, or if
780					// at the beginning of the string, do not add space char to
781					// component.)
782					if ( (str.charAt(pos - 1) && isSpace( str.charAt(pos - 1) ) ) || !component ) {
783						pos += 1;
784						continue;
785					} else if (parenDepth === 0) {
786						pushComponent();
787						pos +=1;
788						continue;
789					} else {
790						// (Replace any space character with a plain space for legibility.)
791						chrctr = " ";
792					}
793				} else if (chrctr === "(") {
794					parenDepth += 1;
795				} else if (chrctr === ")") {
796					parenDepth -= 1;
797				} else if (chrctr === ",") {
798					pushComponent();
799					pushComponentArray();
800					pos += 1;
801					continue;
802				} else if ( (chrctr === "/") && (str.charAt(pos + 1) === "*") ) {
803					inComment = true;
804					pos += 2;
805					continue;
806				}
807
808				component = component + chrctr;
809				pos += 1;
810			}
811		}
812
813		function isValidNonNegativeSourceSizeValue(s) {
814			if (regexCssLengthWithUnits.test(s) && (parseFloat(s) >= 0)) {return true;}
815			if (regexCssCalc.test(s)) {return true;}
816			// ( http://www.w3.org/TR/CSS2/syndata.html#numbers says:
817			// "-0 is equivalent to 0 and is not a negative number." which means that
818			// unitless zero and unitless negative zero must be accepted as special cases.)
819			if ((s === "0") || (s === "-0") || (s === "+0")) {return true;}
820			return false;
821		}
822
823		// When asked to parse a sizes attribute from an element, parse a
824		// comma-separated list of component values from the value of the element's
825		// sizes attribute (or the empty string, if the attribute is absent), and let
826		// unparsed sizes list be the result.
827		// http://dev.w3.org/csswg/css-syntax/#parse-comma-separated-list-of-component-values
828
829		unparsedSizesList = parseComponentValues(strValue);
830		unparsedSizesListLength = unparsedSizesList.length;
831
832		// For each unparsed size in unparsed sizes list:
833		for (i = 0; i < unparsedSizesListLength; i++) {
834			unparsedSize = unparsedSizesList[i];
835
836			// 1. Remove all consecutive <whitespace-token>s from the end of unparsed size.
837			// ( parseComponentValues() already omits spaces outside of parens. )
838
839			// If unparsed size is now empty, that is a parse error; continue to the next
840			// iteration of this algorithm.
841			// ( parseComponentValues() won't push an empty array. )
842
843			// 2. If the last component value in unparsed size is a valid non-negative
844			// <source-size-value>, let size be its value and remove the component value
845			// from unparsed size. Any CSS function other than the calc() function is
846			// invalid. Otherwise, there is a parse error; continue to the next iteration
847			// of this algorithm.
848			// http://dev.w3.org/csswg/css-syntax/#parse-component-value
849			lastComponentValue = unparsedSize[unparsedSize.length - 1];
850
851			if (isValidNonNegativeSourceSizeValue(lastComponentValue)) {
852				size = lastComponentValue;
853				unparsedSize.pop();
854			} else {
855				continue;
856			}
857
858			// 3. Remove all consecutive <whitespace-token>s from the end of unparsed
859			// size. If unparsed size is now empty, return size and exit this algorithm.
860			// If this was not the last item in unparsed sizes list, that is a parse error.
861			if (unparsedSize.length === 0) {
862				return size;
863			}
864
865			// 4. Parse the remaining component values in unparsed size as a
866			// <media-condition>. If it does not parse correctly, or it does parse
867			// correctly but the <media-condition> evaluates to false, continue to the
868			// next iteration of this algorithm.
869			// (Parsing all possible compound media conditions in JS is heavy, complicated,
870			// and the payoff is unclear. Is there ever an situation where the
871			// media condition parses incorrectly but still somehow evaluates to true?
872			// Can we just rely on the browser/polyfill to do it?)
873			unparsedSize = unparsedSize.join(" ");
874			if (!(pf.matchesMedia( unparsedSize ) ) ) {
875				continue;
876			}
877
878			// 5. Return size and exit this algorithm.
879			return size;
880		}
881
882		// If the above algorithm exhausts unparsed sizes list without returning a
883		// size value, return 100vw.
884		return "100vw";
885	}
886
887	// namespace
888	pf.ns = ("pf" + new Date().getTime()).substr(0, 9);
889
890	// srcset support test
891	pf.supSrcset = "srcset" in image;
892	pf.supSizes = "sizes" in image;
893	pf.supPicture = !!window.HTMLPictureElement;
894
895	// UC browser does claim to support srcset and picture, but not sizes,
896	// this extended test reveals the browser does support nothing
897	if (pf.supSrcset && pf.supPicture && !pf.supSizes) {
898		(function(image2) {
899			image.srcset = "data:,a";
900			image2.src = "data:,a";
901			pf.supSrcset = image.complete === image2.complete;
902			pf.supPicture = pf.supSrcset && pf.supPicture;
903		})(document.createElement("img"));
904	}
905
906	// Safari9 has basic support for sizes, but does't expose the `sizes` idl attribute
907	if (pf.supSrcset && !pf.supSizes) {
908
909		(function() {
910			var width2 = "data:image/gif;base64,R0lGODlhAgABAPAAAP///wAAACH5BAAAAAAALAAAAAACAAEAAAICBAoAOw==";
911			var width1 = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
912			var img = document.createElement("img");
913			var test = function() {
914				var width = img.width;
915
916				if (width === 2) {
917					pf.supSizes = true;
918				}
919
920				alwaysCheckWDescriptor = pf.supSrcset && !pf.supSizes;
921
922				isSupportTestReady = true;
923				// force async
924				setTimeout(picturefill);
925			};
926
927			img.onload = test;
928			img.onerror = test;
929			img.setAttribute("sizes", "9px");
930
931			img.srcset = width1 + " 1w," + width2 + " 9w";
932			img.src = width1;
933		})();
934
935	} else {
936		isSupportTestReady = true;
937	}
938
939	// using pf.qsa instead of dom traversing does scale much better,
940	// especially on sites mixing responsive and non-responsive images
941	pf.selShort = "picture>img,img[srcset]";
942	pf.sel = pf.selShort;
943	pf.cfg = cfg;
944
945	/**
946	 * Shortcut property for `devicePixelRatio` ( for easy overriding in tests )
947	 */
948	pf.DPR = (DPR  || 1 );
949	pf.u = units;
950
951	// container of supported mime types that one might need to qualify before using
952	pf.types =  types;
953
954	pf.setSize = noop;
955
956	/**
957	 * Gets a string and returns the absolute URL
958	 * @param src
959	 * @returns {String} absolute URL
960	 */
961
962	pf.makeUrl = memoize(function(src) {
963		anchor.href = src;
964		return anchor.href;
965	});
966
967	/**
968	 * Gets a DOM element or document and a selctor and returns the found matches
969	 * Can be extended with jQuery/Sizzle for IE7 support
970	 * @param context
971	 * @param sel
972	 * @returns {NodeList|Array}
973	 */
974	pf.qsa = function(context, sel) {
975		return ( "querySelector" in context ) ? context.querySelectorAll(sel) : [];
976	};
977
978	/**
979	 * Shortcut method for matchMedia ( for easy overriding in tests )
980	 * wether native or pf.mMQ is used will be decided lazy on first call
981	 * @returns {boolean}
982	 */
983	pf.matchesMedia = function() {
984		if ( window.matchMedia && (matchMedia( "(min-width: 0.1em)" ) || {}).matches ) {
985			pf.matchesMedia = function( media ) {
986				return !media || ( matchMedia( media ).matches );
987			};
988		} else {
989			pf.matchesMedia = pf.mMQ;
990		}
991
992		return pf.matchesMedia.apply( this, arguments );
993	};
994
995	/**
996	 * A simplified matchMedia implementation for IE8 and IE9
997	 * handles only min-width/max-width with px or em values
998	 * @param media
999	 * @returns {boolean}
1000	 */
1001	pf.mMQ = function( media ) {
1002		return media ? evalCSS(media) : true;
1003	};
1004
1005	/**
1006	 * Returns the calculated length in css pixel from the given sourceSizeValue
1007	 * http://dev.w3.org/csswg/css-values-3/#length-value
1008	 * intended Spec mismatches:
1009	 * * Does not check for invalid use of CSS functions
1010	 * * Does handle a computed length of 0 the same as a negative and therefore invalid value
1011	 * @param sourceSizeValue
1012	 * @returns {Number}
1013	 */
1014	pf.calcLength = function( sourceSizeValue ) {
1015
1016		var value = evalCSS(sourceSizeValue, true) || false;
1017		if (value < 0) {
1018			value = false;
1019		}
1020
1021		return value;
1022	};
1023
1024	/**
1025	 * Takes a type string and checks if its supported
1026	 */
1027
1028	pf.supportsType = function( type ) {
1029		return ( type ) ? types[ type ] : true;
1030	};
1031
1032	/**
1033	 * Parses a sourceSize into mediaCondition (media) and sourceSizeValue (length)
1034	 * @param sourceSizeStr
1035	 * @returns {*}
1036	 */
1037	pf.parseSize = memoize(function( sourceSizeStr ) {
1038		var match = ( sourceSizeStr || "" ).match(regSize);
1039		return {
1040			media: match && match[1],
1041			length: match && match[2]
1042		};
1043	});
1044
1045	pf.parseSet = function( set ) {
1046		if ( !set.cands ) {
1047			set.cands = parseSrcset(set.srcset, set);
1048		}
1049		return set.cands;
1050	};
1051
1052	/**
1053	 * returns 1em in css px for html/body default size
1054	 * function taken from respondjs
1055	 * @returns {*|number}
1056	 */
1057	pf.getEmValue = function() {
1058		var body;
1059		if ( !eminpx && (body = document.body) ) {
1060			var div = document.createElement( "div" ),
1061				originalHTMLCSS = docElem.style.cssText,
1062				originalBodyCSS = body.style.cssText;
1063
1064			div.style.cssText = baseStyle;
1065
1066			// 1em in a media query is the value of the default font size of the browser
1067			// reset docElem and body to ensure the correct value is returned
1068			docElem.style.cssText = fsCss;
1069			body.style.cssText = fsCss;
1070
1071			body.appendChild( div );
1072			eminpx = div.offsetWidth;
1073			body.removeChild( div );
1074
1075			//also update eminpx before returning
1076			eminpx = parseFloat( eminpx, 10 );
1077
1078			// restore the original values
1079			docElem.style.cssText = originalHTMLCSS;
1080			body.style.cssText = originalBodyCSS;
1081
1082		}
1083		return eminpx || 16;
1084	};
1085
1086	/**
1087	 * Takes a string of sizes and returns the width in pixels as a number
1088	 */
1089	pf.calcListLength = function( sourceSizeListStr ) {
1090		// Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33%
1091		//
1092		//                           or (min-width:30em) calc(30% - 15px)
1093		if ( !(sourceSizeListStr in sizeLengthCache) || cfg.uT ) {
1094			var winningLength = pf.calcLength( parseSizes( sourceSizeListStr ) );
1095
1096			sizeLengthCache[ sourceSizeListStr ] = !winningLength ? units.width : winningLength;
1097		}
1098
1099		return sizeLengthCache[ sourceSizeListStr ];
1100	};
1101
1102	/**
1103	 * Takes a candidate object with a srcset property in the form of url/
1104	 * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or
1105	 *     "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or
1106	 *     "images/pic-small.png"
1107	 * Get an array of image candidates in the form of
1108	 *      {url: "/foo/bar.png", resolution: 1}
1109	 * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value
1110	 * If sizes is specified, res is calculated
1111	 */
1112	pf.setRes = function( set ) {
1113		var candidates;
1114		if ( set ) {
1115
1116			candidates = pf.parseSet( set );
1117
1118			for ( var i = 0, len = candidates.length; i < len; i++ ) {
1119				setResolution( candidates[ i ], set.sizes );
1120			}
1121		}
1122		return candidates;
1123	};
1124
1125	pf.setRes.res = setResolution;
1126
1127	pf.applySetCandidate = function( candidates, img ) {
1128		if ( !candidates.length ) {return;}
1129		var candidate,
1130			i,
1131			j,
1132			length,
1133			bestCandidate,
1134			curSrc,
1135			curCan,
1136			candidateSrc,
1137			abortCurSrc;
1138
1139		var imageData = img[ pf.ns ];
1140		var dpr = pf.DPR;
1141
1142		curSrc = imageData.curSrc || img[curSrcProp];
1143
1144		curCan = imageData.curCan || setSrcToCur(img, curSrc, candidates[0].set);
1145
1146		// if we have a current source, we might either become lazy or give this source some advantage
1147		if ( curCan && curCan.set === candidates[ 0 ].set ) {
1148
1149			// if browser can abort image request and the image has a higher pixel density than needed
1150			// and this image isn't downloaded yet, we skip next part and try to save bandwidth
1151			abortCurSrc = (supportAbort && !img.complete && curCan.res - 0.1 > dpr);
1152
1153			if ( !abortCurSrc ) {
1154				curCan.cached = true;
1155
1156				// if current candidate is "best", "better" or "okay",
1157				// set it to bestCandidate
1158				if ( curCan.res >= dpr ) {
1159					bestCandidate = curCan;
1160				}
1161			}
1162		}
1163
1164		if ( !bestCandidate ) {
1165
1166			candidates.sort( ascendingSort );
1167
1168			length = candidates.length;
1169			bestCandidate = candidates[ length - 1 ];
1170
1171			for ( i = 0; i < length; i++ ) {
1172				candidate = candidates[ i ];
1173				if ( candidate.res >= dpr ) {
1174					j = i - 1;
1175
1176					// we have found the perfect candidate,
1177					// but let's improve this a little bit with some assumptions ;-)
1178					if (candidates[ j ] &&
1179						(abortCurSrc || curSrc !== pf.makeUrl( candidate.url )) &&
1180						chooseLowRes(candidates[ j ].res, candidate.res, dpr, candidates[ j ].cached)) {
1181
1182						bestCandidate = candidates[ j ];
1183
1184					} else {
1185						bestCandidate = candidate;
1186					}
1187					break;
1188				}
1189			}
1190		}
1191
1192		if ( bestCandidate ) {
1193
1194			candidateSrc = pf.makeUrl( bestCandidate.url );
1195
1196			imageData.curSrc = candidateSrc;
1197			imageData.curCan = bestCandidate;
1198
1199			if ( candidateSrc !== curSrc ) {
1200				pf.setSrc( img, bestCandidate );
1201			}
1202			pf.setSize( img );
1203		}
1204	};
1205
1206	pf.setSrc = function( img, bestCandidate ) {
1207		var origWidth;
1208		img.src = bestCandidate.url;
1209
1210		// although this is a specific Safari issue, we don't want to take too much different code paths
1211		if ( bestCandidate.set.type === "image/svg+xml" ) {
1212			origWidth = img.style.width;
1213			img.style.width = (img.offsetWidth + 1) + "px";
1214
1215			// next line only should trigger a repaint
1216			// if... is only done to trick dead code removal
1217			if ( img.offsetWidth + 1 ) {
1218				img.style.width = origWidth;
1219			}
1220		}
1221	};
1222
1223	pf.getSet = function( img ) {
1224		var i, set, supportsType;
1225		var match = false;
1226		var sets = img [ pf.ns ].sets;
1227
1228		for ( i = 0; i < sets.length && !match; i++ ) {
1229			set = sets[i];
1230
1231			if ( !set.srcset || !pf.matchesMedia( set.media ) || !(supportsType = pf.supportsType( set.type )) ) {
1232				continue;
1233			}
1234
1235			if ( supportsType === "pending" ) {
1236				set = supportsType;
1237			}
1238
1239			match = set;
1240			break;
1241		}
1242
1243		return match;
1244	};
1245
1246	pf.parseSets = function( element, parent, options ) {
1247		var srcsetAttribute, imageSet, isWDescripor, srcsetParsed;
1248
1249		var hasPicture = parent && parent.nodeName.toUpperCase() === "PICTURE";
1250		var imageData = element[ pf.ns ];
1251
1252		if ( imageData.src === undefined || options.src ) {
1253			imageData.src = getImgAttr.call( element, "src" );
1254			if ( imageData.src ) {
1255				setImgAttr.call( element, srcAttr, imageData.src );
1256			} else {
1257				removeImgAttr.call( element, srcAttr );
1258			}
1259		}
1260
1261		if ( imageData.srcset === undefined || options.srcset || !pf.supSrcset || element.srcset ) {
1262			srcsetAttribute = getImgAttr.call( element, "srcset" );
1263			imageData.srcset = srcsetAttribute;
1264			srcsetParsed = true;
1265		}
1266
1267		imageData.sets = [];
1268
1269		if ( hasPicture ) {
1270			imageData.pic = true;
1271			getAllSourceElements( parent, imageData.sets );
1272		}
1273
1274		if ( imageData.srcset ) {
1275			imageSet = {
1276				srcset: imageData.srcset,
1277				sizes: getImgAttr.call( element, "sizes" )
1278			};
1279
1280			imageData.sets.push( imageSet );
1281
1282			isWDescripor = (alwaysCheckWDescriptor || imageData.src) && regWDesc.test(imageData.srcset || "");
1283
1284			// add normal src as candidate, if source has no w descriptor
1285			if ( !isWDescripor && imageData.src && !getCandidateForSrc(imageData.src, imageSet) && !imageSet.has1x ) {
1286				imageSet.srcset += ", " + imageData.src;
1287				imageSet.cands.push({
1288					url: imageData.src,
1289					d: 1,
1290					set: imageSet
1291				});
1292			}
1293
1294		} else if ( imageData.src ) {
1295			imageData.sets.push( {
1296				srcset: imageData.src,
1297				sizes: null
1298			} );
1299		}
1300
1301		imageData.curCan = null;
1302		imageData.curSrc = undefined;
1303
1304		// if img has picture or the srcset was removed or has a srcset and does not support srcset at all
1305		// or has a w descriptor (and does not support sizes) set support to false to evaluate
1306		imageData.supported = !( hasPicture || ( imageSet && !pf.supSrcset ) || (isWDescripor && !pf.supSizes) );
1307
1308		if ( srcsetParsed && pf.supSrcset && !imageData.supported ) {
1309			if ( srcsetAttribute ) {
1310				setImgAttr.call( element, srcsetAttr, srcsetAttribute );
1311				element.srcset = "";
1312			} else {
1313				removeImgAttr.call( element, srcsetAttr );
1314			}
1315		}
1316
1317		if (imageData.supported && !imageData.srcset && ((!imageData.src && element.src) ||  element.src !== pf.makeUrl(imageData.src))) {
1318			if (imageData.src === null) {
1319				element.removeAttribute("src");
1320			} else {
1321				element.src = imageData.src;
1322			}
1323		}
1324
1325		imageData.parsed = true;
1326	};
1327
1328	pf.fillImg = function(element, options) {
1329		var imageData;
1330		var extreme = options.reselect || options.reevaluate;
1331
1332		// expando for caching data on the img
1333		if ( !element[ pf.ns ] ) {
1334			element[ pf.ns ] = {};
1335		}
1336
1337		imageData = element[ pf.ns ];
1338
1339		// if the element has already been evaluated, skip it
1340		// unless `options.reevaluate` is set to true ( this, for example,
1341		// is set to true when running `picturefill` on `resize` ).
1342		if ( !extreme && imageData.evaled === evalId ) {
1343			return;
1344		}
1345
1346		if ( !imageData.parsed || options.reevaluate ) {
1347			pf.parseSets( element, element.parentNode, options );
1348		}
1349
1350		if ( !imageData.supported ) {
1351			applyBestCandidate( element );
1352		} else {
1353			imageData.evaled = evalId;
1354		}
1355	};
1356
1357	pf.setupRun = function() {
1358		if ( !alreadyRun || isVwDirty || (DPR !== window.devicePixelRatio) ) {
1359			updateMetrics();
1360		}
1361	};
1362
1363	// If picture is supported, well, that's awesome.
1364	if ( pf.supPicture ) {
1365		picturefill = noop;
1366		pf.fillImg = noop;
1367	} else {
1368
1369		 // Set up picture polyfill by polling the document
1370		(function() {
1371			var isDomReady;
1372			var regReady = window.attachEvent ? /d$|^c/ : /d$|^c|^i/;
1373
1374			var run = function() {
1375				var readyState = document.readyState || "";
1376
1377				timerId = setTimeout(run, readyState === "loading" ? 200 :  999);
1378				if ( document.body ) {
1379					pf.fillImgs();
1380					isDomReady = isDomReady || regReady.test(readyState);
1381					if ( isDomReady ) {
1382						clearTimeout( timerId );
1383					}
1384
1385				}
1386			};
1387
1388			var timerId = setTimeout(run, document.body ? 9 : 99);
1389
1390			// Also attach picturefill on resize and readystatechange
1391			// http://modernjavascript.blogspot.com/2013/08/building-better-debounce.html
1392			var debounce = function(func, wait) {
1393				var timeout, timestamp;
1394				var later = function() {
1395					var last = (new Date()) - timestamp;
1396
1397					if (last < wait) {
1398						timeout = setTimeout(later, wait - last);
1399					} else {
1400						timeout = null;
1401						func();
1402					}
1403				};
1404
1405				return function() {
1406					timestamp = new Date();
1407
1408					if (!timeout) {
1409						timeout = setTimeout(later, wait);
1410					}
1411				};
1412			};
1413			var lastClientWidth = docElem.clientHeight;
1414			var onResize = function() {
1415				isVwDirty = Math.max(window.innerWidth || 0, docElem.clientWidth) !== units.width || docElem.clientHeight !== lastClientWidth;
1416				lastClientWidth = docElem.clientHeight;
1417				if ( isVwDirty ) {
1418					pf.fillImgs();
1419				}
1420			};
1421
1422			on( window, "resize", debounce(onResize, 99 ) );
1423			on( document, "readystatechange", run );
1424		})();
1425	}
1426
1427	pf.picturefill = picturefill;
1428	//use this internally for easy monkey patching/performance testing
1429	pf.fillImgs = picturefill;
1430	pf.teardownRun = noop;
1431
1432	/* expose methods for testing */
1433	picturefill._ = pf;
1434
1435	window.picturefillCFG = {
1436		pf: pf,
1437		push: function(args) {
1438			var name = args.shift();
1439			if (typeof pf[name] === "function") {
1440				pf[name].apply(pf, args);
1441			} else {
1442				cfg[name] = args[0];
1443				if (alreadyRun) {
1444					pf.fillImgs( { reselect: true } );
1445				}
1446			}
1447		}
1448	};
1449
1450	while (setOptions && setOptions.length) {
1451		window.picturefillCFG.push(setOptions.shift());
1452	}
1453
1454	/* expose picturefill */
1455	window.picturefill = picturefill;
1456
1457	/* expose picturefill */
1458	if ( typeof module === "object" && typeof module.exports === "object" ) {
1459		// CommonJS, just export
1460		module.exports = picturefill;
1461	} else if ( typeof define === "function" && define.amd ) {
1462		// AMD support
1463		define( "picturefill", function() { return picturefill; } );
1464	}
1465
1466	// IE8 evals this sync, so it must be the last thing we do
1467	if ( !pf.supPicture ) {
1468		types[ "image/webp" ] = detectTypeSupport("image/webp", "data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAABBxAR/Q9ERP8DAABWUDggGAAAADABAJ0BKgEAAQADADQlpAADcAD++/1QAA==" );
1469	}
1470
1471} )( window, document );

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.