PageSourceSearch

https://www.growninmonmouth.com/JS/modernizr-1.5.js

js growninmonmouth.com collected 2026-10-06 06:49:26 UTC 37,275 bytes, 857 lines download raw bytes

1/*!
2 * Modernizr JavaScript library 1.5
3 * http://www.modernizr.com/
4 *
5 * Copyright (c) 2009-2010 Faruk Ates - http://farukat.es/
6 * Dual-licensed under the BSD and MIT licenses.
7 * http://www.modernizr.com/license/
8 *
9 * Featuring major contributions by
10 * Paul Irish  - http://paulirish.com
11 */
12
13/*
14 * LicenseModernizr is available under the MIT and BSD licenses:
15
16 * MIT License
17 * Copyright (c) 2009–2010 Faruk Ate?
18 * Permission is hereby granted, free of charge, to any person obtaining a copy
19 * of this software and associated documentation files (the "Software"), to deal
20 * in the Software without restriction, including without limitation the rights
21 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22 * copies of the Software, and to permit persons to whom the Software is
23 * furnished to do so, subject to the following conditions:
24
25 * The above copyright notice and this permission notice shall be included in
26 * all copies or substantial portions of the Software.
27
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
34 * THE SOFTWARE.
35
36 * BSD License
37 * Copyright (c) 2010, Faruk Ate?
38 * All rights reserved.
39
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions are met:
42 * * Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * * Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 *  * Neither the name of the Organization nor the
48 *  names of its contributors may be used to endorse or promote products
49 *  derived from this software without specific prior written permission.
50
51 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
52 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 *  DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
55 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61*/
62 
63/*
64 * Modernizr is a script that will detect native CSS3 and HTML5 features
65 * available in the current UA and provide an object containing all
66 * features with a true/false value, depending on whether the UA has
67 * native support for it or not.
68 * 
69 * In addition to that, Modernizr will add classes to the <html>
70 * element of the page, one for each cutting-edge feature. If the UA
71 * supports it, a class like "cssgradients" will be added. If not,
72 * the class name will be "no-cssgradients". This allows for simple
73 * if-conditionals in CSS styling, making it easily to have fine
74 * control over the look and feel of your website.
75 * 
76 * @author        Faruk Ates
77 * @copyright     (c) 2009-2010 Faruk Ates.
78 *
79 * @contributor   Paul Irish
80 * @contributor   Ben Alman
81 */
82
83window.Modernizr = (function(window,doc,undefined){
84    
85    var version = '1.5',
86    
87    ret = {},
88
89    /**
90     * enableHTML5 is a private property for advanced use only. If enabled,
91     * it will make Modernizr.init() run through a brief while() loop in
92     * which it will create all HTML5 elements in the DOM to allow for
93     * styling them in Internet Explorer, which does not recognize any
94     * non-HTML4 elements unless created in the DOM this way.
95     * 
96     * enableHTML5 is ON by default.
97     */
98    enableHTML5 = true,
99    
100    
101    /**
102     * fontfaceCheckDelay is the ms delay before the @font-face test is
103     * checked a second time. This is neccessary because both Gecko and
104     * WebKit do not load data: URI font data synchronously.
105     *   https://bugzilla.mozilla.org/show_bug.cgi?id=512566
106     * The check will be done again at fontfaceCheckDelay*2 and then 
107     * a fourth time at window's load event. 
108     * If you need to query for @font-face support, send a callback to: 
109     *  Modernizr._fontfaceready(fn);
110     * The callback is passed the boolean value of Modernizr.fontface
111     */
112    fontfaceCheckDelay = 75,
113    
114    
115    docElement = doc.documentElement,
116
117    /**
118     * Create our "modernizr" element that we do most feature tests on.
119     */
120    mod = 'modernizr',
121    m = doc.createElement( mod ),
122    m_style = m.style,
123
124    /**
125     * Create the input element for various Web Forms feature tests.
126     */
127    f = doc.createElement( 'input' ),
128    
129    // Reused strings, stored here to allow better minification
130    
131    canvas = 'canvas',
132    canvastext = 'canvastext',
133    rgba = 'rgba',
134    hsla = 'hsla',
135    multiplebgs = 'multiplebgs',
136    backgroundsize = 'backgroundsize',
137    borderimage = 'borderimage',
138    borderradius = 'borderradius',
139    boxshadow = 'boxshadow',
140    opacity = 'opacity',
141    cssanimations = 'cssanimations',
142    csscolumns = 'csscolumns',
143    cssgradients = 'cssgradients',
144    cssreflections = 'cssreflections',
145    csstransforms = 'csstransforms',
146    csstransforms3d = 'csstransforms3d',
147    csstransitions = 'csstransitions',
148    fontface = 'fontface',
149    geolocation = 'geolocation',
150    video = 'video',
151    audio = 'audio',
152    input = 'input',
153    inputtypes = input + 'types',
154    // inputtypes is an object of its own containing individual tests for
155    // various new input types, such as search, range, datetime, etc.
156    
157    svg = 'svg',
158    smil = 'smil',
159    svgclippaths = svg+'clippaths',
160    
161    background = 'background',
162    backgroundColor = background + 'Color',
163    canPlayType = 'canPlayType',
164    
165    // FF gets really angry if you name local variables as these, but camelCased.
166    localstorage = 'localStorage',
167    sessionstorage = 'sessionStorage',
168    applicationcache = 'applicationCache',
169    
170    webWorkers = 'webworkers',
171    hashchange = 'hashchange',
172    crosswindowmessaging = 'crosswindowmessaging',
173    historymanagement = 'historymanagement',
174    draganddrop = 'draganddrop',
175    websqldatabase = 'websqldatabase',
176    indexedDB = 'indexedDB',
177    websockets = 'websockets',
178    smile = ':)',
179    
180    // IE7 gets mad if you name a local variable `toString`
181    tostring = Object.prototype.toString,
182    
183    // list of property values to set for css tests. see ticket #21
184    prefixes = ' -o- -moz- -ms- -webkit- -khtml- '.split(' '),
185
186    tests = {},
187    inputs = {},
188    attrs = {},
189    
190    classes = [],
191    
192    /**
193      * isEventSupported determines if a given element supports the given event
194      * function from http://yura.thinkweb2.com/isEventSupported/
195      */
196    isEventSupported = (function(){
197  
198        var TAGNAMES = {
199          'select':'input','change':'input',
200          'submit':'form','reset':'form',
201          'error':'img','load':'img','abort':'img'
202        }, 
203        cache = { };
204        
205        function isEventSupported(eventName, element) {
206            var canCache = (arguments.length == 1);
207            
208            // only return cached result when no element is given
209            if (canCache && cache[eventName]) {
210                return cache[eventName];
211            }
212            
213            element = element || document.createElement(TAGNAMES[eventName] || 'div');
214            eventName = 'on' + eventName;
215            
216            // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize"
217            // `in` "catches" those
218            var isSupported = (eventName in element);
219            
220            if (!isSupported && element.setAttribute) {
221                element.setAttribute(eventName, 'return;');
222                isSupported = typeof element[eventName] == 'function';
223            }
224            
225            element = null;
226            return canCache ? (cache[eventName] = isSupported) : isSupported;
227        }
228        
229        return isEventSupported;
230    })();    
231    
232    
233    var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
234    if (typeof _hasOwnProperty !== 'undefined' && typeof _hasOwnProperty.call !== 'undefined') {
235      hasOwnProperty = function (object, property) {
236        return _hasOwnProperty.call(object, property);
237      };
238    }
239    else {
240      hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
241        return ((property in object) && typeof object.constructor.prototype[property] === 'undefined');
242      };
243    }
244    
245    /**
246     * set_css applies given styles to the Modernizr DOM node.
247     */
248    function set_css( str ) {
249        m_style.cssText = str;
250    }
251
252    /**
253     * set_css_all extrapolates all vendor-specific css strings.
254     */
255    function set_css_all( str1, str2 ) {
256        return set_css(prefixes.join(str1 + ';') + ( str2 || '' ));
257    }
258
259    /**
260     * contains returns a boolean for if substr is found within str.
261     */
262    function contains( str, substr ) {
263        return (''+str).indexOf( substr ) !== -1;
264    }
265
266    /**
267     * test_props is a generic CSS / DOM property test; if a browser supports
268     *   a certain property, it won't return undefined for it.
269     *   A supported CSS property returns empty string when its not yet set.
270     */
271    function test_props( props, callback ) {
272        for ( var i in props ) {
273            if ( m_style[ props[i] ] !== undefined && ( !callback || callback( props[i], m ) ) ) {
274                return true;
275            }
276        }
277    }
278
279    /**
280     * test_props_all tests a list of DOM properties we want to check against.
281     *   We specify literally ALL possible (known and/or likely) properties on 
282     *   the element including the non-vendor prefixed one, for forward-
283     *   compatibility.
284     */
285    function test_props_all( prop, callback ) {
286        var uc_prop = prop.charAt(0).toUpperCase() + prop.substr(1),
287        
288        // following spec is to expose vendor-specific style properties as:
289        //   elem.style.WebkitBorderRadius
290        // and the following would be incorrect:
291        //   elem.style.webkitBorderRadius
292        // Webkit and Mozilla are nice enough to ghost their properties in the lowercase
293        //   version but Opera does not.
294        
295        // see more here: http://github.com/Modernizr/Modernizr/issues/issue/21
296        props = [
297            prop,
298            'Webkit' + uc_prop,
299            'Moz' + uc_prop,
300            'O' + uc_prop,
301            'ms' + uc_prop,
302            'Khtml' + uc_prop
303        ];
304
305        return !!test_props( props, callback );
306    }
307    
308
309    /**
310     * Tests
311     */
312     
313    tests[canvas] = function() {
314        return !!doc.createElement( canvas ).getContext;
315    };
316    
317    tests[canvastext] = function() {
318        return !!(tests[canvas]() && typeof doc.createElement( canvas ).getContext('2d').fillText == 'function');
319    };
320    
321    /**
322     * The Modernizr.touch test only indicates if the browser supports
323     *    touch events, which does not necessarily reflect a touchscreen
324     *    device, as evidenced by tablets running Windows 7 or, alas,
325     *    the Palm Pre / WebOS (touch) phones.
326     * Additionally, chrome used to lie about its support on this, but that 
327     *    has since been recitifed: http://crbug.com/36415
328     * Because there is no way to reliably detect Chrome's false positive 
329     *    without UA sniffing we have removed this test from Modernizr. We 
330     *    hope to add it in after Chrome 5 has been sunsetted. 
331     * See also http://github.com/Modernizr/Modernizr/issues#issue/84
332     
333    tests[touch] = function() {
334
335        return !!('ontouchstart' in window);
336        
337    };
338    */
339
340    /**
341     * geolocation tests for the new Geolocation API specification.
342     *   This test is a standards compliant-only test; for more complete
343     *   testing, including a Google Gears fallback, please see:
344     *   http://code.google.com/p/geo-location-javascript/
345     * or view a fallback solution using google's geo API:
346     *   http://gist.github.com/366184
347     */
348    tests[geolocation] = function() {
349        return !!navigator.geolocation;
350    };
351
352    tests[crosswindowmessaging] = function() {
353      return !!window.postMessage;
354    };
355
356    tests[websqldatabase] = function() {
357      var result = !!window.openDatabase;
358      if (result){
359        try {
360          result = !!openDatabase("testdb", "1.0", "html5 test db", 200000);
361        } catch(err) {
362          result = false;
363        }
364      }
365      return result;
366    };
367    
368    tests[indexedDB] = function(){
369      return !!window[indexedDB];
370    };
371
372    // documentMode logic from YUI to filter out IE8 Compat Mode
373    //   which false positives.
374    tests[hashchange] = function() {
375      return isEventSupported(hashchange, window) && ( document.documentMode === undefined || document.documentMode > 7 );
376    };
377
378    tests[historymanagement] = function() {
379      return !!(window.history && history.pushState);
380    };
381
382    tests[draganddrop] = function() {
383        return isEventSupported('drag')
384            && isEventSupported('dragstart')
385            && isEventSupported('dragenter')
386            && isEventSupported('dragover')
387            && isEventSupported('dragleave')
388            && isEventSupported('dragend')
389            && isEventSupported('drop');
390    };
391
392    
393    tests[websockets] = function(){
394        return ('WebSocket' in window);
395    };
396    
397    
398    // http://css-tricks.com/rgba-browser-support/
399    tests[rgba] = function() {
400        // Set an rgba() color and check the returned value
401        
402        set_css( background + '-color:rgba(150,255,150,.5)' );
403        
404        return contains( m_style[backgroundColor], rgba );
405    };
406    
407    tests[hsla] = function() {
408        // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally
409        
410        set_css( background + '-color:hsla(120,40%,100%,.5)' );
411        
412        return contains( m_style[backgroundColor], rgba );
413    };
414    
415    tests[multiplebgs] = function() {
416        // Setting multiple images AND a color on the background shorthand property
417        //  and then querying the style.background property value for the number of
418        //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
419        
420        set_css( background + ':url(//:),url(//:),red url(//:)' );
421        
422        // If the UA supports multiple backgrounds, there should be three occurrences
423        //  of the string "url(" in the return value for elem_style.background
424
425        return new RegExp("(url\\s*\\(.*?){3}").test(m_style[background]);
426    };
427    
428    
429    // In testing support for a given CSS property, it's legit to test:
430    //    elem.style[styleName] !== undefined
431    // If the property is supported it will return an empty string,
432    // if unsupported it will return undefined.
433    // We'll take advantage of this quick test and skip setting a style 
434    // on our modernizr element, but instead just testing undefined vs
435    // empty string.
436    // The legacy set_css_all calls will remain in the source 
437    // (however, commented) in for clarity, yet functionally they are 
438    // no longer needed.
439    
440
441    tests[backgroundsize] = function() {
442        return test_props_all( background + 'Size' );
443    };
444    
445    tests[borderimage] = function() {
446        //  set_css_all( 'border-image:url(m.png) 1 1 stretch' );
447        return test_props_all( 'borderImage' );
448    };
449    
450    
451    // super comprehensive table about all the unique implementations of 
452    // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
453    
454    tests[borderradius] = function() {
455        //  set_css_all( 'border-radius:10px' );
456        return test_props_all( 'borderRadius', '', function( prop ) {
457            return contains( prop, 'orderRadius' );
458        });
459    };
460    
461    
462    tests[boxshadow] = function() {
463        //  set_css_all( 'box-shadow:#000 1px 1px 3px' );
464        return test_props_all( 'boxShadow' );
465    };
466    
467    
468    tests[opacity] = function() {
469        // Browsers that actually have CSS Opacity implemented have done so
470        //  according to spec, which means their return values are within the
471        //  range of [0.0,1.0] - including the leading zero.
472        
473        set_css_all( 'opacity:.5' );
474        
475        return contains( m_style[opacity], '0.5' );
476    };
477    
478    
479    tests[cssanimations] = function() {
480        //  set_css_all( 'animation:"animate" 2s ease 2', 'position:relative' );
481        return test_props_all( 'animationName' );
482    };
483    
484    
485    tests[csscolumns] = function() {
486        //  set_css_all( 'column-count:3' );
487        return test_props_all( 'columnCount' );
488    };
489    
490    
491    tests[cssgradients] = function() {
492        /**
493         * For CSS Gradients syntax, please see:
494         * http://webkit.org/blog/175/introducing-css-gradients/
495         * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
496         * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
497         * http://dev.w3.org/csswg/css3-images/#gradients-
498         */
499        
500        var str1 = background + '-image:',
501            str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
502            str3 = 'linear-gradient(left top,#9f9, white);';
503        
504        set_css(
505            (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0,-str1.length)
506        );
507        
508        return contains( m_style.backgroundImage, 'gradient' );
509    };
510    
511    
512    tests[cssreflections] = function() {
513        //  set_css_all( 'box-reflect:right 1px' );
514        return test_props_all( 'boxReflect' );
515    };
516    
517    
518    tests[csstransforms] = function() {
519        //  set_css_all( 'transform:rotate(3deg)' );
520        return !!test_props([ 'transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform' ]);
521    };
522    
523    
524    tests[csstransforms3d] = function() {
525        //  set_css_all( 'perspective:500' );
526        
527        var ret = !!test_props([ 'perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective' ]);
528        
529        // webkit has 3d transforms disabled for chrome, though
530        //   it works fine in safari on leopard and snow leopard
531        // as a result, it 'recognizes' the syntax and throws a false positive
532        // thus we must do a more thorough check:
533        if (ret){
534            var st = document.createElement('style'),
535                div = doc.createElement('div');
536                
537            // webkit allows this media query to succeed only if the feature is enabled.    
538            // "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){#modernizr{height:3px}}"
539            st.textContent = '@media ('+prefixes.join('transform-3d),(')+'modernizr){#modernizr{height:3px}}';
540            doc.getElementsByTagName('head')[0].appendChild(st);
541            div.id = 'modernizr';
542            docElement.appendChild(div);
543            
544            ret = div.offsetHeight === 3;
545            
546            st.parentNode.removeChild(st);
547            div.parentNode.removeChild(div);
548        }
549        return ret;
550    };
551    
552    
553    tests[csstransitions] = function() {
554        //  set_css_all( 'transition:all .5s linear' );
555        return test_props_all( 'transitionProperty' );
556    };
557
558
559    // @font-face detection routine created by Paul Irish - paulirish.com
560    // Merged into Modernizr with approval. Read more about Paul's work here:
561    // http://paulirish.com/2009/font-face-feature-detection/  
562    tests[fontface] = function(){
563
564        var fontret;
565        if (/*@cc_on@if(@_jscript_version>=5)!@end@*/0) fontret = true;
566  
567        else {
568      
569          // Create variables for dedicated @font-face test
570          var st  = doc.createElement('style'),
571            spn = doc.createElement('span'),
572            size, isFakeBody = false, body = doc.body,
573            callback, isCallbackCalled;
574  
575          // The following is a font-face + glyph definition for the . character:
576          st.textContent = "@font-face{font-family:testfont;src:url('data:font/ttf;base64,AAEAAAAMAIAAAwBAT1MvMliohmwAAADMAAAAVmNtYXCp5qrBAAABJAAAANhjdnQgACICiAAAAfwAAAAEZ2FzcP//AAMAAAIAAAAACGdseWYv5OZoAAACCAAAANxoZWFk69bnvwAAAuQAAAA2aGhlYQUJAt8AAAMcAAAAJGhtdHgGDgC4AAADQAAAABRsb2NhAIQAwgAAA1QAAAAMbWF4cABVANgAAANgAAAAIG5hbWUgXduAAAADgAAABPVwb3N03NkzmgAACHgAAAA4AAECBAEsAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAACAAMDAAAAAAAAgAACbwAAAAoAAAAAAAAAAFBmRWQAAAAgqS8DM/8zAFwDMwDNAAAABQAAAAAAAAAAAAMAAAADAAAAHAABAAAAAABGAAMAAQAAAK4ABAAqAAAABgAEAAEAAgAuqQD//wAAAC6pAP///9ZXAwAAAAAAAAACAAAABgBoAAAAAAAvAAEAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEACoAAAAGAAQAAQACAC6pAP//AAAALqkA////1lcDAAAAAAAAAAIAAAAiAogAAAAB//8AAgACACIAAAEyAqoAAwAHAC6xAQAvPLIHBADtMrEGBdw8sgMCAO0yALEDAC88sgUEAO0ysgcGAfw8sgECAO0yMxEhESczESMiARDuzMwCqv1WIgJmAAACAFUAAAIRAc0ADwAfAAATFRQWOwEyNj0BNCYrASIGARQGKwEiJj0BNDY7ATIWFX8aIvAiGhoi8CIaAZIoN/43KCg3/jcoAWD0JB4eJPQkHh7++EY2NkbVRjY2RgAAAAABAEH/+QCdAEEACQAANjQ2MzIWFAYjIkEeEA8fHw8QDxwWFhwWAAAAAQAAAAIAAIuYbWpfDzz1AAsEAAAAAADFn9IuAAAAAMWf0i797/8zA4gDMwAAAAgAAgAAAAAAAAABAAADM/8zAFwDx/3v/98DiAABAAAAAAAAAAAAAAAAAAAABQF2ACIAAAAAAVUAAAJmAFUA3QBBAAAAKgAqACoAWgBuAAEAAAAFAFAABwBUAAQAAgAAAAEAAQAAAEAALgADAAMAAAAQAMYAAQAAAAAAAACLAAAAAQAAAAAAAQAhAIsAAQAAAAAAAgAFAKwAAQAAAAAAAwBDALEAAQAAAAAABAAnAPQAAQAAAAAABQAKARsAAQAAAAAABgAmASUAAQAAAAAADgAaAUsAAwABBAkAAAEWAWUAAwABBAkAAQBCAnsAAwABBAkAAgAKAr0AAwABBAkAAwCGAscAAwABBAkABABOA00AAwABBAkABQAUA5sAAwABBAkABgBMA68AAwABBAkADgA0A/tDb3B5cmlnaHQgMjAwOSBieSBEYW5pZWwgSm9obnNvbi4gIFJlbGVhc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgT3BlbiBGb250IExpY2Vuc2UuIEtheWFoIExpIGdseXBocyBhcmUgcmVsZWFzZWQgdW5kZXIgdGhlIEdQTCB2ZXJzaW9uIDMuYmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhTGlnaHRiYWVjMmE5MmJmZmU1MDMyIC0gc3Vic2V0IG9mIEZvbnRGb3JnZSAyLjAgOiBKdXJhIExpZ2h0IDogMjMtMS0yMDA5YmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhIExpZ2h0VmVyc2lvbiAyIGJhZWMyYTkyYmZmZTUwMzIgLSBzdWJzZXQgb2YgSnVyYUxpZ2h0aHR0cDovL3NjcmlwdHMuc2lsLm9yZy9PRkwAQwBvAHAAeQByAGkAZwBoAHQAIAAyADAAMAA5ACAAYgB5ACAARABhAG4AaQBlAGwAIABKAG8AaABuAHMAbwBuAC4AIAAgAFIAZQBsAGUAYQBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAAdABlAHIAbQBzACAAbwBmACAAdABoAGUAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUALgAgAEsAYQB5AGEAaAAgAEwAaQAgAGcAbAB5AHAAaABzACAAYQByAGUAIAByAGUAbABlAGEAcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAEcAUABMACAAdgBlAHIAcwBpAG8AbgAgADMALgBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQBMAGkAZwBoAHQAYgBhAGUAYwAyAGEAOQAyAGIAZgBmAGUANQAwADMAMgAgAC0AIABzAHUAYgBzAGUAdAAgAG8AZgAgAEYAbwBuAHQARgBvAHIAZwBlACAAMgAuADAAIAA6ACAASgB1AHIAYQAgAEwAaQBnAGgAdAAgADoAIAAyADMALQAxAC0AMgAwADAAOQBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQAgAEwAaQBnAGgAdABWAGUAcgBzAGkAbwBuACAAMgAgAGIAYQBlAGMAMgBhADkAMgBiAGYAZgBlADUAMAAzADIAIAAtACAAcwB1AGIAcwBlAHQAIABvAGYAIABKAHUAcgBhAEwAaQBnAGgAdABoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAAAAAgAAAAAAAP+BADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAQACAQIAEQt6ZXJva2F5YWhsaQ==')}";
577          doc.getElementsByTagName('head')[0].appendChild(st);
578      
579          // we don't use `serif` and we don't use `monospace`
580          // http://github.com/Modernizr/Modernizr/issues/closed#issue/39
581          // http://neugierig.org/software/chromium/notes/2009/09/monospace-fonts-workaround.html
582          spn.setAttribute('style','font:99px _,arial,helvetica;position:absolute;visibility:hidden'); 
583      
584          if  (!body){
585            body = docElement.appendChild(doc.createElement(fontface));
586            isFakeBody = true;
587          } 
588      
589          // the data-uri'd font only has the . glyph; which is 3 pixels wide.
590          spn.innerHTML = '........';
591          spn.id        = 'fonttest';
592      
593          body.appendChild(spn);
594          size = spn.offsetWidth*spn.offsetHeight;
595          spn.style.font = '99px testfont,_,arial,helvetica';
596      
597          // needed for the CSSFontFaceRule false positives (ff3, chrome, op9)
598          fontret = size !== spn.offsetWidth*spn.offsetHeight;
599      
600          function delayedCheck(){
601            if (!body.parentNode) return;
602            fontret = ret[fontface] = size !== spn.offsetWidth*spn.offsetHeight;
603            docElement.className = docElement.className.replace(/(no-)?fontface\b/,'') + (fontret ? ' ' : ' no-') + fontface;
604          }
605
606          setTimeout(delayedCheck,fontfaceCheckDelay);
607          setTimeout(delayedCheck,fontfaceCheckDelay*2);
608          addEventListener('load',function(){
609              delayedCheck();
610              (isCallbackCalled = true) && callback && callback(fontret);
611              setTimeout(function(){
612                  if (!isFakeBody) body = spn;
613                  body.parentNode.removeChild(body);
614                  st.parentNode.removeChild(st);
615              }, 50);
616          },false);
617        }
618
619        // allow for a callback
620        ret._fontfaceready = function(fn){
621          (isCallbackCalled || fontret) ? fn(fontret) : (callback = fn);
622        }
623      
624        return fontret || size !== spn.offsetWidth;
625    
626    };
627    
628
629    // These tests evaluate support of the video/audio elements, as well as
630    // testing what types of content they support.
631    //
632    // we're using the Boolean constructor here, so that we can extend the value
633    // e.g.  Modernizr.video     // true
634    //       Modernizr.video.ogg // 'probably'
635    //
636    // codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
637    //                     thx to NielsLeenheer and zcorpan
638    
639    tests[video] = function() {
640        var elem = doc.createElement(video),
641            bool = !!elem[canPlayType];
642        
643        if (bool){  
644            bool      = new Boolean(bool);  
645            bool.ogg  = elem[canPlayType]('video/ogg; codecs="theora"');
646            bool.h264 = elem[canPlayType]('video/mp4; codecs="avc1.42E01E"');
647            bool.webm = elem[canPlayType]('video/webm; codecs="vp8, vorbis"');
648        }
649        return bool;
650    };
651    
652    tests[audio] = function() {
653        var elem = doc.createElement(audio),
654            bool = !!elem[canPlayType];
655        
656        if (bool){  
657            bool      = new Boolean(bool);  
658            bool.ogg  = elem[canPlayType]('audio/ogg; codecs="vorbis"');
659            bool.mp3  = elem[canPlayType]('audio/mpeg;');
660            
661            // mimetypes accepted: 
662            //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
663            //   http://bit.ly/iphoneoscodecs
664            bool.wav  = elem[canPlayType]('audio/wav; codecs="1"');
665            bool.m4a  = elem[canPlayType]('audio/x-m4a;') || elem[canPlayType]('audio/aac;');
666        }
667        return bool;
668    };
669
670
671    // both localStorage and sessionStorage are
672    // tested in this method because otherwise Firefox will
673    //   throw an error: https://bugzilla.mozilla.org/show_bug.cgi?id=365772
674    // if cookies are disabled
675    
676    // FWIW miller device resolves to [object Storage] in all supporting browsers
677    //   except for IE who does [object Object]
678    
679    // IE8 Compat mode supports these features completely:
680    //   http://www.quirksmode.org/dom/html5.html
681    
682    tests[localstorage] = function() {
683        return ('localStorage' in window) && window[localstorage] !== null;
684    };
685
686    tests[sessionstorage] = function() {
687        // try/catch required for pissy FF behavior
688        try {
689            return ('sessionStorage' in window) && window[sessionstorage] !== null;
690        } catch(e){
691            return false;
692        }
693    };
694
695
696    tests[webWorkers] = function () {
697        return !!window.Worker;
698    };
699
700
701    tests[applicationcache] =  function() {
702        var cache = window[applicationcache];
703        return !!(cache && (typeof cache.status != 'undefined') && (typeof cache.update == 'function') && (typeof cache.swapCache == 'function'));
704    };
705
706 
707    // thanks to Erik Dahlstrom
708    tests[svg] = function(){
709        return !!doc.createElementNS && !!doc.createElementNS( "http://www.w3.org/2000/svg", "svg").createSVGRect;
710    };
711    
712    // thanks to F1lt3r and lucideer
713    // http://github.com/Modernizr/Modernizr/issues#issue/35
714    tests[smil] = function(){
715        return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS('http://www.w3.org/2000/svg','animate')));
716    };
717
718    tests[svgclippaths] = function(){
719        // returns a false positive in saf 3.2?
720        return !!doc.createElementNS && /SVG/.test(tostring.call(doc.createElementNS('http://www.w3.org/2000/svg','clipPath')));
721    };
722
723
724    // input features and input types go directly onto the ret object, bypassing the tests loop.
725    // hold this guy to execute in a moment.
726    function webforms(){
727    
728        // Run through HTML5's new input attributes to see if the UA understands any.
729        // We're using f which is the <input> element created early on
730        // Mike Taylr has created a comprehensive resource for testing these attributes
731        //   when applied to all input types: 
732        //   http://miketaylr.com/code/input-type-attr.html
733        // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
734        ret[input] = (function(props) {
735            for (var i = 0,len=props.length;i<len;i++) {
736                attrs[ props[i] ] = !!(props[i] in f);
737            }
738            return attrs;
739        })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
740
741        // Run through HTML5's new input types to see if the UA understands any.
742        //   This is put behind the tests runloop because it doesn't return a
743        //   true/false like all the other tests; instead, it returns an object
744        //   containing each input type with its corresponding true/false value 
745        
746        // Big thx to @miketaylr for the html5 forms expertise. http://miketaylr.com/
747        ret[inputtypes] = (function(props) {
748            for (var i = 0,bool,len=props.length;i<len;i++) {
749                f.setAttribute('type', props[i]);
750                bool = f.type !== 'text';
751                
752                // chrome likes to falsely purport support, so we feed it a textual value
753                // if that doesnt succeed then we know there's a custom UI
754                if (bool){  
755
756                    f.value = smile;
757                    
758                    /* Safari 4 is allowing the smiley as a value, and incorrecty failing..
759                       the test fixes for webkit only, but breaks Opera.. 
760                    if (/range/.test(f.type)){
761                      bool =  test_props_all('appearance',function(prop,m){ return m_style[prop] !== 'textfield' })  
762                    } 
763                    */
764                            
765                    if (/tel|search/.test(f.type)){
766                      // spec doesnt define any special parsing or detectable UI 
767                      //   behaviors so we pass these through as true
768                      
769                    } else if (/url|email/.test(f.type)) {
770                      // real url and email support comes with prebaked validation.
771                      bool = f.checkValidity && f.checkValidity() === false;
772                      
773                    } else {
774                      bool = f.value != smile;
775                    }
776                }
777                
778                inputs[ props[i] ] = !!bool;
779            }
780            return inputs;
781        })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
782
783    }
784
785
786
787    // end of test definitions
788
789
790    // Run through all tests and detect their support in the current UA.
791    // todo: hypothetically we could be doing an array of tests and use a basic loop here.
792    for ( var feature in tests ) {
793        if ( hasOwnProperty( tests, feature ) ) {
794            // run the test, throw the return value into the Modernizr,
795            //   then based on that boolean, define an appropriate className
796            //   and push it into an array of classes we'll join later.
797            classes.push( ( ( ret[ feature.toLowerCase() ] = tests[ feature ]() ) ?  '' : 'no-' ) + feature.toLowerCase() );
798        }
799    }
800    
801    // input tests need to run.
802    if (!ret[input]) webforms();
803    
804
805   
806
807
808
809    /**
810     * Addtest allows the user to define their own feature tests
811     * the result will be added onto the Modernizr object,
812     * as well as an appropriate className set on the html element
813     * 
814     * @param feature - String naming the feature
815     * @param test - Function returning true if feature is supported, false if not
816     */
817    ret.addTest = function (feature, test) {
818      feature = feature.toLowerCase();
819      
820      if (ret[ feature ]) {
821        return; // quit if you're trying to overwrite an existing test
822      } 
823      test = !!(test());
824      docElement.className += ' ' + (test ? '' : 'no-') + feature; 
825      ret[ feature ] = test;
826      return ret; // allow chaining.
827    };
828
829    /**
830     * Reset m.style.cssText to nothing to reduce memory footprint.
831     */
832    set_css( '' );
833    m = f = null;
834
835    // Enable HTML 5 elements for styling in IE. 
836    // fyi: jscript version does not reflect trident version
837    //      therefore ie9 in ie7 mode will still have a jScript v.9
838    if ( enableHTML5 && (function(){ var elem = doc.createElement("div");
839                                      elem.innerHTML = "<elem></elem>";
840                                      return elem.childNodes.length !== 1; })()) {
841        // iepp v1.5.1 MIT @jon_neal  http://code.google.com/p/ie-print-protector/
842        (function(p,e){function q(a,b){if(g[a])g[a].styleSheet.cssText+=b;else{var c=r[l],d=e[j]("style");d.media=a;c.insertBefore(d,c[l]);g[a]=d;q(a,b)}}function s(a,b){for(var c=new RegExp("\\b("+m+")\\b(?!.*[;}])","gi"),d=function(k){return".iepp_"+k},h=-1;++h<a.length;){b=a[h].media||b;s(a[h].imports,b);q(b,a[h].cssText.replace(c,d))}}
842function t(){for(var a,b=e.getElementsByTagName("*"),c,d,h=new RegExp("^"+m+"$","i"),k=-1;++k<b.length;)if((a=b[k])&&(d=a.nodeName.match(h))){c=new RegExp("^\\s*<"+d+"(.*)\\/"+d+">\\s*$","i");i.innerHTML=a.outerHTML.replace(/\r|\n/g," ").replace(c,a.currentStyle.display=="block"?"<div$1/div>":"<span$1/span>");c=i.childNodes[0];c.className+=" iepp_"+d;c=f[f.length]=[a,c];a.parentNode.replaceChild(c[1],c[0])}s(e.styleSheets,"all")}function u(){for(var a=-1,b;++a<f.length;)f[a][1].parentNode.replaceChild(f[a][0],f[a][1]);for(b in g)r[l].removeChild(g[b]);g={};f=[]}for(var r=e.documentElement,i=e.createDocumentFragment(),g={},m="abbr|article|aside|audio|canvas|command|datalist|details|figure|figcaption|footer|header|hgroup|keygen|mark|meter|nav|output|progress|section|source|summary|time|video",n=m.split("|"),f=[],o=-1,l="firstChild",j="createElement";++o<n.length;){e[j](n[o]);i[j](n[o])}i=i.appendChild(e[j]("div"));p.attachEvent("onbeforeprint",t);p.attachEvent("onafterprint",u)})(this,doc);
843    }
844
845    // Assign private properties to the return object with prefix
846    ret._enableHTML5     = enableHTML5;
847    ret._version         = version;
848
849    // Remove "no-js" class from <html> element, if it exists:
850    docElement.className=docElement.className.replace(/\bno-js\b/,'') + ' js';
851
852    // Add the new classes to the <html> element.
853    docElement.className += ' ' + classes.join( ' ' );
854    
855    return ret;
856
857})(this,this.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.