| 1 |  |  | /*! | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  * Platform.js <https://mths.be/platform> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  * Copyright 2014-2016 Benjamin Tan <https://demoneaux.github.io/> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * Available under MIT license <https://mths.be/mit> | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 6 |  |  |  */ | 
            
                                                        
            
                                    
            
            
                | 7 |  |  | ;(function() { | 
            
                                                        
            
                                    
            
            
                | 8 |  |  |   'use strict'; | 
            
                                                        
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 10 |  |  |   /** Used to determine if values are of the language type `Object`. */ | 
            
                                                        
            
                                    
            
            
                | 11 |  |  |   var objectTypes = { | 
            
                                                        
            
                                    
            
            
                | 12 |  |  |     'function': true, | 
            
                                                        
            
                                    
            
            
                | 13 |  |  |     'object': true | 
            
                                                        
            
                                    
            
            
                | 14 |  |  |   }; | 
            
                                                        
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 16 |  |  |   /** Used as a reference to the global object. */ | 
            
                                                        
            
                                    
            
            
                | 17 |  |  |   var root = (objectTypes[typeof window] && window) || this; | 
            
                                                        
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 19 |  |  |   /** Backup possible global object. */ | 
            
                                                        
            
                                    
            
            
                | 20 |  |  |   var oldRoot = root; | 
            
                                                        
            
                                    
            
            
                | 21 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 22 |  |  |   /** Detect free variable `exports`. */ | 
            
                                                        
            
                                    
            
            
                | 23 |  |  |   var freeExports = objectTypes[typeof exports] && exports; | 
            
                                                        
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 25 |  |  |   /** Detect free variable `module`. */ | 
            
                                                        
            
                                    
            
            
                | 26 |  |  |   var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; | 
            
                                                        
            
                                    
            
            
                | 27 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 28 |  |  |   /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ | 
            
                                                        
            
                                    
            
            
                | 29 |  |  |   var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; | 
            
                                                        
            
                                    
            
            
                | 30 |  |  |   if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { | 
            
                                                        
            
                                    
            
            
                | 31 |  |  |     root = freeGlobal; | 
            
                                                        
            
                                    
            
            
                | 32 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 33 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 34 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 35 |  |  |    * Used as the maximum length of an array-like object. | 
            
                                                        
            
                                    
            
            
                | 36 |  |  |    * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) | 
            
                                                        
            
                                    
            
            
                | 37 |  |  |    * for more details. | 
            
                                                        
            
                                    
            
            
                | 38 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 39 |  |  |   var maxSafeInteger = Math.pow(2, 53) - 1; | 
            
                                                        
            
                                    
            
            
                | 40 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 41 |  |  |   /** Regular expression to detect Opera. */ | 
            
                                                        
            
                                    
            
            
                | 42 |  |  |   var reOpera = /\bOpera/; | 
            
                                                        
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 44 |  |  |   /** Possible global object. */ | 
            
                                                        
            
                                    
            
            
                | 45 |  |  |   var thisBinding = this; | 
            
                                                        
            
                                    
            
            
                | 46 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 47 |  |  |   /** Used for native method references. */ | 
            
                                                        
            
                                    
            
            
                | 48 |  |  |   var objectProto = Object.prototype; | 
            
                                                        
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 50 |  |  |   /** Used to check for own properties of an object. */ | 
            
                                                        
            
                                    
            
            
                | 51 |  |  |   var hasOwnProperty = objectProto.hasOwnProperty; | 
            
                                                        
            
                                    
            
            
                | 52 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 53 |  |  |   /** Used to resolve the internal `[[Class]]` of values. */ | 
            
                                                        
            
                                    
            
            
                | 54 |  |  |   var toString = objectProto.toString; | 
            
                                                        
            
                                    
            
            
                | 55 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 56 |  |  |   /*--------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 58 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 59 |  |  |    * Capitalizes a string value. | 
            
                                                        
            
                                    
            
            
                | 60 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 61 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 62 |  |  |    * @param {string} string The string to capitalize. | 
            
                                                        
            
                                    
            
            
                | 63 |  |  |    * @returns {string} The capitalized string. | 
            
                                                        
            
                                    
            
            
                | 64 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 65 |  |  |   function capitalize(string) { | 
            
                                                        
            
                                    
            
            
                | 66 |  |  |     string = String(string); | 
            
                                                        
            
                                    
            
            
                | 67 |  |  |     return string.charAt(0).toUpperCase() + string.slice(1); | 
            
                                                        
            
                                    
            
            
                | 68 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 70 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 71 |  |  |    * A utility function to clean up the OS name. | 
            
                                                        
            
                                    
            
            
                | 72 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 73 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 74 |  |  |    * @param {string} os The OS name to clean up. | 
            
                                                        
            
                                    
            
            
                | 75 |  |  |    * @param {string} [pattern] A `RegExp` pattern matching the OS name. | 
            
                                                        
            
                                    
            
            
                | 76 |  |  |    * @param {string} [label] A label for the OS. | 
            
                                                        
            
                                    
            
            
                | 77 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 78 |  |  |   function cleanupOS(os, pattern, label) { | 
            
                                                        
            
                                    
            
            
                | 79 |  |  |     // Platform tokens are defined at: | 
            
                                                        
            
                                    
            
            
                | 80 |  |  |     // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx | 
            
                                                        
            
                                    
            
            
                | 81 |  |  |     // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx | 
            
                                                        
            
                                    
            
            
                | 82 |  |  |     var data = { | 
            
                                                        
            
                                    
            
            
                | 83 |  |  |       '10.0': '10', | 
            
                                                        
            
                                    
            
            
                | 84 |  |  |       '6.4':  '10 Technical Preview', | 
            
                                                        
            
                                    
            
            
                | 85 |  |  |       '6.3':  '8.1', | 
            
                                                        
            
                                    
            
            
                | 86 |  |  |       '6.2':  '8', | 
            
                                                        
            
                                    
            
            
                | 87 |  |  |       '6.1':  'Server 2008 R2 / 7', | 
            
                                                        
            
                                    
            
            
                | 88 |  |  |       '6.0':  'Server 2008 / Vista', | 
            
                                                        
            
                                    
            
            
                | 89 |  |  |       '5.2':  'Server 2003 / XP 64-bit', | 
            
                                                        
            
                                    
            
            
                | 90 |  |  |       '5.1':  'XP', | 
            
                                                        
            
                                    
            
            
                | 91 |  |  |       '5.01': '2000 SP1', | 
            
                                                        
            
                                    
            
            
                | 92 |  |  |       '5.0':  '2000', | 
            
                                                        
            
                                    
            
            
                | 93 |  |  |       '4.0':  'NT', | 
            
                                                        
            
                                    
            
            
                | 94 |  |  |       '4.90': 'ME' | 
            
                                                        
            
                                    
            
            
                | 95 |  |  |     }; | 
            
                                                        
            
                                    
            
            
                | 96 |  |  |     // Detect Windows version from platform tokens. | 
            
                                                        
            
                                    
            
            
                | 97 |  |  |     if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && | 
            
                                                        
            
                                    
            
            
                | 98 |  |  |         (data = data[/[\d.]+$/.exec(os)])) { | 
            
                                                        
            
                                    
            
            
                | 99 |  |  |       os = 'Windows ' + data; | 
            
                                                        
            
                                    
            
            
                | 100 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 101 |  |  |     // Correct character case and cleanup string. | 
            
                                                        
            
                                    
            
            
                | 102 |  |  |     os = String(os); | 
            
                                                        
            
                                    
            
            
                | 103 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 104 |  |  |     if (pattern && label) { | 
            
                                                        
            
                                    
            
            
                | 105 |  |  |       os = os.replace(RegExp(pattern, 'i'), label); | 
            
                                                        
            
                                    
            
            
                | 106 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 107 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 108 |  |  |     os = format( | 
            
                                                        
            
                                    
            
            
                | 109 |  |  |       os.replace(/ ce$/i, ' CE') | 
            
                                                        
            
                                    
            
            
                | 110 |  |  |         .replace(/\bhpw/i, 'web') | 
            
                                                        
            
                                    
            
            
                | 111 |  |  |         .replace(/\bMacintosh\b/, 'Mac OS') | 
            
                                                        
            
                                    
            
            
                | 112 |  |  |         .replace(/_PowerPC\b/i, ' OS') | 
            
                                                        
            
                                    
            
            
                | 113 |  |  |         .replace(/\b(OS X) [^ \d]+/i, '$1') | 
            
                                                        
            
                                    
            
            
                | 114 |  |  |         .replace(/\bMac (OS X)\b/, '$1') | 
            
                                                        
            
                                    
            
            
                | 115 |  |  |         .replace(/\/(\d)/, ' $1') | 
            
                                                        
            
                                    
            
            
                | 116 |  |  |         .replace(/_/g, '.') | 
            
                                                        
            
                                    
            
            
                | 117 |  |  |         .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') | 
            
                                                        
            
                                    
            
            
                | 118 |  |  |         .replace(/\bx86\.64\b/gi, 'x86_64') | 
            
                                                        
            
                                    
            
            
                | 119 |  |  |         .replace(/\b(Windows Phone) OS\b/, '$1') | 
            
                                                        
            
                                    
            
            
                | 120 |  |  |         .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') | 
            
                                                        
            
                                    
            
            
                | 121 |  |  |         .split(' on ')[0] | 
            
                                                        
            
                                    
            
            
                | 122 |  |  |     ); | 
            
                                                        
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 124 |  |  |     return os; | 
            
                                                        
            
                                    
            
            
                | 125 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 126 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 127 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 128 |  |  |    * An iteration utility for arrays and objects. | 
            
                                                        
            
                                    
            
            
                | 129 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 130 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 131 |  |  |    * @param {Array|Object} object The object to iterate over. | 
            
                                                        
            
                                    
            
            
                | 132 |  |  |    * @param {Function} callback The function called per iteration. | 
            
                                                        
            
                                    
            
            
                | 133 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 134 |  |  |   function each(object, callback) { | 
            
                                                        
            
                                    
            
            
                | 135 |  |  |     var index = -1, | 
            
                                                        
            
                                    
            
            
                | 136 |  |  |         length = object ? object.length : 0; | 
            
                                                        
            
                                    
            
            
                | 137 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 138 |  |  |     if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { | 
            
                                                        
            
                                    
            
            
                | 139 |  |  |       while (++index < length) { | 
            
                                                        
            
                                    
            
            
                | 140 |  |  |         callback(object[index], index, object); | 
            
                                                        
            
                                    
            
            
                | 141 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 142 |  |  |     } else { | 
            
                                                        
            
                                    
            
            
                | 143 |  |  |       forOwn(object, callback); | 
            
                                                        
            
                                    
            
            
                | 144 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 145 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 146 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 147 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 148 |  |  |    * Trim and conditionally capitalize string values. | 
            
                                                        
            
                                    
            
            
                | 149 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 150 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 151 |  |  |    * @param {string} string The string to format. | 
            
                                                        
            
                                    
            
            
                | 152 |  |  |    * @returns {string} The formatted string. | 
            
                                                        
            
                                    
            
            
                | 153 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 154 |  |  |   function format(string) { | 
            
                                                        
            
                                    
            
            
                | 155 |  |  |     string = trim(string); | 
            
                                                        
            
                                    
            
            
                | 156 |  |  |     return /^(?:webOS|i(?:OS|P))/.test(string) | 
            
                                                        
            
                                    
            
            
                | 157 |  |  |       ? string | 
            
                                                        
            
                                    
            
            
                | 158 |  |  |       : capitalize(string); | 
            
                                                        
            
                                    
            
            
                | 159 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 160 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 161 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 162 |  |  |    * Iterates over an object's own properties, executing the `callback` for each. | 
            
                                                        
            
                                    
            
            
                | 163 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 164 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 165 |  |  |    * @param {Object} object The object to iterate over. | 
            
                                                        
            
                                    
            
            
                | 166 |  |  |    * @param {Function} callback The function executed per own property. | 
            
                                                        
            
                                    
            
            
                | 167 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 168 |  |  |   function forOwn(object, callback) { | 
            
                                                        
            
                                    
            
            
                | 169 |  |  |     for (var key in object) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 170 |  |  |       if (hasOwnProperty.call(object, key)) { | 
            
                                                        
            
                                    
            
            
                | 171 |  |  |         callback(object[key], key, object); | 
            
                                                        
            
                                    
            
            
                | 172 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 173 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 174 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 175 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 176 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 177 |  |  |    * Gets the internal `[[Class]]` of a value. | 
            
                                                        
            
                                    
            
            
                | 178 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 179 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 180 |  |  |    * @param {*} value The value. | 
            
                                                        
            
                                    
            
            
                | 181 |  |  |    * @returns {string} The `[[Class]]`. | 
            
                                                        
            
                                    
            
            
                | 182 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 183 |  |  |   function getClassOf(value) { | 
            
                                                        
            
                                    
            
            
                | 184 |  |  |     return value == null | 
            
                                                        
            
                                    
            
            
                | 185 |  |  |       ? capitalize(value) | 
            
                                                        
            
                                    
            
            
                | 186 |  |  |       : toString.call(value).slice(8, -1); | 
            
                                                        
            
                                    
            
            
                | 187 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 189 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 190 |  |  |    * Host objects can return type values that are different from their actual | 
            
                                                        
            
                                    
            
            
                | 191 |  |  |    * data type. The objects we are concerned with usually return non-primitive | 
            
                                                        
            
                                    
            
            
                | 192 |  |  |    * types of "object", "function", or "unknown". | 
            
                                                        
            
                                    
            
            
                | 193 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 194 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 195 |  |  |    * @param {*} object The owner of the property. | 
            
                                                        
            
                                    
            
            
                | 196 |  |  |    * @param {string} property The property to check. | 
            
                                                        
            
                                    
            
            
                | 197 |  |  |    * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. | 
            
                                                        
            
                                    
            
            
                | 198 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 199 |  |  |   function isHostType(object, property) { | 
            
                                                        
            
                                    
            
            
                | 200 |  |  |     var type = object != null ? typeof object[property] : 'number'; | 
            
                                                        
            
                                    
            
            
                | 201 |  |  |     return !/^(?:boolean|number|string|undefined)$/.test(type) && | 
            
                                                        
            
                                    
            
            
                | 202 |  |  |       (type == 'object' ? !!object[property] : true); | 
            
                                                        
            
                                    
            
            
                | 203 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 204 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 205 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 206 |  |  |    * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. | 
            
                                                        
            
                                    
            
            
                | 207 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 208 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 209 |  |  |    * @param {string} string The string to qualify. | 
            
                                                        
            
                                    
            
            
                | 210 |  |  |    * @returns {string} The qualified string. | 
            
                                                        
            
                                    
            
            
                | 211 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 212 |  |  |   function qualify(string) { | 
            
                                                        
            
                                    
            
            
                | 213 |  |  |     return String(string).replace(/([ -])(?!$)/g, '$1?'); | 
            
                                                        
            
                                    
            
            
                | 214 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 215 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 216 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 217 |  |  |    * A bare-bones `Array#reduce` like utility function. | 
            
                                                        
            
                                    
            
            
                | 218 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 219 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 220 |  |  |    * @param {Array} array The array to iterate over. | 
            
                                                        
            
                                    
            
            
                | 221 |  |  |    * @param {Function} callback The function called per iteration. | 
            
                                                        
            
                                    
            
            
                | 222 |  |  |    * @returns {*} The accumulated result. | 
            
                                                        
            
                                    
            
            
                | 223 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 224 |  |  |   function reduce(array, callback) { | 
            
                                                        
            
                                    
            
            
                | 225 |  |  |     var accumulator = null; | 
            
                                                        
            
                                    
            
            
                | 226 |  |  |     each(array, function(value, index) { | 
            
                                                        
            
                                    
            
            
                | 227 |  |  |       accumulator = callback(accumulator, value, index, array); | 
            
                                                        
            
                                    
            
            
                | 228 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 229 |  |  |     return accumulator; | 
            
                                                        
            
                                    
            
            
                | 230 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 231 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 232 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 233 |  |  |    * Removes leading and trailing whitespace from a string. | 
            
                                                        
            
                                    
            
            
                | 234 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 235 |  |  |    * @private | 
            
                                                        
            
                                    
            
            
                | 236 |  |  |    * @param {string} string The string to trim. | 
            
                                                        
            
                                    
            
            
                | 237 |  |  |    * @returns {string} The trimmed string. | 
            
                                                        
            
                                    
            
            
                | 238 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 239 |  |  |   function trim(string) { | 
            
                                                        
            
                                    
            
            
                | 240 |  |  |     return String(string).replace(/^ +| +$/g, ''); | 
            
                                                        
            
                                    
            
            
                | 241 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 242 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 243 |  |  |   /*--------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 244 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 245 |  |  |   /** | 
            
                                                        
            
                                    
            
            
                | 246 |  |  |    * Creates a new platform object. | 
            
                                                        
            
                                    
            
            
                | 247 |  |  |    * | 
            
                                                        
            
                                    
            
            
                | 248 |  |  |    * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 249 |  |  |    * @param {Object|string} [ua=navigator.userAgent] The user agent string or | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 250 |  |  |    *  context object. | 
            
                                                        
            
                                    
            
            
                | 251 |  |  |    * @returns {Object} A platform object. | 
            
                                                        
            
                                    
            
            
                | 252 |  |  |    */ | 
            
                                                        
            
                                    
            
            
                | 253 |  |  |   function parse(ua) { | 
            
                                                        
            
                                    
            
            
                | 254 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 255 |  |  |     /** The environment context object. */ | 
            
                                                        
            
                                    
            
            
                | 256 |  |  |     var context = root; | 
            
                                                        
            
                                    
            
            
                | 257 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 258 |  |  |     /** Used to flag when a custom context is provided. */ | 
            
                                                        
            
                                    
            
            
                | 259 |  |  |     var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; | 
            
                                                        
            
                                    
            
            
                | 260 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 261 |  |  |     // Juggle arguments. | 
            
                                                        
            
                                    
            
            
                | 262 |  |  |     if (isCustomContext) { | 
            
                                                        
            
                                    
            
            
                | 263 |  |  |       context = ua; | 
            
                                                        
            
                                    
            
            
                | 264 |  |  |       ua = null; | 
            
                                                        
            
                                    
            
            
                | 265 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 266 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 267 |  |  |     /** Browser navigator object. */ | 
            
                                                        
            
                                    
            
            
                | 268 |  |  |     var nav = context.navigator || {}; | 
            
                                                        
            
                                    
            
            
                | 269 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 270 |  |  |     /** Browser user agent string. */ | 
            
                                                        
            
                                    
            
            
                | 271 |  |  |     var userAgent = nav.userAgent || ''; | 
            
                                                        
            
                                    
            
            
                | 272 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 273 |  |  |     ua || (ua = userAgent); | 
            
                                                        
            
                                    
            
            
                | 274 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 275 |  |  |     /** Used to flag when `thisBinding` is the [ModuleScope]. */ | 
            
                                                        
            
                                    
            
            
                | 276 |  |  |     var isModuleScope = isCustomContext || thisBinding == oldRoot; | 
            
                                                        
            
                                    
            
            
                | 277 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 278 |  |  |     /** Used to detect if browser is like Chrome. */ | 
            
                                                        
            
                                    
            
            
                | 279 |  |  |     var likeChrome = isCustomContext | 
            
                                                        
            
                                    
            
            
                | 280 |  |  |       ? !!nav.likeChrome | 
            
                                                        
            
                                    
            
            
                | 281 |  |  |       : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); | 
            
                                                        
            
                                    
            
            
                | 282 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 283 |  |  |     /** Internal `[[Class]]` value shortcuts. */ | 
            
                                                        
            
                                    
            
            
                | 284 |  |  |     var objectClass = 'Object', | 
            
                                                        
            
                                    
            
            
                | 285 |  |  |         airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', | 
            
                                                        
            
                                    
            
            
                | 286 |  |  |         enviroClass = isCustomContext ? objectClass : 'Environment', | 
            
                                                        
            
                                    
            
            
                | 287 |  |  |         javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), | 
            
                                                        
            
                                    
            
            
                | 288 |  |  |         phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; | 
            
                                                        
            
                                    
            
            
                | 289 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 290 |  |  |     /** Detect Java environments. */ | 
            
                                                        
            
                                    
            
            
                | 291 |  |  |     var java = /\bJava/.test(javaClass) && context.java; | 
            
                                                        
            
                                    
            
            
                | 292 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 293 |  |  |     /** Detect Rhino. */ | 
            
                                                        
            
                                    
            
            
                | 294 |  |  |     var rhino = java && getClassOf(context.environment) == enviroClass; | 
            
                                                        
            
                                    
            
            
                | 295 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 296 |  |  |     /** A character to represent alpha. */ | 
            
                                                        
            
                                    
            
            
                | 297 |  |  |     var alpha = java ? 'a' : '\u03b1'; | 
            
                                                        
            
                                    
            
            
                | 298 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 299 |  |  |     /** A character to represent beta. */ | 
            
                                                        
            
                                    
            
            
                | 300 |  |  |     var beta = java ? 'b' : '\u03b2'; | 
            
                                                        
            
                                    
            
            
                | 301 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 302 |  |  |     /** Browser document object. */ | 
            
                                                        
            
                                    
            
            
                | 303 |  |  |     var doc = context.document || {}; | 
            
                                                        
            
                                    
            
            
                | 304 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 305 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 306 |  |  |      * Detect Opera browser (Presto-based). | 
            
                                                        
            
                                    
            
            
                | 307 |  |  |      * http://www.howtocreate.co.uk/operaStuff/operaObject.html | 
            
                                                        
            
                                    
            
            
                | 308 |  |  |      * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini | 
            
                                                        
            
                                    
            
            
                | 309 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 310 |  |  |     var opera = context.operamini || context.opera; | 
            
                                                        
            
                                    
            
            
                | 311 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 312 |  |  |     /** Opera `[[Class]]`. */ | 
            
                                                        
            
                                    
            
            
                | 313 |  |  |     var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) | 
            
                                                        
            
                                    
            
            
                | 314 |  |  |       ? operaClass | 
            
                                                        
            
                                    
            
            
                | 315 |  |  |       : (opera = null); | 
            
                                                        
            
                                    
            
            
                | 316 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 317 |  |  |     /*------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 318 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 319 |  |  |     /** Temporary variable used over the script's lifetime. */ | 
            
                                                        
            
                                    
            
            
                | 320 |  |  |     var data; | 
            
                                                        
            
                                    
            
            
                | 321 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 322 |  |  |     /** The CPU architecture. */ | 
            
                                                        
            
                                    
            
            
                | 323 |  |  |     var arch = ua; | 
            
                                                        
            
                                    
            
            
                | 324 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 325 |  |  |     /** Platform description array. */ | 
            
                                                        
            
                                    
            
            
                | 326 |  |  |     var description = []; | 
            
                                                        
            
                                    
            
            
                | 327 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 328 |  |  |     /** Platform alpha/beta indicator. */ | 
            
                                                        
            
                                    
            
            
                | 329 |  |  |     var prerelease = null; | 
            
                                                        
            
                                    
            
            
                | 330 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 331 |  |  |     /** A flag to indicate that environment features should be used to resolve the platform. */ | 
            
                                                        
            
                                    
            
            
                | 332 |  |  |     var useFeatures = ua == userAgent; | 
            
                                                        
            
                                    
            
            
                | 333 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 334 |  |  |     /** The browser/environment version. */ | 
            
                                                        
            
                                    
            
            
                | 335 |  |  |     var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); | 
            
                                                        
            
                                    
            
            
                | 336 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 337 |  |  |     /** A flag to indicate if the OS ends with "/ Version" */ | 
            
                                                        
            
                                    
            
            
                | 338 |  |  |     var isSpecialCasedOS; | 
            
                                                        
            
                                    
            
            
                | 339 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 340 |  |  |     /* Detectable layout engines (order is important). */ | 
            
                                                        
            
                                    
            
            
                | 341 |  |  |     var layout = getLayout([ | 
            
                                                        
            
                                    
            
            
                | 342 |  |  |       { 'label': 'EdgeHTML', 'pattern': 'Edge' }, | 
            
                                                        
            
                                    
            
            
                | 343 |  |  |       'Trident', | 
            
                                                        
            
                                    
            
            
                | 344 |  |  |       { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, | 
            
                                                        
            
                                    
            
            
                | 345 |  |  |       'iCab', | 
            
                                                        
            
                                    
            
            
                | 346 |  |  |       'Presto', | 
            
                                                        
            
                                    
            
            
                | 347 |  |  |       'NetFront', | 
            
                                                        
            
                                    
            
            
                | 348 |  |  |       'Tasman', | 
            
                                                        
            
                                    
            
            
                | 349 |  |  |       'KHTML', | 
            
                                                        
            
                                    
            
            
                | 350 |  |  |       'Gecko' | 
            
                                                        
            
                                    
            
            
                | 351 |  |  |     ]); | 
            
                                                        
            
                                    
            
            
                | 352 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 353 |  |  |     /* Detectable browser names (order is important). */ | 
            
                                                        
            
                                    
            
            
                | 354 |  |  |     var name = getName([ | 
            
                                                        
            
                                    
            
            
                | 355 |  |  |       'Adobe AIR', | 
            
                                                        
            
                                    
            
            
                | 356 |  |  |       'Arora', | 
            
                                                        
            
                                    
            
            
                | 357 |  |  |       'Avant Browser', | 
            
                                                        
            
                                    
            
            
                | 358 |  |  |       'Breach', | 
            
                                                        
            
                                    
            
            
                | 359 |  |  |       'Camino', | 
            
                                                        
            
                                    
            
            
                | 360 |  |  |       'Electron', | 
            
                                                        
            
                                    
            
            
                | 361 |  |  |       'Epiphany', | 
            
                                                        
            
                                    
            
            
                | 362 |  |  |       'Fennec', | 
            
                                                        
            
                                    
            
            
                | 363 |  |  |       'Flock', | 
            
                                                        
            
                                    
            
            
                | 364 |  |  |       'Galeon', | 
            
                                                        
            
                                    
            
            
                | 365 |  |  |       'GreenBrowser', | 
            
                                                        
            
                                    
            
            
                | 366 |  |  |       'iCab', | 
            
                                                        
            
                                    
            
            
                | 367 |  |  |       'Iceweasel', | 
            
                                                        
            
                                    
            
            
                | 368 |  |  |       'K-Meleon', | 
            
                                                        
            
                                    
            
            
                | 369 |  |  |       'Konqueror', | 
            
                                                        
            
                                    
            
            
                | 370 |  |  |       'Lunascape', | 
            
                                                        
            
                                    
            
            
                | 371 |  |  |       'Maxthon', | 
            
                                                        
            
                                    
            
            
                | 372 |  |  |       { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, | 
            
                                                        
            
                                    
            
            
                | 373 |  |  |       'Midori', | 
            
                                                        
            
                                    
            
            
                | 374 |  |  |       'Nook Browser', | 
            
                                                        
            
                                    
            
            
                | 375 |  |  |       'PaleMoon', | 
            
                                                        
            
                                    
            
            
                | 376 |  |  |       'PhantomJS', | 
            
                                                        
            
                                    
            
            
                | 377 |  |  |       'Raven', | 
            
                                                        
            
                                    
            
            
                | 378 |  |  |       'Rekonq', | 
            
                                                        
            
                                    
            
            
                | 379 |  |  |       'RockMelt', | 
            
                                                        
            
                                    
            
            
                | 380 |  |  |       { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, | 
            
                                                        
            
                                    
            
            
                | 381 |  |  |       'SeaMonkey', | 
            
                                                        
            
                                    
            
            
                | 382 |  |  |       { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, | 
            
                                                        
            
                                    
            
            
                | 383 |  |  |       'Sleipnir', | 
            
                                                        
            
                                    
            
            
                | 384 |  |  |       'SlimBrowser', | 
            
                                                        
            
                                    
            
            
                | 385 |  |  |       { 'label': 'SRWare Iron', 'pattern': 'Iron' }, | 
            
                                                        
            
                                    
            
            
                | 386 |  |  |       'Sunrise', | 
            
                                                        
            
                                    
            
            
                | 387 |  |  |       'Swiftfox', | 
            
                                                        
            
                                    
            
            
                | 388 |  |  |       'Waterfox', | 
            
                                                        
            
                                    
            
            
                | 389 |  |  |       'WebPositive', | 
            
                                                        
            
                                    
            
            
                | 390 |  |  |       'Opera Mini', | 
            
                                                        
            
                                    
            
            
                | 391 |  |  |       { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, | 
            
                                                        
            
                                    
            
            
                | 392 |  |  |       'Opera', | 
            
                                                        
            
                                    
            
            
                | 393 |  |  |       { 'label': 'Opera', 'pattern': 'OPR' }, | 
            
                                                        
            
                                    
            
            
                | 394 |  |  |       'Chrome', | 
            
                                                        
            
                                    
            
            
                | 395 |  |  |       { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, | 
            
                                                        
            
                                    
            
            
                | 396 |  |  |       { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, | 
            
                                                        
            
                                    
            
            
                | 397 |  |  |       { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, | 
            
                                                        
            
                                    
            
            
                | 398 |  |  |       { 'label': 'IE', 'pattern': 'IEMobile' }, | 
            
                                                        
            
                                    
            
            
                | 399 |  |  |       { 'label': 'IE', 'pattern': 'MSIE' }, | 
            
                                                        
            
                                    
            
            
                | 400 |  |  |       'Safari' | 
            
                                                        
            
                                    
            
            
                | 401 |  |  |     ]); | 
            
                                                        
            
                                    
            
            
                | 402 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 403 |  |  |     /* Detectable products (order is important). */ | 
            
                                                        
            
                                    
            
            
                | 404 |  |  |     var product = getProduct([ | 
            
                                                        
            
                                    
            
            
                | 405 |  |  |       { 'label': 'BlackBerry', 'pattern': 'BB10' }, | 
            
                                                        
            
                                    
            
            
                | 406 |  |  |       'BlackBerry', | 
            
                                                        
            
                                    
            
            
                | 407 |  |  |       { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, | 
            
                                                        
            
                                    
            
            
                | 408 |  |  |       { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, | 
            
                                                        
            
                                    
            
            
                | 409 |  |  |       { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, | 
            
                                                        
            
                                    
            
            
                | 410 |  |  |       { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, | 
            
                                                        
            
                                    
            
            
                | 411 |  |  |       { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, | 
            
                                                        
            
                                    
            
            
                | 412 |  |  |       { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, | 
            
                                                        
            
                                    
            
            
                | 413 |  |  |       { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, | 
            
                                                        
            
                                    
            
            
                | 414 |  |  |       { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, | 
            
                                                        
            
                                    
            
            
                | 415 |  |  |       { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, | 
            
                                                        
            
                                    
            
            
                | 416 |  |  |       'Google TV', | 
            
                                                        
            
                                    
            
            
                | 417 |  |  |       'Lumia', | 
            
                                                        
            
                                    
            
            
                | 418 |  |  |       'iPad', | 
            
                                                        
            
                                    
            
            
                | 419 |  |  |       'iPod', | 
            
                                                        
            
                                    
            
            
                | 420 |  |  |       'iPhone', | 
            
                                                        
            
                                    
            
            
                | 421 |  |  |       'Kindle', | 
            
                                                        
            
                                    
            
            
                | 422 |  |  |       { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, | 
            
                                                        
            
                                    
            
            
                | 423 |  |  |       'Nexus', | 
            
                                                        
            
                                    
            
            
                | 424 |  |  |       'Nook', | 
            
                                                        
            
                                    
            
            
                | 425 |  |  |       'PlayBook', | 
            
                                                        
            
                                    
            
            
                | 426 |  |  |       'PlayStation Vita', | 
            
                                                        
            
                                    
            
            
                | 427 |  |  |       'PlayStation', | 
            
                                                        
            
                                    
            
            
                | 428 |  |  |       'TouchPad', | 
            
                                                        
            
                                    
            
            
                | 429 |  |  |       'Transformer', | 
            
                                                        
            
                                    
            
            
                | 430 |  |  |       { 'label': 'Wii U', 'pattern': 'WiiU' }, | 
            
                                                        
            
                                    
            
            
                | 431 |  |  |       'Wii', | 
            
                                                        
            
                                    
            
            
                | 432 |  |  |       'Xbox One', | 
            
                                                        
            
                                    
            
            
                | 433 |  |  |       { 'label': 'Xbox 360', 'pattern': 'Xbox' }, | 
            
                                                        
            
                                    
            
            
                | 434 |  |  |       'Xoom' | 
            
                                                        
            
                                    
            
            
                | 435 |  |  |     ]); | 
            
                                                        
            
                                    
            
            
                | 436 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 437 |  |  |     /* Detectable manufacturers. */ | 
            
                                                        
            
                                    
            
            
                | 438 |  |  |     var manufacturer = getManufacturer({ | 
            
                                                        
            
                                    
            
            
                | 439 |  |  |       'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, | 
            
                                                        
            
                                    
            
            
                | 440 |  |  |       'Archos': {}, | 
            
                                                        
            
                                    
            
            
                | 441 |  |  |       'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, | 
            
                                                        
            
                                    
            
            
                | 442 |  |  |       'Asus': { 'Transformer': 1 }, | 
            
                                                        
            
                                    
            
            
                | 443 |  |  |       'Barnes & Noble': { 'Nook': 1 }, | 
            
                                                        
            
                                    
            
            
                | 444 |  |  |       'BlackBerry': { 'PlayBook': 1 }, | 
            
                                                        
            
                                    
            
            
                | 445 |  |  |       'Google': { 'Google TV': 1, 'Nexus': 1 }, | 
            
                                                        
            
                                    
            
            
                | 446 |  |  |       'HP': { 'TouchPad': 1 }, | 
            
                                                        
            
                                    
            
            
                | 447 |  |  |       'HTC': {}, | 
            
                                                        
            
                                    
            
            
                | 448 |  |  |       'LG': {}, | 
            
                                                        
            
                                    
            
            
                | 449 |  |  |       'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, | 
            
                                                        
            
                                    
            
            
                | 450 |  |  |       'Motorola': { 'Xoom': 1 }, | 
            
                                                        
            
                                    
            
            
                | 451 |  |  |       'Nintendo': { 'Wii U': 1,  'Wii': 1 }, | 
            
                                                        
            
                                    
            
            
                | 452 |  |  |       'Nokia': { 'Lumia': 1 }, | 
            
                                                        
            
                                    
            
            
                | 453 |  |  |       'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, | 
            
                                                        
            
                                    
            
            
                | 454 |  |  |       'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } | 
            
                                                        
            
                                    
            
            
                | 455 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 456 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 457 |  |  |     /* Detectable operating systems (order is important). */ | 
            
                                                        
            
                                    
            
            
                | 458 |  |  |     var os = getOS([ | 
            
                                                        
            
                                    
            
            
                | 459 |  |  |       'Windows Phone', | 
            
                                                        
            
                                    
            
            
                | 460 |  |  |       'Android', | 
            
                                                        
            
                                    
            
            
                | 461 |  |  |       'CentOS', | 
            
                                                        
            
                                    
            
            
                | 462 |  |  |       { 'label': 'Chrome OS', 'pattern': 'CrOS' }, | 
            
                                                        
            
                                    
            
            
                | 463 |  |  |       'Debian', | 
            
                                                        
            
                                    
            
            
                | 464 |  |  |       'Fedora', | 
            
                                                        
            
                                    
            
            
                | 465 |  |  |       'FreeBSD', | 
            
                                                        
            
                                    
            
            
                | 466 |  |  |       'Gentoo', | 
            
                                                        
            
                                    
            
            
                | 467 |  |  |       'Haiku', | 
            
                                                        
            
                                    
            
            
                | 468 |  |  |       'Kubuntu', | 
            
                                                        
            
                                    
            
            
                | 469 |  |  |       'Linux Mint', | 
            
                                                        
            
                                    
            
            
                | 470 |  |  |       'OpenBSD', | 
            
                                                        
            
                                    
            
            
                | 471 |  |  |       'Red Hat', | 
            
                                                        
            
                                    
            
            
                | 472 |  |  |       'SuSE', | 
            
                                                        
            
                                    
            
            
                | 473 |  |  |       'Ubuntu', | 
            
                                                        
            
                                    
            
            
                | 474 |  |  |       'Xubuntu', | 
            
                                                        
            
                                    
            
            
                | 475 |  |  |       'Cygwin', | 
            
                                                        
            
                                    
            
            
                | 476 |  |  |       'Symbian OS', | 
            
                                                        
            
                                    
            
            
                | 477 |  |  |       'hpwOS', | 
            
                                                        
            
                                    
            
            
                | 478 |  |  |       'webOS ', | 
            
                                                        
            
                                    
            
            
                | 479 |  |  |       'webOS', | 
            
                                                        
            
                                    
            
            
                | 480 |  |  |       'Tablet OS', | 
            
                                                        
            
                                    
            
            
                | 481 |  |  |       'Tizen', | 
            
                                                        
            
                                    
            
            
                | 482 |  |  |       'Linux', | 
            
                                                        
            
                                    
            
            
                | 483 |  |  |       'Mac OS X', | 
            
                                                        
            
                                    
            
            
                | 484 |  |  |       'Macintosh', | 
            
                                                        
            
                                    
            
            
                | 485 |  |  |       'Mac', | 
            
                                                        
            
                                    
            
            
                | 486 |  |  |       'Windows 98;', | 
            
                                                        
            
                                    
            
            
                | 487 |  |  |       'Windows ' | 
            
                                                        
            
                                    
            
            
                | 488 |  |  |     ]); | 
            
                                                        
            
                                    
            
            
                | 489 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 490 |  |  |     /*------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 491 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 492 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 493 |  |  |      * Picks the layout engine from an array of guesses. | 
            
                                                        
            
                                    
            
            
                | 494 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 495 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 496 |  |  |      * @param {Array} guesses An array of guesses. | 
            
                                                        
            
                                    
            
            
                | 497 |  |  |      * @returns {null|string} The detected layout engine. | 
            
                                                        
            
                                    
            
            
                | 498 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 499 |  |  |     function getLayout(guesses) { | 
            
                                                        
            
                                    
            
            
                | 500 |  |  |       return reduce(guesses, function(result, guess) { | 
            
                                                        
            
                                    
            
            
                | 501 |  |  |         return result || RegExp('\\b' + ( | 
            
                                                        
            
                                    
            
            
                | 502 |  |  |           guess.pattern || qualify(guess) | 
            
                                                        
            
                                    
            
            
                | 503 |  |  |         ) + '\\b', 'i').exec(ua) && (guess.label || guess); | 
            
                                                        
            
                                    
            
            
                | 504 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 505 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 506 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 507 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 508 |  |  |      * Picks the manufacturer from an array of guesses. | 
            
                                                        
            
                                    
            
            
                | 509 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 510 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 511 |  |  |      * @param {Array} guesses An object of guesses. | 
            
                                                        
            
                                    
            
            
                | 512 |  |  |      * @returns {null|string} The detected manufacturer. | 
            
                                                        
            
                                    
            
            
                | 513 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 514 |  |  |     function getManufacturer(guesses) { | 
            
                                                        
            
                                    
            
            
                | 515 |  |  |       return reduce(guesses, function(result, value, key) { | 
            
                                                        
            
                                    
            
            
                | 516 |  |  |         // Lookup the manufacturer by product or scan the UA for the manufacturer. | 
            
                                                        
            
                                    
            
            
                | 517 |  |  |         return result || ( | 
            
                                                        
            
                                    
            
            
                | 518 |  |  |           value[product] || | 
            
                                                        
            
                                    
            
            
                | 519 |  |  |           value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || | 
            
                                                        
            
                                    
            
            
                | 520 |  |  |           RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) | 
            
                                                        
            
                                    
            
            
                | 521 |  |  |         ) && key; | 
            
                                                        
            
                                    
            
            
                | 522 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 523 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 524 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 525 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 526 |  |  |      * Picks the browser name from an array of guesses. | 
            
                                                        
            
                                    
            
            
                | 527 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 528 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 529 |  |  |      * @param {Array} guesses An array of guesses. | 
            
                                                        
            
                                    
            
            
                | 530 |  |  |      * @returns {null|string} The detected browser name. | 
            
                                                        
            
                                    
            
            
                | 531 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 532 |  |  |     function getName(guesses) { | 
            
                                                        
            
                                    
            
            
                | 533 |  |  |       return reduce(guesses, function(result, guess) { | 
            
                                                        
            
                                    
            
            
                | 534 |  |  |         return result || RegExp('\\b' + ( | 
            
                                                        
            
                                    
            
            
                | 535 |  |  |           guess.pattern || qualify(guess) | 
            
                                                        
            
                                    
            
            
                | 536 |  |  |         ) + '\\b', 'i').exec(ua) && (guess.label || guess); | 
            
                                                        
            
                                    
            
            
                | 537 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 538 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 539 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 540 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 541 |  |  |      * Picks the OS name from an array of guesses. | 
            
                                                        
            
                                    
            
            
                | 542 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 543 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 544 |  |  |      * @param {Array} guesses An array of guesses. | 
            
                                                        
            
                                    
            
            
                | 545 |  |  |      * @returns {null|string} The detected OS name. | 
            
                                                        
            
                                    
            
            
                | 546 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 547 |  |  |     function getOS(guesses) { | 
            
                                                        
            
                                    
            
            
                | 548 |  |  |       return reduce(guesses, function(result, guess) { | 
            
                                                        
            
                                    
            
            
                | 549 |  |  |         var pattern = guess.pattern || qualify(guess); | 
            
                                                        
            
                                    
            
            
                | 550 |  |  |         if (!result && (result = | 
            
                                                        
            
                                    
            
            
                | 551 |  |  |               RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) | 
            
                                                        
            
                                    
            
            
                | 552 |  |  |             )) { | 
            
                                                        
            
                                    
            
            
                | 553 |  |  |           result = cleanupOS(result, pattern, guess.label || guess); | 
            
                                                        
            
                                    
            
            
                | 554 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 555 |  |  |         return result; | 
            
                                                        
            
                                    
            
            
                | 556 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 557 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 558 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 559 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 560 |  |  |      * Picks the product name from an array of guesses. | 
            
                                                        
            
                                    
            
            
                | 561 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 562 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 563 |  |  |      * @param {Array} guesses An array of guesses. | 
            
                                                        
            
                                    
            
            
                | 564 |  |  |      * @returns {null|string} The detected product name. | 
            
                                                        
            
                                    
            
            
                | 565 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 566 |  |  |     function getProduct(guesses) { | 
            
                                                        
            
                                    
            
            
                | 567 |  |  |       return reduce(guesses, function(result, guess) { | 
            
                                                        
            
                                    
            
            
                | 568 |  |  |         var pattern = guess.pattern || qualify(guess); | 
            
                                                        
            
                                    
            
            
                | 569 |  |  |         if (!result && (result = | 
            
                                                        
            
                                    
            
            
                | 570 |  |  |               RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || | 
            
                                                        
            
                                    
            
            
                | 571 |  |  |               RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || | 
            
                                                        
            
                                    
            
            
                | 572 |  |  |               RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) | 
            
                                                        
            
                                    
            
            
                | 573 |  |  |             )) { | 
            
                                                        
            
                                    
            
            
                | 574 |  |  |           // Split by forward slash and append product version if needed. | 
            
                                                        
            
                                    
            
            
                | 575 |  |  |           if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { | 
            
                                                        
            
                                    
            
            
                | 576 |  |  |             result[0] += ' ' + result[1]; | 
            
                                                        
            
                                    
            
            
                | 577 |  |  |           } | 
            
                                                        
            
                                    
            
            
                | 578 |  |  |           // Correct character case and cleanup string. | 
            
                                                        
            
                                    
            
            
                | 579 |  |  |           guess = guess.label || guess; | 
            
                                                        
            
                                    
            
            
                | 580 |  |  |           result = format(result[0] | 
            
                                                        
            
                                    
            
            
                | 581 |  |  |             .replace(RegExp(pattern, 'i'), guess) | 
            
                                                        
            
                                    
            
            
                | 582 |  |  |             .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') | 
            
                                                        
            
                                    
            
            
                | 583 |  |  |             .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); | 
            
                                                        
            
                                    
            
            
                | 584 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 585 |  |  |         return result; | 
            
                                                        
            
                                    
            
            
                | 586 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 587 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 588 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 589 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 590 |  |  |      * Resolves the version using an array of UA patterns. | 
            
                                                        
            
                                    
            
            
                | 591 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 592 |  |  |      * @private | 
            
                                                        
            
                                    
            
            
                | 593 |  |  |      * @param {Array} patterns An array of UA patterns. | 
            
                                                        
            
                                    
            
            
                | 594 |  |  |      * @returns {null|string} The detected version. | 
            
                                                        
            
                                    
            
            
                | 595 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 596 |  |  |     function getVersion(patterns) { | 
            
                                                        
            
                                    
            
            
                | 597 |  |  |       return reduce(patterns, function(result, pattern) { | 
            
                                                        
            
                                    
            
            
                | 598 |  |  |         return result || (RegExp(pattern + | 
            
                                                        
            
                                    
            
            
                | 599 |  |  |           '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; | 
            
                                                        
            
                                    
            
            
                | 600 |  |  |       }); | 
            
                                                        
            
                                    
            
            
                | 601 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 602 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 603 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 604 |  |  |      * Returns `platform.description` when the platform object is coerced to a string. | 
            
                                                        
            
                                    
            
            
                | 605 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 606 |  |  |      * @name toString | 
            
                                                        
            
                                    
            
            
                | 607 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 608 |  |  |      * @returns {string} Returns `platform.description` if available, else an empty string. | 
            
                                                        
            
                                    
            
            
                | 609 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 610 |  |  |     function toStringPlatform() { | 
            
                                                        
            
                                    
            
            
                | 611 |  |  |       return this.description || ''; | 
            
                                                        
            
                                    
            
            
                | 612 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 613 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 614 |  |  |     /*------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 615 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 616 |  |  |     // Convert layout to an array so we can add extra details. | 
            
                                                        
            
                                    
            
            
                | 617 |  |  |     layout && (layout = [layout]); | 
            
                                                        
            
                                    
            
            
                | 618 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 619 |  |  |     // Detect product names that contain their manufacturer's name. | 
            
                                                        
            
                                    
            
            
                | 620 |  |  |     if (manufacturer && !product) { | 
            
                                                        
            
                                    
            
            
                | 621 |  |  |       product = getProduct([manufacturer]); | 
            
                                                        
            
                                    
            
            
                | 622 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 623 |  |  |     // Clean up Google TV. | 
            
                                                        
            
                                    
            
            
                | 624 |  |  |     if ((data = /\bGoogle TV\b/.exec(product))) { | 
            
                                                        
            
                                    
            
            
                | 625 |  |  |       product = data[0]; | 
            
                                                        
            
                                    
            
            
                | 626 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 627 |  |  |     // Detect simulators. | 
            
                                                        
            
                                    
            
            
                | 628 |  |  |     if (/\bSimulator\b/i.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 629 |  |  |       product = (product ? product + ' ' : '') + 'Simulator'; | 
            
                                                        
            
                                    
            
            
                | 630 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 631 |  |  |     // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. | 
            
                                                        
            
                                    
            
            
                | 632 |  |  |     if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 633 |  |  |       description.push('running in Turbo/Uncompressed mode'); | 
            
                                                        
            
                                    
            
            
                | 634 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 635 |  |  |     // Detect IE Mobile 11. | 
            
                                                        
            
                                    
            
            
                | 636 |  |  |     if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 637 |  |  |       data = parse(ua.replace(/like iPhone OS/, '')); | 
            
                                                        
            
                                    
            
            
                | 638 |  |  |       manufacturer = data.manufacturer; | 
            
                                                        
            
                                    
            
            
                | 639 |  |  |       product = data.product; | 
            
                                                        
            
                                    
            
            
                | 640 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 641 |  |  |     // Detect iOS. | 
            
                                                        
            
                                    
            
            
                | 642 |  |  |     else if (/^iP/.test(product)) { | 
            
                                                        
            
                                    
            
            
                | 643 |  |  |       name || (name = 'Safari'); | 
            
                                                        
            
                                    
            
            
                | 644 |  |  |       os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) | 
            
                                                        
            
                                    
            
            
                | 645 |  |  |         ? ' ' + data[1].replace(/_/g, '.') | 
            
                                                        
            
                                    
            
            
                | 646 |  |  |         : ''); | 
            
                                                        
            
                                    
            
            
                | 647 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 648 |  |  |     // Detect Kubuntu. | 
            
                                                        
            
                                    
            
            
                | 649 |  |  |     else if (name == 'Konqueror' && !/buntu/i.test(os)) { | 
            
                                                        
            
                                    
            
            
                | 650 |  |  |       os = 'Kubuntu'; | 
            
                                                        
            
                                    
            
            
                | 651 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 652 |  |  |     // Detect Android browsers. | 
            
                                                        
            
                                    
            
            
                | 653 |  |  |     else if ((manufacturer && manufacturer != 'Google' && | 
            
                                                        
            
                                    
            
            
                | 654 |  |  |         ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || | 
            
                                                        
            
                                    
            
            
                | 655 |  |  |         (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { | 
            
                                                        
            
                                    
            
            
                | 656 |  |  |       name = 'Android Browser'; | 
            
                                                        
            
                                    
            
            
                | 657 |  |  |       os = /\bAndroid\b/.test(os) ? os : 'Android'; | 
            
                                                        
            
                                    
            
            
                | 658 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 659 |  |  |     // Detect Silk desktop/accelerated modes. | 
            
                                                        
            
                                    
            
            
                | 660 |  |  |     else if (name == 'Silk') { | 
            
                                                        
            
                                    
            
            
                | 661 |  |  |       if (!/\bMobi/i.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 662 |  |  |         os = 'Android'; | 
            
                                                        
            
                                    
            
            
                | 663 |  |  |         description.unshift('desktop mode'); | 
            
                                                        
            
                                    
            
            
                | 664 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 665 |  |  |       if (/Accelerated *= *true/i.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 666 |  |  |         description.unshift('accelerated'); | 
            
                                                        
            
                                    
            
            
                | 667 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 668 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 669 |  |  |     // Detect PaleMoon identifying as Firefox. | 
            
                                                        
            
                                    
            
            
                | 670 |  |  |     else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { | 
            
                                                        
            
                                    
            
            
                | 671 |  |  |       description.push('identifying as Firefox ' + data[1]); | 
            
                                                        
            
                                    
            
            
                | 672 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 673 |  |  |     // Detect Firefox OS and products running Firefox. | 
            
                                                        
            
                                    
            
            
                | 674 |  |  |     else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { | 
            
                                                        
            
                                    
            
            
                | 675 |  |  |       os || (os = 'Firefox OS'); | 
            
                                                        
            
                                    
            
            
                | 676 |  |  |       product || (product = data[1]); | 
            
                                                        
            
                                    
            
            
                | 677 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 678 |  |  |     // Detect false positives for Firefox/Safari. | 
            
                                                        
            
                                    
            
            
                | 679 |  |  |     else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { | 
            
                                                        
            
                                    
            
            
                | 680 |  |  |       // Escape the `/` for Firefox 1. | 
            
                                                        
            
                                    
            
            
                | 681 |  |  |       if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { | 
            
                                                        
            
                                    
            
            
                | 682 |  |  |         // Clear name of false positives. | 
            
                                                        
            
                                    
            
            
                | 683 |  |  |         name = null; | 
            
                                                        
            
                                    
            
            
                | 684 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 685 |  |  |       // Reassign a generic name. | 
            
                                                        
            
                                    
            
            
                | 686 |  |  |       if ((data = product || manufacturer || os) && | 
            
                                                        
            
                                    
            
            
                | 687 |  |  |           (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { | 
            
                                                        
            
                                    
            
            
                | 688 |  |  |         name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; | 
            
                                                        
            
                                    
            
            
                | 689 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 690 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 691 |  |  |     // Add Chrome version to description for Electron. | 
            
                                                        
            
                                    
            
            
                | 692 |  |  |     else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { | 
            
                                                        
            
                                    
            
            
                | 693 |  |  |       description.push('Chromium ' + data); | 
            
                                                        
            
                                    
            
            
                | 694 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 695 |  |  |     // Detect non-Opera (Presto-based) versions (order is important). | 
            
                                                        
            
                                    
            
            
                | 696 |  |  |     if (!version) { | 
            
                                                        
            
                                    
            
            
                | 697 |  |  |       version = getVersion([ | 
            
                                                        
            
                                    
            
            
                | 698 |  |  |         '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', | 
            
                                                        
            
                                    
            
            
                | 699 |  |  |         'Version', | 
            
                                                        
            
                                    
            
            
                | 700 |  |  |         qualify(name), | 
            
                                                        
            
                                    
            
            
                | 701 |  |  |         '(?:Firefox|Minefield|NetFront)' | 
            
                                                        
            
                                    
            
            
                | 702 |  |  |       ]); | 
            
                                                        
            
                                    
            
            
                | 703 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 704 |  |  |     // Detect stubborn layout engines. | 
            
                                                        
            
                                    
            
            
                | 705 |  |  |     if ((data = | 
            
                                                        
            
                                    
            
            
                | 706 |  |  |           layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || | 
            
                                                        
            
                                    
            
            
                | 707 |  |  |           /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || | 
            
                                                        
            
                                    
            
            
                | 708 |  |  |           /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || | 
            
                                                        
            
                                    
            
            
                | 709 |  |  |           !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || | 
            
                                                        
            
                                    
            
            
                | 710 |  |  |           layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' | 
            
                                                        
            
                                    
            
            
                | 711 |  |  |         )) { | 
            
                                                        
            
                                    
            
            
                | 712 |  |  |       layout = [data]; | 
            
                                                        
            
                                    
            
            
                | 713 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 714 |  |  |     // Detect Windows Phone 7 desktop mode. | 
            
                                                        
            
                                    
            
            
                | 715 |  |  |     if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { | 
            
                                                        
            
                                    
            
            
                | 716 |  |  |       name += ' Mobile'; | 
            
                                                        
            
                                    
            
            
                | 717 |  |  |       os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); | 
            
                                                        
            
                                    
            
            
                | 718 |  |  |       description.unshift('desktop mode'); | 
            
                                                        
            
                                    
            
            
                | 719 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 720 |  |  |     // Detect Windows Phone 8.x desktop mode. | 
            
                                                        
            
                                    
            
            
                | 721 |  |  |     else if (/\bWPDesktop\b/i.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 722 |  |  |       name = 'IE Mobile'; | 
            
                                                        
            
                                    
            
            
                | 723 |  |  |       os = 'Windows Phone 8.x'; | 
            
                                                        
            
                                    
            
            
                | 724 |  |  |       description.unshift('desktop mode'); | 
            
                                                        
            
                                    
            
            
                | 725 |  |  |       version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); | 
            
                                                        
            
                                    
            
            
                | 726 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 727 |  |  |     // Detect IE 11 identifying as other browsers. | 
            
                                                        
            
                                    
            
            
                | 728 |  |  |     else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { | 
            
                                                        
            
                                    
            
            
                | 729 |  |  |       if (name) { | 
            
                                                        
            
                                    
            
            
                | 730 |  |  |         description.push('identifying as ' + name + (version ? ' ' + version : '')); | 
            
                                                        
            
                                    
            
            
                | 731 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 732 |  |  |       name = 'IE'; | 
            
                                                        
            
                                    
            
            
                | 733 |  |  |       version = data[1]; | 
            
                                                        
            
                                    
            
            
                | 734 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 735 |  |  |     // Leverage environment features. | 
            
                                                        
            
                                    
            
            
                | 736 |  |  |     if (useFeatures) { | 
            
                                                        
            
                                    
            
            
                | 737 |  |  |       // Detect server-side environments. | 
            
                                                        
            
                                    
            
            
                | 738 |  |  |       // Rhino has a global function while others have a global object. | 
            
                                                        
            
                                    
            
            
                | 739 |  |  |       if (isHostType(context, 'global')) { | 
            
                                                        
            
                                    
            
            
                | 740 |  |  |         if (java) { | 
            
                                                        
            
                                    
            
            
                | 741 |  |  |           data = java.lang.System; | 
            
                                                        
            
                                    
            
            
                | 742 |  |  |           arch = data.getProperty('os.arch'); | 
            
                                                        
            
                                    
            
            
                | 743 |  |  |           os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); | 
            
                                                        
            
                                    
            
            
                | 744 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 745 |  |  |         if (isModuleScope && isHostType(context, 'system') && (data = [context.system])[0]) { | 
            
                                                        
            
                                    
            
            
                | 746 |  |  |           os || (os = data[0].os || null); | 
            
                                                        
            
                                    
            
            
                | 747 |  |  |           try { | 
            
                                                        
            
                                    
            
            
                | 748 |  |  |             data[1] = context.require('ringo/engine').version; | 
            
                                                        
            
                                    
            
            
                | 749 |  |  |             version = data[1].join('.'); | 
            
                                                        
            
                                    
            
            
                | 750 |  |  |             name = 'RingoJS'; | 
            
                                                        
            
                                    
            
            
                | 751 |  |  |           } catch(e) { | 
            
                                                        
            
                                    
            
            
                | 752 |  |  |             if (data[0].global.system == context.system) { | 
            
                                                        
            
                                    
            
            
                | 753 |  |  |               name = 'Narwhal'; | 
            
                                                        
            
                                    
            
            
                | 754 |  |  |             } | 
            
                                                        
            
                                    
            
            
                | 755 |  |  |           } | 
            
                                                        
            
                                    
            
            
                | 756 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 757 |  |  |         else if ( | 
            
                                                        
            
                                    
            
            
                | 758 |  |  |           typeof context.process == 'object' && !context.process.browser && | 
            
                                                        
            
                                    
            
            
                | 759 |  |  |           (data = context.process) | 
            
                                                        
            
                                    
            
            
                | 760 |  |  |         ) { | 
            
                                                        
            
                                    
            
            
                | 761 |  |  |           if (typeof data.versions == 'object') { | 
            
                                                        
            
                                    
            
            
                | 762 |  |  |             if (typeof data.versions.electron == 'string') { | 
            
                                                        
            
                                    
            
            
                | 763 |  |  |               description.push('Node ' + data.versions.node); | 
            
                                                        
            
                                    
            
            
                | 764 |  |  |               name = 'Electron'; | 
            
                                                        
            
                                    
            
            
                | 765 |  |  |               version = data.versions.electron; | 
            
                                                        
            
                                    
            
            
                | 766 |  |  |             } else if (typeof data.versions.nw == 'string') { | 
            
                                                        
            
                                    
            
            
                | 767 |  |  |               description.push('Chromium ' + version, 'Node ' + data.versions.node); | 
            
                                                        
            
                                    
            
            
                | 768 |  |  |               name = 'NW.js'; | 
            
                                                        
            
                                    
            
            
                | 769 |  |  |               version = data.versions.nw; | 
            
                                                        
            
                                    
            
            
                | 770 |  |  |             } | 
            
                                                        
            
                                    
            
            
                | 771 |  |  |           } | 
            
                                                        
            
                                    
            
            
                | 772 |  |  |           if (!name) { | 
            
                                                        
            
                                    
            
            
                | 773 |  |  |             name = 'Node.js'; | 
            
                                                        
            
                                    
            
            
                | 774 |  |  |             arch = data.arch; | 
            
                                                        
            
                                    
            
            
                | 775 |  |  |             os = data.platform; | 
            
                                                        
            
                                    
            
            
                | 776 |  |  |             version = /[\d.]+/.exec(data.version) | 
            
                                                        
            
                                    
            
            
                | 777 |  |  |             version = version ? version[0] : 'unknown'; | 
            
                                                        
            
                                    
            
            
                | 778 |  |  |           } | 
            
                                                        
            
                                    
            
            
                | 779 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 780 |  |  |         else if (rhino) { | 
            
                                                        
            
                                    
            
            
                | 781 |  |  |           name = 'Rhino'; | 
            
                                                        
            
                                    
            
            
                | 782 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 783 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 784 |  |  |       // Detect Adobe AIR. | 
            
                                                        
            
                                    
            
            
                | 785 |  |  |       else if (getClassOf((data = context.runtime)) == airRuntimeClass) { | 
            
                                                        
            
                                    
            
            
                | 786 |  |  |         name = 'Adobe AIR'; | 
            
                                                        
            
                                    
            
            
                | 787 |  |  |         os = data.flash.system.Capabilities.os; | 
            
                                                        
            
                                    
            
            
                | 788 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 789 |  |  |       // Detect PhantomJS. | 
            
                                                        
            
                                    
            
            
                | 790 |  |  |       else if (getClassOf((data = context.phantom)) == phantomClass) { | 
            
                                                        
            
                                    
            
            
                | 791 |  |  |         name = 'PhantomJS'; | 
            
                                                        
            
                                    
            
            
                | 792 |  |  |         version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); | 
            
                                                        
            
                                    
            
            
                | 793 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 794 |  |  |       // Detect IE compatibility modes. | 
            
                                                        
            
                                    
            
            
                | 795 |  |  |       else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { | 
            
                                                        
            
                                    
            
            
                | 796 |  |  |         // We're in compatibility mode when the Trident version + 4 doesn't | 
            
                                                        
            
                                    
            
            
                | 797 |  |  |         // equal the document mode. | 
            
                                                        
            
                                    
            
            
                | 798 |  |  |         version = [version, doc.documentMode]; | 
            
                                                        
            
                                    
            
            
                | 799 |  |  |         if ((data = +data[1] + 4) != version[1]) { | 
            
                                                        
            
                                    
            
            
                | 800 |  |  |           description.push('IE ' + version[1] + ' mode'); | 
            
                                                        
            
                                    
            
            
                | 801 |  |  |           layout && (layout[1] = ''); | 
            
                                                        
            
                                    
            
            
                | 802 |  |  |           version[1] = data; | 
            
                                                        
            
                                    
            
            
                | 803 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 804 |  |  |         version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; | 
            
                                                        
            
                                    
            
            
                | 805 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 806 |  |  |       // Detect IE 11 masking as other browsers. | 
            
                                                        
            
                                    
            
            
                | 807 |  |  |       else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { | 
            
                                                        
            
                                    
            
            
                | 808 |  |  |         description.push('masking as ' + name + ' ' + version); | 
            
                                                        
            
                                    
            
            
                | 809 |  |  |         name = 'IE'; | 
            
                                                        
            
                                    
            
            
                | 810 |  |  |         version = '11.0'; | 
            
                                                        
            
                                    
            
            
                | 811 |  |  |         layout = ['Trident']; | 
            
                                                        
            
                                    
            
            
                | 812 |  |  |         os = 'Windows'; | 
            
                                                        
            
                                    
            
            
                | 813 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 814 |  |  |       os = os && format(os); | 
            
                                                        
            
                                    
            
            
                | 815 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 816 |  |  |     // Detect prerelease phases. | 
            
                                                        
            
                                    
            
            
                | 817 |  |  |     if (version && (data = | 
            
                                                        
            
                                    
            
            
                | 818 |  |  |           /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || | 
            
                                                        
            
                                    
            
            
                | 819 |  |  |           /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || | 
            
                                                        
            
                                    
            
            
                | 820 |  |  |           /\bMinefield\b/i.test(ua) && 'a' | 
            
                                                        
            
                                    
            
            
                | 821 |  |  |         )) { | 
            
                                                        
            
                                    
            
            
                | 822 |  |  |       prerelease = /b/i.test(data) ? 'beta' : 'alpha'; | 
            
                                                        
            
                                    
            
            
                | 823 |  |  |       version = version.replace(RegExp(data + '\\+?$'), '') + | 
            
                                                        
            
                                    
            
            
                | 824 |  |  |         (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); | 
            
                                                        
            
                                    
            
            
                | 825 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 826 |  |  |     // Detect Firefox Mobile. | 
            
                                                        
            
                                    
            
            
                | 827 |  |  |     if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { | 
            
                                                        
            
                                    
            
            
                | 828 |  |  |       name = 'Firefox Mobile'; | 
            
                                                        
            
                                    
            
            
                | 829 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 830 |  |  |     // Obscure Maxthon's unreliable version. | 
            
                                                        
            
                                    
            
            
                | 831 |  |  |     else if (name == 'Maxthon' && version) { | 
            
                                                        
            
                                    
            
            
                | 832 |  |  |       version = version.replace(/\.[\d.]+/, '.x'); | 
            
                                                        
            
                                    
            
            
                | 833 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 834 |  |  |     // Detect Xbox 360 and Xbox One. | 
            
                                                        
            
                                    
            
            
                | 835 |  |  |     else if (/\bXbox\b/i.test(product)) { | 
            
                                                        
            
                                    
            
            
                | 836 |  |  |       if (product == 'Xbox 360') { | 
            
                                                        
            
                                    
            
            
                | 837 |  |  |         os = null; | 
            
                                                        
            
                                    
            
            
                | 838 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 839 |  |  |       if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { | 
            
                                                        
            
                                    
            
            
                | 840 |  |  |         description.unshift('mobile mode'); | 
            
                                                        
            
                                    
            
            
                | 841 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 842 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 843 |  |  |     // Add mobile postfix. | 
            
                                                        
            
                                    
            
            
                | 844 |  |  |     else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && | 
            
                                                        
            
                                    
            
            
                | 845 |  |  |         (os == 'Windows CE' || /Mobi/i.test(ua))) { | 
            
                                                        
            
                                    
            
            
                | 846 |  |  |       name += ' Mobile'; | 
            
                                                        
            
                                    
            
            
                | 847 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 848 |  |  |     // Detect IE platform preview. | 
            
                                                        
            
                                    
            
            
                | 849 |  |  |     else if (name == 'IE' && useFeatures) { | 
            
                                                        
            
                                    
            
            
                | 850 |  |  |       try { | 
            
                                                        
            
                                    
            
            
                | 851 |  |  |         if (context.external === null) { | 
            
                                                        
            
                                    
            
            
                | 852 |  |  |           description.unshift('platform preview'); | 
            
                                                        
            
                                    
            
            
                | 853 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 854 |  |  |       } catch(e) { | 
            
                                                        
            
                                    
            
            
                | 855 |  |  |         description.unshift('embedded'); | 
            
                                                        
            
                                    
            
            
                | 856 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 857 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 858 |  |  |     // Detect BlackBerry OS version. | 
            
                                                        
            
                                    
            
            
                | 859 |  |  |     // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp | 
            
                                                        
            
                                    
            
            
                | 860 |  |  |     else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = | 
            
                                                        
            
                                    
            
            
                | 861 |  |  |           (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || | 
            
                                                        
            
                                    
            
            
                | 862 |  |  |           version | 
            
                                                        
            
                                    
            
            
                | 863 |  |  |         )) { | 
            
                                                        
            
                                    
            
            
                | 864 |  |  |       data = [data, /BB10/.test(ua)]; | 
            
                                                        
            
                                    
            
            
                | 865 |  |  |       os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 866 |  |  |       version = null; | 
            
                                                        
            
                                    
            
            
                | 867 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 868 |  |  |     // Detect Opera identifying/masking itself as another browser. | 
            
                                                        
            
                                    
            
            
                | 869 |  |  |     // http://www.opera.com/support/kb/view/843/ | 
            
                                                        
            
                                    
            
            
                | 870 |  |  |     else if (this != forOwn && product != 'Wii' && ( | 
            
                                                        
            
                                    
            
            
                | 871 |  |  |           (useFeatures && opera) || | 
            
                                                        
            
                                    
            
            
                | 872 |  |  |           (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || | 
            
                                                        
            
                                    
            
            
                | 873 |  |  |           (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || | 
            
                                                        
            
                                    
            
            
                | 874 |  |  |           (name == 'IE' && ( | 
            
                                                        
            
                                    
            
            
                | 875 |  |  |             (os && !/^Win/.test(os) && version > 5.5) || | 
            
                                                        
            
                                    
            
            
                | 876 |  |  |             /\bWindows XP\b/.test(os) && version > 8 || | 
            
                                                        
            
                                    
            
            
                | 877 |  |  |             version == 8 && !/\bTrident\b/.test(ua) | 
            
                                                        
            
                                    
            
            
                | 878 |  |  |           )) | 
            
                                                        
            
                                    
            
            
                | 879 |  |  |         ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { | 
            
                                                        
            
                                    
            
            
                | 880 |  |  |       // When "identifying", the UA contains both Opera and the other browser's name. | 
            
                                                        
            
                                    
            
            
                | 881 |  |  |       data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); | 
            
                                                        
            
                                    
            
            
                | 882 |  |  |       if (reOpera.test(name)) { | 
            
                                                        
            
                                    
            
            
                | 883 |  |  |         if (/\bIE\b/.test(data) && os == 'Mac OS') { | 
            
                                                        
            
                                    
            
            
                | 884 |  |  |           os = null; | 
            
                                                        
            
                                    
            
            
                | 885 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 886 |  |  |         data = 'identify' + data; | 
            
                                                        
            
                                    
            
            
                | 887 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 888 |  |  |       // When "masking", the UA contains only the other browser's name. | 
            
                                                        
            
                                    
            
            
                | 889 |  |  |       else { | 
            
                                                        
            
                                    
            
            
                | 890 |  |  |         data = 'mask' + data; | 
            
                                                        
            
                                    
            
            
                | 891 |  |  |         if (operaClass) { | 
            
                                                        
            
                                    
            
            
                | 892 |  |  |           name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); | 
            
                                                        
            
                                    
            
            
                | 893 |  |  |         } else { | 
            
                                                        
            
                                    
            
            
                | 894 |  |  |           name = 'Opera'; | 
            
                                                        
            
                                    
            
            
                | 895 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 896 |  |  |         if (/\bIE\b/.test(data)) { | 
            
                                                        
            
                                    
            
            
                | 897 |  |  |           os = null; | 
            
                                                        
            
                                    
            
            
                | 898 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 899 |  |  |         if (!useFeatures) { | 
            
                                                        
            
                                    
            
            
                | 900 |  |  |           version = null; | 
            
                                                        
            
                                    
            
            
                | 901 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 902 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 903 |  |  |       layout = ['Presto']; | 
            
                                                        
            
                                    
            
            
                | 904 |  |  |       description.push(data); | 
            
                                                        
            
                                    
            
            
                | 905 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 906 |  |  |     // Detect WebKit Nightly and approximate Chrome/Safari versions. | 
            
                                                        
            
                                    
            
            
                | 907 |  |  |     if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { | 
            
                                                        
            
                                    
            
            
                | 908 |  |  |       // Correct build number for numeric comparison. | 
            
                                                        
            
                                    
            
            
                | 909 |  |  |       // (e.g. "532.5" becomes "532.05") | 
            
                                                        
            
                                    
            
            
                | 910 |  |  |       data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; | 
            
                                                        
            
                                    
            
            
                | 911 |  |  |       // Nightly builds are postfixed with a "+". | 
            
                                                        
            
                                    
            
            
                | 912 |  |  |       if (name == 'Safari' && data[1].slice(-1) == '+') { | 
            
                                                        
            
                                    
            
            
                | 913 |  |  |         name = 'WebKit Nightly'; | 
            
                                                        
            
                                    
            
            
                | 914 |  |  |         prerelease = 'alpha'; | 
            
                                                        
            
                                    
            
            
                | 915 |  |  |         version = data[1].slice(0, -1); | 
            
                                                        
            
                                    
            
            
                | 916 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 917 |  |  |       // Clear incorrect browser versions. | 
            
                                                        
            
                                    
            
            
                | 918 |  |  |       else if (version == data[1] || | 
            
                                                        
            
                                    
            
            
                | 919 |  |  |           version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { | 
            
                                                        
            
                                    
            
            
                | 920 |  |  |         version = null; | 
            
                                                        
            
                                    
            
            
                | 921 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 922 |  |  |       // Use the full Chrome version when available. | 
            
                                                        
            
                                    
            
            
                | 923 |  |  |       data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; | 
            
                                                        
            
                                    
            
            
                | 924 |  |  |       // Detect Blink layout engine. | 
            
                                                        
            
                                    
            
            
                | 925 |  |  |       if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { | 
            
                                                        
            
                                    
            
            
                | 926 |  |  |         layout = ['Blink']; | 
            
                                                        
            
                                    
            
            
                | 927 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 928 |  |  |       // Detect JavaScriptCore. | 
            
                                                        
            
                                    
            
            
                | 929 |  |  |       // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi | 
            
                                                        
            
                                    
            
            
                | 930 |  |  |       if (!useFeatures || (!likeChrome && !data[1])) { | 
            
                                                        
            
                                    
            
            
                | 931 |  |  |         layout && (layout[1] = 'like Safari'); | 
            
                                                        
            
                                    
            
            
                | 932 |  |  |         data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 933 |  |  |       } else { | 
            
                                                        
            
                                    
            
            
                | 934 |  |  |         layout && (layout[1] = 'like Chrome'); | 
            
                                                        
            
                                    
            
            
                | 935 |  |  |         data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                        
            
                                    
            
            
                | 936 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 937 |  |  |       // Add the postfix of ".x" or "+" for approximate versions. | 
            
                                                        
            
                                    
            
            
                | 938 |  |  |       layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); | 
            
                                                        
            
                                    
            
            
                | 939 |  |  |       // Obscure version for some Safari 1-2 releases. | 
            
                                                        
            
                                    
            
            
                | 940 |  |  |       if (name == 'Safari' && (!version || parseInt(version) > 45)) { | 
            
                                                        
            
                                    
            
            
                | 941 |  |  |         version = data; | 
            
                                                        
            
                                    
            
            
                | 942 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 943 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 944 |  |  |     // Detect Opera desktop modes. | 
            
                                                        
            
                                    
            
            
                | 945 |  |  |     if (name == 'Opera' &&  (data = /\bzbov|zvav$/.exec(os))) { | 
            
                                                        
            
                                    
            
            
                | 946 |  |  |       name += ' '; | 
            
                                                        
            
                                    
            
            
                | 947 |  |  |       description.unshift('desktop mode'); | 
            
                                                        
            
                                    
            
            
                | 948 |  |  |       if (data == 'zvav') { | 
            
                                                        
            
                                    
            
            
                | 949 |  |  |         name += 'Mini'; | 
            
                                                        
            
                                    
            
            
                | 950 |  |  |         version = null; | 
            
                                                        
            
                                    
            
            
                | 951 |  |  |       } else { | 
            
                                                        
            
                                    
            
            
                | 952 |  |  |         name += 'Mobile'; | 
            
                                                        
            
                                    
            
            
                | 953 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 954 |  |  |       os = os.replace(RegExp(' *' + data + '$'), ''); | 
            
                                                        
            
                                    
            
            
                | 955 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 956 |  |  |     // Detect Chrome desktop mode. | 
            
                                                        
            
                                    
            
            
                | 957 |  |  |     else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { | 
            
                                                        
            
                                    
            
            
                | 958 |  |  |       description.unshift('desktop mode'); | 
            
                                                        
            
                                    
            
            
                | 959 |  |  |       name = 'Chrome Mobile'; | 
            
                                                        
            
                                    
            
            
                | 960 |  |  |       version = null; | 
            
                                                        
            
                                    
            
            
                | 961 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 962 |  |  |       if (/\bOS X\b/.test(os)) { | 
            
                                                        
            
                                    
            
            
                | 963 |  |  |         manufacturer = 'Apple'; | 
            
                                                        
            
                                    
            
            
                | 964 |  |  |         os = 'iOS 4.3+'; | 
            
                                                        
            
                                    
            
            
                | 965 |  |  |       } else { | 
            
                                                        
            
                                    
            
            
                | 966 |  |  |         os = null; | 
            
                                                        
            
                                    
            
            
                | 967 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 968 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 969 |  |  |     // Strip incorrect OS versions. | 
            
                                                        
            
                                    
            
            
                | 970 |  |  |     if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && | 
            
                                                        
            
                                    
            
            
                | 971 |  |  |         ua.indexOf('/' + data + '-') > -1) { | 
            
                                                        
            
                                    
            
            
                | 972 |  |  |       os = trim(os.replace(data, '')); | 
            
                                                        
            
                                    
            
            
                | 973 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 974 |  |  |     // Add layout engine. | 
            
                                                        
            
                                    
            
            
                | 975 |  |  |     if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( | 
            
                                                        
            
                                    
            
            
                | 976 |  |  |         /Browser|Lunascape|Maxthon/.test(name) || | 
            
                                                        
            
                                    
            
            
                | 977 |  |  |         name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || | 
            
                                                        
            
                                    
            
            
                | 978 |  |  |         /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { | 
            
                                                        
            
                                    
            
            
                | 979 |  |  |       // Don't add layout details to description if they are falsey. | 
            
                                                        
            
                                    
            
            
                | 980 |  |  |       (data = layout[layout.length - 1]) && description.push(data); | 
            
                                                        
            
                                    
            
            
                | 981 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 982 |  |  |     // Combine contextual information. | 
            
                                                        
            
                                    
            
            
                | 983 |  |  |     if (description.length) { | 
            
                                                        
            
                                    
            
            
                | 984 |  |  |       description = ['(' + description.join('; ') + ')']; | 
            
                                                        
            
                                    
            
            
                | 985 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 986 |  |  |     // Append manufacturer to description. | 
            
                                                        
            
                                    
            
            
                | 987 |  |  |     if (manufacturer && product && product.indexOf(manufacturer) < 0) { | 
            
                                                        
            
                                    
            
            
                | 988 |  |  |       description.push('on ' + manufacturer); | 
            
                                                        
            
                                    
            
            
                | 989 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 990 |  |  |     // Append product to description. | 
            
                                                        
            
                                    
            
            
                | 991 |  |  |     if (product) { | 
            
                                                        
            
                                    
            
            
                | 992 |  |  |       description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); | 
            
                                                        
            
                                    
            
            
                | 993 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 994 |  |  |     // Parse the OS into an object. | 
            
                                                        
            
                                    
            
            
                | 995 |  |  |     if (os) { | 
            
                                                        
            
                                    
            
            
                | 996 |  |  |       data = / ([\d.+]+)$/.exec(os); | 
            
                                                        
            
                                    
            
            
                | 997 |  |  |       isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; | 
            
                                                        
            
                                    
            
            
                | 998 |  |  |       os = { | 
            
                                                        
            
                                    
            
            
                | 999 |  |  |         'architecture': 32, | 
            
                                                        
            
                                    
            
            
                | 1000 |  |  |         'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, | 
            
                                                        
            
                                    
            
            
                | 1001 |  |  |         'version': data ? data[1] : null, | 
            
                                                        
            
                                    
            
            
                | 1002 |  |  |         'toString': function() { | 
            
                                                        
            
                                    
            
            
                | 1003 |  |  |           var version = this.version; | 
            
                                                        
            
                                    
            
            
                | 1004 |  |  |           return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); | 
            
                                                        
            
                                    
            
            
                | 1005 |  |  |         } | 
            
                                                        
            
                                    
            
            
                | 1006 |  |  |       }; | 
            
                                                        
            
                                    
            
            
                | 1007 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1008 |  |  |     // Add browser/OS architecture. | 
            
                                                        
            
                                    
            
            
                | 1009 |  |  |     if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { | 
            
                                                        
            
                                    
            
            
                | 1010 |  |  |       if (os) { | 
            
                                                        
            
                                    
            
            
                | 1011 |  |  |         os.architecture = 64; | 
            
                                                        
            
                                    
            
            
                | 1012 |  |  |         os.family = os.family.replace(RegExp(' *' + data), ''); | 
            
                                                        
            
                                    
            
            
                | 1013 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 1014 |  |  |       if ( | 
            
                                                        
            
                                    
            
            
                | 1015 |  |  |           name && (/\bWOW64\b/i.test(ua) || | 
            
                                                        
            
                                    
            
            
                | 1016 |  |  |           (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) | 
            
                                                        
            
                                    
            
            
                | 1017 |  |  |       ) { | 
            
                                                        
            
                                    
            
            
                | 1018 |  |  |         description.unshift('32-bit'); | 
            
                                                        
            
                                    
            
            
                | 1019 |  |  |       } | 
            
                                                        
            
                                    
            
            
                | 1020 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1021 |  |  |     // Chrome 39 and above on OS X is always 64-bit. | 
            
                                                        
            
                                    
            
            
                | 1022 |  |  |     else if ( | 
            
                                                        
            
                                    
            
            
                | 1023 |  |  |         os && /^OS X/.test(os.family) && | 
            
                                                        
            
                                    
            
            
                | 1024 |  |  |         name == 'Chrome' && parseFloat(version) >= 39 | 
            
                                                        
            
                                    
            
            
                | 1025 |  |  |     ) { | 
            
                                                        
            
                                    
            
            
                | 1026 |  |  |       os.architecture = 64; | 
            
                                                        
            
                                    
            
            
                | 1027 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1028 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1029 |  |  |     ua || (ua = null); | 
            
                                                        
            
                                    
            
            
                | 1030 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1031 |  |  |     /*------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 1032 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1033 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1034 |  |  |      * The platform object. | 
            
                                                        
            
                                    
            
            
                | 1035 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1036 |  |  |      * @name platform | 
            
                                                        
            
                                    
            
            
                | 1037 |  |  |      * @type Object | 
            
                                                        
            
                                    
            
            
                | 1038 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1039 |  |  |     var platform = {}; | 
            
                                                        
            
                                    
            
            
                | 1040 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1041 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1042 |  |  |      * The platform description. | 
            
                                                        
            
                                    
            
            
                | 1043 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1044 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1045 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1046 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1047 |  |  |     platform.description = ua; | 
            
                                                        
            
                                    
            
            
                | 1048 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1049 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1050 |  |  |      * The name of the browser's layout engine. | 
            
                                                        
            
                                    
            
            
                | 1051 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1052 |  |  |      * The list of common layout engines include: | 
            
                                                        
            
                                    
            
            
                | 1053 |  |  |      * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" | 
            
                                                        
            
                                    
            
            
                | 1054 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1055 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1056 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1057 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1058 |  |  |     platform.layout = layout && layout[0]; | 
            
                                                        
            
                                    
            
            
                | 1059 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1060 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1061 |  |  |      * The name of the product's manufacturer. | 
            
                                                        
            
                                    
            
            
                | 1062 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1063 |  |  |      * The list of manufacturers include: | 
            
                                                        
            
                                    
            
            
                | 1064 |  |  |      * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", | 
            
                                                        
            
                                    
            
            
                | 1065 |  |  |      * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", | 
            
                                                        
            
                                    
            
            
                | 1066 |  |  |      * "Nokia", "Samsung" and "Sony" | 
            
                                                        
            
                                    
            
            
                | 1067 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1068 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1069 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1070 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1071 |  |  |     platform.manufacturer = manufacturer; | 
            
                                                        
            
                                    
            
            
                | 1072 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1073 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1074 |  |  |      * The name of the browser/environment. | 
            
                                                        
            
                                    
            
            
                | 1075 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1076 |  |  |      * The list of common browser names include: | 
            
                                                        
            
                                    
            
            
                | 1077 |  |  |      * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", | 
            
                                                        
            
                                    
            
            
                | 1078 |  |  |      * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", | 
            
                                                        
            
                                    
            
            
                | 1079 |  |  |      * "Opera Mini" and "Opera" | 
            
                                                        
            
                                    
            
            
                | 1080 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1081 |  |  |      * Mobile versions of some browsers have "Mobile" appended to their name: | 
            
                                                        
            
                                    
            
            
                | 1082 |  |  |      * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" | 
            
                                                        
            
                                    
            
            
                | 1083 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1084 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1085 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1086 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1087 |  |  |     platform.name = name; | 
            
                                                        
            
                                    
            
            
                | 1088 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1089 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1090 |  |  |      * The alpha/beta release indicator. | 
            
                                                        
            
                                    
            
            
                | 1091 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1092 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1093 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1094 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1095 |  |  |     platform.prerelease = prerelease; | 
            
                                                        
            
                                    
            
            
                | 1096 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1097 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1098 |  |  |      * The name of the product hosting the browser. | 
            
                                                        
            
                                    
            
            
                | 1099 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1100 |  |  |      * The list of common products include: | 
            
                                                        
            
                                    
            
            
                | 1101 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1102 |  |  |      * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", | 
            
                                                        
            
                                    
            
            
                | 1103 |  |  |      * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" | 
            
                                                        
            
                                    
            
            
                | 1104 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1105 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1106 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1107 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1108 |  |  |     platform.product = product; | 
            
                                                        
            
                                    
            
            
                | 1109 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1110 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1111 |  |  |      * The browser's user agent string. | 
            
                                                        
            
                                    
            
            
                | 1112 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1113 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1114 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1115 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1116 |  |  |     platform.ua = ua; | 
            
                                                        
            
                                    
            
            
                | 1117 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1118 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1119 |  |  |      * The browser/environment version. | 
            
                                                        
            
                                    
            
            
                | 1120 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1121 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1122 |  |  |      * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1123 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1124 |  |  |     platform.version = name && version; | 
            
                                                        
            
                                    
            
            
                | 1125 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1126 |  |  |     /** | 
            
                                                        
            
                                    
            
            
                | 1127 |  |  |      * The name of the operating system. | 
            
                                                        
            
                                    
            
            
                | 1128 |  |  |      * | 
            
                                                        
            
                                    
            
            
                | 1129 |  |  |      * @memberOf platform | 
            
                                                        
            
                                    
            
            
                | 1130 |  |  |      * @type Object | 
            
                                                        
            
                                    
            
            
                | 1131 |  |  |      */ | 
            
                                                        
            
                                    
            
            
                | 1132 |  |  |     platform.os = os || { | 
            
                                                        
            
                                    
            
            
                | 1133 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1134 |  |  |       /** | 
            
                                                        
            
                                    
            
            
                | 1135 |  |  |        * The CPU architecture the OS is built for. | 
            
                                                        
            
                                    
            
            
                | 1136 |  |  |        * | 
            
                                                        
            
                                    
            
            
                | 1137 |  |  |        * @memberOf platform.os | 
            
                                                        
            
                                    
            
            
                | 1138 |  |  |        * @type number|null | 
            
                                                        
            
                                    
            
            
                | 1139 |  |  |        */ | 
            
                                                        
            
                                    
            
            
                | 1140 |  |  |       'architecture': null, | 
            
                                                        
            
                                    
            
            
                | 1141 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1142 |  |  |       /** | 
            
                                                        
            
                                    
            
            
                | 1143 |  |  |        * The family of the OS. | 
            
                                                        
            
                                    
            
            
                | 1144 |  |  |        * | 
            
                                                        
            
                                    
            
            
                | 1145 |  |  |        * Common values include: | 
            
                                                        
            
                                    
            
            
                | 1146 |  |  |        * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", | 
            
                                                        
            
                                    
            
            
                | 1147 |  |  |        * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", | 
            
                                                        
            
                                    
            
            
                | 1148 |  |  |        * "Android", "iOS" and "Windows Phone" | 
            
                                                        
            
                                    
            
            
                | 1149 |  |  |        * | 
            
                                                        
            
                                    
            
            
                | 1150 |  |  |        * @memberOf platform.os | 
            
                                                        
            
                                    
            
            
                | 1151 |  |  |        * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1152 |  |  |        */ | 
            
                                                        
            
                                    
            
            
                | 1153 |  |  |       'family': null, | 
            
                                                        
            
                                    
            
            
                | 1154 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1155 |  |  |       /** | 
            
                                                        
            
                                    
            
            
                | 1156 |  |  |        * The version of the OS. | 
            
                                                        
            
                                    
            
            
                | 1157 |  |  |        * | 
            
                                                        
            
                                    
            
            
                | 1158 |  |  |        * @memberOf platform.os | 
            
                                                        
            
                                    
            
            
                | 1159 |  |  |        * @type string|null | 
            
                                                        
            
                                    
            
            
                | 1160 |  |  |        */ | 
            
                                                        
            
                                    
            
            
                | 1161 |  |  |       'version': null, | 
            
                                                        
            
                                    
            
            
                | 1162 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1163 |  |  |       /** | 
            
                                                        
            
                                    
            
            
                | 1164 |  |  |        * Returns the OS string. | 
            
                                                        
            
                                    
            
            
                | 1165 |  |  |        * | 
            
                                                        
            
                                    
            
            
                | 1166 |  |  |        * @memberOf platform.os | 
            
                                                        
            
                                    
            
            
                | 1167 |  |  |        * @returns {string} The OS string. | 
            
                                                        
            
                                    
            
            
                | 1168 |  |  |        */ | 
            
                                                        
            
                                    
            
            
                | 1169 |  |  |       'toString': function() { return 'null'; } | 
            
                                                        
            
                                    
            
            
                | 1170 |  |  |     }; | 
            
                                                        
            
                                    
            
            
                | 1171 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1172 |  |  |     platform.parse = parse; | 
            
                                                        
            
                                    
            
            
                | 1173 |  |  |     platform.toString = toStringPlatform; | 
            
                                                        
            
                                    
            
            
                | 1174 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1175 |  |  |     if (platform.version) { | 
            
                                                        
            
                                    
            
            
                | 1176 |  |  |       description.unshift(version); | 
            
                                                        
            
                                    
            
            
                | 1177 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1178 |  |  |     if (platform.name) { | 
            
                                                        
            
                                    
            
            
                | 1179 |  |  |       description.unshift(name); | 
            
                                                        
            
                                    
            
            
                | 1180 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1181 |  |  |     if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { | 
            
                                                        
            
                                    
            
            
                | 1182 |  |  |       description.push(product ? '(' + os + ')' : 'on ' + os); | 
            
                                                        
            
                                    
            
            
                | 1183 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1184 |  |  |     if (description.length) { | 
            
                                                        
            
                                    
            
            
                | 1185 |  |  |       platform.description = description.join(' '); | 
            
                                                        
            
                                    
            
            
                | 1186 |  |  |     } | 
            
                                                        
            
                                    
            
            
                | 1187 |  |  |     return platform; | 
            
                                                        
            
                                    
            
            
                | 1188 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 1189 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1190 |  |  |   /*--------------------------------------------------------------------------*/ | 
            
                                                        
            
                                    
            
            
                | 1191 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1192 |  |  |   // Export platform. | 
            
                                                        
            
                                    
            
            
                | 1193 |  |  |   var platform = parse(); | 
            
                                                        
            
                                    
            
            
                | 1194 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1195 |  |  |   // Some AMD build optimizers, like r.js, check for condition patterns like the following: | 
            
                                                        
            
                                    
            
            
                | 1196 |  |  |   if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { | 
            
                                                        
            
                                    
            
            
                | 1197 |  |  |     // Expose platform on the global object to prevent errors when platform is | 
            
                                                        
            
                                    
            
            
                | 1198 |  |  |     // loaded by a script tag in the presence of an AMD loader. | 
            
                                                        
            
                                    
            
            
                | 1199 |  |  |     // See http://requirejs.org/docs/errors.html#mismatch for more details. | 
            
                                                        
            
                                    
            
            
                | 1200 |  |  |     root.platform = platform; | 
            
                                                        
            
                                    
            
            
                | 1201 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 1202 |  |  |     // Define as an anonymous module so platform can be aliased through path mapping. | 
            
                                                        
            
                                    
            
            
                | 1203 |  |  |     define(function() { | 
            
                                                        
            
                                    
            
            
                | 1204 |  |  |       return platform; | 
            
                                                        
            
                                    
            
            
                | 1205 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 1206 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 1207 |  |  |   // Check for `exports` after `define` in case a build optimizer adds an `exports` object. | 
            
                                                        
            
                                    
            
            
                | 1208 |  |  |   else if (freeExports && freeModule) { | 
            
                                                        
            
                                    
            
            
                | 1209 |  |  |     // Export for CommonJS support. | 
            
                                                        
            
                                    
            
            
                | 1210 |  |  |     forOwn(platform, function(value, key) { | 
            
                                                        
            
                                    
            
            
                | 1211 |  |  |       freeExports[key] = value; | 
            
                                                        
            
                                    
            
            
                | 1212 |  |  |     }); | 
            
                                                        
            
                                    
            
            
                | 1213 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 1214 |  |  |   else { | 
            
                                                        
            
                                    
            
            
                | 1215 |  |  |     // Export to the global object. | 
            
                                                        
            
                                    
            
            
                | 1216 |  |  |     root.platform = platform; | 
            
                                                        
            
                                    
            
            
                | 1217 |  |  |   } | 
            
                                                        
            
                                    
            
            
                | 1218 |  |  | }.call(this)); | 
            
                                                        
            
                                    
            
            
                | 1219 |  |  |  | 
            
                        
When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically: