j1-template 2021.1.10 → 2021.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/assets/error_pages/HTTP204.html +3 -0
  3. data/assets/error_pages/HTTP400.html +3 -0
  4. data/assets/error_pages/HTTP401.html +3 -0
  5. data/assets/error_pages/HTTP403.html +3 -0
  6. data/assets/error_pages/HTTP404.html +3 -0
  7. data/assets/error_pages/HTTP500.html +3 -0
  8. data/assets/error_pages/HTTP501.html +3 -0
  9. data/assets/error_pages/HTTP502.html +3 -0
  10. data/assets/error_pages/HTTP503.html +3 -0
  11. data/assets/themes/j1/adapter/js/cookieConsent.js +18 -8
  12. data/assets/themes/j1/adapter/js/j1.js +93 -39
  13. data/assets/themes/j1/adapter/js/navigator.js +5 -2
  14. data/assets/themes/j1/adapter/js/themer.js +137 -92
  15. data/assets/themes/j1/core/js/template.js +24 -4
  16. data/assets/themes/j1/core/js/template.js.map +1 -1
  17. data/assets/themes/j1/core/js/template.min.js +24 -4
  18. data/assets/themes/j1/core/js/template.min.js.map +1 -1
  19. data/lib/j1/version.rb +1 -1
  20. data/lib/starter_web/Gemfile +1 -1
  21. data/lib/starter_web/_config.yml +1 -1
  22. data/lib/starter_web/_data/resources.yml +0 -4
  23. data/lib/starter_web/_includes/attributes.asciidoc +1 -1
  24. data/lib/starter_web/_plugins/lunr_index.rb +1 -1
  25. data/lib/starter_web/package.json +1 -1
  26. data/lib/starter_web/utilsrv/_defaults/package.json +1 -1
  27. data/lib/starter_web/utilsrv/package.json +1 -1
  28. metadata +2 -7
  29. data/assets/themes/j1/adapter/js/themer.1.js +0 -326
  30. data/assets/themes/j1/modules/util/js/js.cookie.js +0 -163
  31. data/assets/themes/j1/modules/util/js/lite-url.js +0 -203
  32. data/assets/themes/j1/modules/util/js/lite-url.min.js +0 -7
  33. data/assets/themes/j1/modules/util/js/platform.js +0 -1260
@@ -1,203 +0,0 @@
1
- /**
2
- * lite-url - Small, JS lib that uses regex for parsing a URL into it's component parts.
3
- * @version v1.0.5
4
- * @link https://github.com/sadams/lite-url
5
- * @license BSD-3-Clause
6
- */
7
- (function(){
8
- 'use strict';
9
-
10
- /**
11
- * Establish the root object, `window` in the browser, or `exports` on the server.
12
- */
13
- var root = this;
14
-
15
- /**
16
- * In memory cache for so we don't parse the same url twice
17
- * @type {{}}
18
- */
19
- var memo = {};
20
-
21
- /**
22
- * splits a string on the first occurrence of 'splitter' and calls back with the two entries.
23
- * @param {string} str
24
- * @param {string} splitter
25
- * @param {function} callback
26
- * @return *
27
- */
28
- function splitOnFirst(str, splitter, callback) {
29
- var parts = str.split(splitter);
30
- var first = parts.shift();
31
- return callback(first, parts.join(splitter));
32
- }
33
-
34
- /**
35
- *
36
- * @param {string} str - the url to parse
37
- * @returns {{
38
- * href: string // http://user:pass@host.com:81/directory/file.ext?query=1#anchor
39
- * protocol: string, // http:
40
- * origin: string, // http://user:pass@host.com:81
41
- * host: string, // host.com:81
42
- * hostname: string, // host.com
43
- * port: string, // 81
44
- * pathname: string, // /directory/file.ext
45
- * search: string, // ?query=1
46
- * hash: string, // #anchor
47
- * username: string, // user
48
- * password: string, // pass
49
- * username: string, // user
50
- * }}
51
- */
52
- function uriParser(str) {
53
- var uri = {
54
- hash:'',
55
- host:'',
56
- hostname:'',
57
- origin:'',
58
- pathname:'',
59
- protocol:'',
60
- search:'',
61
- password:'',
62
- username:'',
63
- port:''
64
- };
65
- // http://user:pass@host.com:81/directory/file.ext?query=1#anchor
66
- splitOnFirst(str, '#', function(nonHash, hash) {
67
- // http://user:pass@host.com:81/directory/file.ext?query=1, anchor
68
- if (hash) {
69
- // #anchor
70
- uri.hash = hash ? '#' + hash : '';
71
- }
72
- // http://user:pass@host.com:81/directory/file.ext?query=1
73
- splitOnFirst(nonHash, '?', function(nonSearch, search) {
74
- // http://user:pass@host.com:81/directory/file.ext, query=1
75
- if (search) {
76
- // ?query=1
77
- uri.search = '?' + search;
78
- }
79
- if (!nonSearch) {
80
- //means we were given a query string only
81
- return;
82
- }
83
- // http://user:pass@host.com:81/directory/file.ext
84
- splitOnFirst(nonSearch, '//', function(protocol, hostUserPortPath) {
85
- // http:, user:pass@host.com:81/directory/file.ext
86
- uri.protocol = protocol;
87
- splitOnFirst(hostUserPortPath, '/', function(hostUserPort, path) {
88
- // user:pass@host.com:81, directory/file.ext
89
- uri.pathname = '/' + (path || ''); // /directory/file.ext
90
- if (uri.protocol || hostUserPort) {
91
- // http://user:pass@host.com:81
92
- uri.origin = uri.protocol + '//' + hostUserPort;
93
- }
94
- // user:pass@host.com:81
95
- splitOnFirst(hostUserPort, '@', function(auth, hostPort){
96
- // user:pass, host.com:81
97
- if (!hostPort) {
98
- hostPort = auth;
99
- } else {
100
- // user:pass
101
- var userPass = auth.split(':');
102
- uri.username = userPass[0];// user
103
- uri.password = userPass[1];// pass
104
- }
105
- // host.com:81
106
- uri.host = hostPort;
107
- splitOnFirst(hostPort, ':', function(hostName, port){
108
- // host.com, 81
109
- uri.hostname = hostName; // host.com
110
- if (port) {
111
- uri.port = port; // 81
112
- }
113
- });
114
- });
115
- });
116
-
117
- });
118
- });
119
- });
120
-
121
- uri.href = uri.origin + uri.pathname + uri.search + uri.hash;
122
-
123
- return uri;
124
- }
125
-
126
- /**
127
- * @param {string} uri
128
- * @returns {{}}
129
- */
130
- function queryParser(uri) {
131
- var params = {};
132
- var search = uri.search;
133
- if (search) {
134
- search = search.replace(new RegExp('\\?'), '');
135
- var pairs = search.split('&');
136
- for (var i in pairs) {
137
- if (pairs.hasOwnProperty(i) && pairs[i]) {
138
- var pair = pairs[i].split('=');
139
- params[pair[0]] = pair[1];
140
- }
141
- }
142
- }
143
- return params;
144
- }
145
-
146
- /**
147
- * Uri parsing method.
148
- *
149
- * @param {string} str
150
- * @returns {{
151
- * href:string,
152
- * origin:string,
153
- * protocol:string,
154
- * username:string,
155
- * password:string,
156
- * host:string,
157
- * hostname:string,
158
- * port:string,
159
- * path:string,
160
- * search:string,
161
- * hash:string,
162
- * params:{}
163
- * }}
164
- */
165
- function liteURL(str) {
166
- // We first check if we have parsed this URL before, to avoid running the
167
- // monster regex over and over (which is expensive!)
168
- var uri = memo[str];
169
-
170
- if (typeof uri !== 'undefined') {
171
- return uri;
172
- }
173
-
174
- //parsed url
175
- uri = uriParser(str);
176
-
177
- uri.params = queryParser(uri);
178
-
179
- // Stored parsed values
180
- memo[str] = uri;
181
-
182
- return uri;
183
- }
184
-
185
- liteURL.changeQueryParser = function(parser) {
186
- queryParser = parser;
187
- };
188
-
189
- //moduleType support
190
- if (typeof exports !== 'undefined') {
191
- //supports node
192
- if (typeof module !== 'undefined' && module.exports) {
193
- exports = module.exports = liteURL;
194
- }
195
- exports.liteURL = liteURL;
196
- } else {
197
- //supports globals
198
- root.liteURL = liteURL;
199
- }
200
-
201
- //supports requirejs/amd
202
- return liteURL;
203
- }).call(this);
@@ -1,7 +0,0 @@
1
- /**
2
- * lite-url - Small, JS lib that uses regex for parsing a URL into it's component parts.
3
- * @version v1.0.5
4
- * @link https://github.com/sadams/lite-url
5
- * @license BSD-3-Clause
6
- */
7
- (function(){"use strict";function r(r,n,t){var e=r.split(n),o=e.shift();return t(o,e.join(n))}function n(n){var t={hash:"",host:"",hostname:"",origin:"",pathname:"",protocol:"",search:"",password:"",username:"",port:""};return r(n,"#",function(n,e){e&&(t.hash=e?"#"+e:""),r(n,"?",function(n,e){e&&(t.search="?"+e),n&&r(n,"//",function(n,e){t.protocol=n,r(e,"/",function(n,e){t.pathname="/"+(e||""),(t.protocol||n)&&(t.origin=t.protocol+"//"+n),r(n,"@",function(n,e){if(e){var o=n.split(":");t.username=o[0],t.password=o[1]}else e=n;t.host=e,r(e,":",function(r,n){t.hostname=r,n&&(t.port=n)})})})})})}),t.href=t.origin+t.pathname+t.search+t.hash,t}function t(r){var n={},t=r.search;if(t){t=t.replace(new RegExp("\\?"),"");var e=t.split("&");for(var o in e)if(e.hasOwnProperty(o)&&e[o]){var i=e[o].split("=");n[i[0]]=i[1]}}return n}function e(r){var e=i[r];return"undefined"!=typeof e?e:(e=n(r),e.params=t(e),i[r]=e,e)}var o=this,i={};return e.changeQueryParser=function(r){t=r},"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=e),exports.liteURL=e):o.liteURL=e,e}).call(this);
@@ -1,1260 +0,0 @@
1
- /*!
2
- * Platform.js v1.3.6
3
- * Copyright 2014-2020 Benjamin Tan
4
- * Copyright 2011-2013 John-David Dalton
5
- * Available under MIT license
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|Edg|EdgA|EdgiOS)' },
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
- 'Vivaldi',
389
- 'Waterfox',
390
- 'WebPositive',
391
- { 'label': 'Yandex Browser', 'pattern': 'YaBrowser' },
392
- { 'label': 'UC Browser', 'pattern': 'UCBrowser' },
393
- 'Opera Mini',
394
- { 'label': 'Opera Mini', 'pattern': 'OPiOS' },
395
- 'Opera',
396
- { 'label': 'Opera', 'pattern': 'OPR' },
397
- 'Chromium',
398
- 'Chrome',
399
- { 'label': 'Chrome', 'pattern': '(?:HeadlessChrome)' },
400
- { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' },
401
- { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' },
402
- { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' },
403
- { 'label': 'IE', 'pattern': 'IEMobile' },
404
- { 'label': 'IE', 'pattern': 'MSIE' },
405
- 'Safari'
406
- ]);
407
-
408
- /* Detectable products (order is important). */
409
- var product = getProduct([
410
- { 'label': 'BlackBerry', 'pattern': 'BB10' },
411
- 'BlackBerry',
412
- { 'label': 'Galaxy S', 'pattern': 'GT-I9000' },
413
- { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' },
414
- { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' },
415
- { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' },
416
- { 'label': 'Galaxy S5', 'pattern': 'SM-G900' },
417
- { 'label': 'Galaxy S6', 'pattern': 'SM-G920' },
418
- { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' },
419
- { 'label': 'Galaxy S7', 'pattern': 'SM-G930' },
420
- { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' },
421
- 'Google TV',
422
- 'Lumia',
423
- 'iPad',
424
- 'iPod',
425
- 'iPhone',
426
- 'Kindle',
427
- { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' },
428
- 'Nexus',
429
- 'Nook',
430
- 'PlayBook',
431
- 'PlayStation Vita',
432
- 'PlayStation',
433
- 'TouchPad',
434
- 'Transformer',
435
- { 'label': 'Wii U', 'pattern': 'WiiU' },
436
- 'Wii',
437
- 'Xbox One',
438
- { 'label': 'Xbox 360', 'pattern': 'Xbox' },
439
- 'Xoom'
440
- ]);
441
-
442
- /* Detectable manufacturers. */
443
- var manufacturer = getManufacturer({
444
- 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 },
445
- 'Alcatel': {},
446
- 'Archos': {},
447
- 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 },
448
- 'Asus': { 'Transformer': 1 },
449
- 'Barnes & Noble': { 'Nook': 1 },
450
- 'BlackBerry': { 'PlayBook': 1 },
451
- 'Google': { 'Google TV': 1, 'Nexus': 1 },
452
- 'HP': { 'TouchPad': 1 },
453
- 'HTC': {},
454
- 'Huawei': {},
455
- 'Lenovo': {},
456
- 'LG': {},
457
- 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 },
458
- 'Motorola': { 'Xoom': 1 },
459
- 'Nintendo': { 'Wii U': 1, 'Wii': 1 },
460
- 'Nokia': { 'Lumia': 1 },
461
- 'Oppo': {},
462
- 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 },
463
- 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 },
464
- 'Xiaomi': { 'Mi': 1, 'Redmi': 1 }
465
- });
466
-
467
- /* Detectable operating systems (order is important). */
468
- var os = getOS([
469
- 'Windows Phone',
470
- 'KaiOS',
471
- 'Android',
472
- 'CentOS',
473
- { 'label': 'Chrome OS', 'pattern': 'CrOS' },
474
- 'Debian',
475
- { 'label': 'DragonFly BSD', 'pattern': 'DragonFly' },
476
- 'Fedora',
477
- 'FreeBSD',
478
- 'Gentoo',
479
- 'Haiku',
480
- 'Kubuntu',
481
- 'Linux Mint',
482
- 'OpenBSD',
483
- 'Red Hat',
484
- 'SuSE',
485
- 'Ubuntu',
486
- 'Xubuntu',
487
- 'Cygwin',
488
- 'Symbian OS',
489
- 'hpwOS',
490
- 'webOS ',
491
- 'webOS',
492
- 'Tablet OS',
493
- 'Tizen',
494
- 'Linux',
495
- 'Mac OS X',
496
- 'Macintosh',
497
- 'Mac',
498
- 'Windows 98;',
499
- 'Windows '
500
- ]);
501
-
502
- /*------------------------------------------------------------------------*/
503
-
504
- /**
505
- * Picks the layout engine from an array of guesses.
506
- *
507
- * @private
508
- * @param {Array} guesses An array of guesses.
509
- * @returns {null|string} The detected layout engine.
510
- */
511
- function getLayout(guesses) {
512
- return reduce(guesses, function(result, guess) {
513
- return result || RegExp('\\b' + (
514
- guess.pattern || qualify(guess)
515
- ) + '\\b', 'i').exec(ua) && (guess.label || guess);
516
- });
517
- }
518
-
519
- /**
520
- * Picks the manufacturer from an array of guesses.
521
- *
522
- * @private
523
- * @param {Array} guesses An object of guesses.
524
- * @returns {null|string} The detected manufacturer.
525
- */
526
- function getManufacturer(guesses) {
527
- return reduce(guesses, function(result, value, key) {
528
- // Lookup the manufacturer by product or scan the UA for the manufacturer.
529
- return result || (
530
- value[product] ||
531
- value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] ||
532
- RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua)
533
- ) && key;
534
- });
535
- }
536
-
537
- /**
538
- * Picks the browser name from an array of guesses.
539
- *
540
- * @private
541
- * @param {Array} guesses An array of guesses.
542
- * @returns {null|string} The detected browser name.
543
- */
544
- function getName(guesses) {
545
- return reduce(guesses, function(result, guess) {
546
- return result || RegExp('\\b' + (
547
- guess.pattern || qualify(guess)
548
- ) + '\\b', 'i').exec(ua) && (guess.label || guess);
549
- });
550
- }
551
-
552
- /**
553
- * Picks the OS name from an array of guesses.
554
- *
555
- * @private
556
- * @param {Array} guesses An array of guesses.
557
- * @returns {null|string} The detected OS name.
558
- */
559
- function getOS(guesses) {
560
- return reduce(guesses, function(result, guess) {
561
- var pattern = guess.pattern || qualify(guess);
562
- if (!result && (result =
563
- RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua)
564
- )) {
565
- result = cleanupOS(result, pattern, guess.label || guess);
566
- }
567
- return result;
568
- });
569
- }
570
-
571
- /**
572
- * Picks the product name from an array of guesses.
573
- *
574
- * @private
575
- * @param {Array} guesses An array of guesses.
576
- * @returns {null|string} The detected product name.
577
- */
578
- function getProduct(guesses) {
579
- return reduce(guesses, function(result, guess) {
580
- var pattern = guess.pattern || qualify(guess);
581
- if (!result && (result =
582
- RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) ||
583
- RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) ||
584
- RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua)
585
- )) {
586
- // Split by forward slash and append product version if needed.
587
- if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) {
588
- result[0] += ' ' + result[1];
589
- }
590
- // Correct character case and cleanup string.
591
- guess = guess.label || guess;
592
- result = format(result[0]
593
- .replace(RegExp(pattern, 'i'), guess)
594
- .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ')
595
- .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2'));
596
- }
597
- return result;
598
- });
599
- }
600
-
601
- /**
602
- * Resolves the version using an array of UA patterns.
603
- *
604
- * @private
605
- * @param {Array} patterns An array of UA patterns.
606
- * @returns {null|string} The detected version.
607
- */
608
- function getVersion(patterns) {
609
- return reduce(patterns, function(result, pattern) {
610
- return result || (RegExp(pattern +
611
- '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null;
612
- });
613
- }
614
-
615
- /**
616
- * Returns `platform.description` when the platform object is coerced to a string.
617
- *
618
- * @name toString
619
- * @memberOf platform
620
- * @returns {string} Returns `platform.description` if available, else an empty string.
621
- */
622
- function toStringPlatform() {
623
- return this.description || '';
624
- }
625
-
626
- /*------------------------------------------------------------------------*/
627
-
628
- // Convert layout to an array so we can add extra details.
629
- layout && (layout = [layout]);
630
-
631
- // Detect Android products.
632
- // Browsers on Android devices typically provide their product IDS after "Android;"
633
- // up to "Build" or ") AppleWebKit".
634
- // Example:
635
- // "Mozilla/5.0 (Linux; Android 8.1.0; Moto G (5) Plus) AppleWebKit/537.36
636
- // (KHTML, like Gecko) Chrome/70.0.3538.80 Mobile Safari/537.36"
637
- if (/\bAndroid\b/.test(os) && !product &&
638
- (data = /\bAndroid[^;]*;(.*?)(?:Build|\) AppleWebKit)\b/i.exec(ua))) {
639
- product = trim(data[1])
640
- // Replace any language codes (eg. "en-US").
641
- .replace(/^[a-z]{2}-[a-z]{2};\s*/i, '')
642
- || null;
643
- }
644
- // Detect product names that contain their manufacturer's name.
645
- if (manufacturer && !product) {
646
- product = getProduct([manufacturer]);
647
- } else if (manufacturer && product) {
648
- product = product
649
- .replace(RegExp('^(' + qualify(manufacturer) + ')[-_.\\s]', 'i'), manufacturer + ' ')
650
- .replace(RegExp('^(' + qualify(manufacturer) + ')[-_.]?(\\w)', 'i'), manufacturer + ' $2');
651
- }
652
- // Clean up Google TV.
653
- if ((data = /\bGoogle TV\b/.exec(product))) {
654
- product = data[0];
655
- }
656
- // Detect simulators.
657
- if (/\bSimulator\b/i.test(ua)) {
658
- product = (product ? product + ' ' : '') + 'Simulator';
659
- }
660
- // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS.
661
- if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) {
662
- description.push('running in Turbo/Uncompressed mode');
663
- }
664
- // Detect IE Mobile 11.
665
- if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) {
666
- data = parse(ua.replace(/like iPhone OS/, ''));
667
- manufacturer = data.manufacturer;
668
- product = data.product;
669
- }
670
- // Detect iOS.
671
- else if (/^iP/.test(product)) {
672
- name || (name = 'Safari');
673
- os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua))
674
- ? ' ' + data[1].replace(/_/g, '.')
675
- : '');
676
- }
677
- // Detect Kubuntu.
678
- else if (name == 'Konqueror' && /^Linux\b/i.test(os)) {
679
- os = 'Kubuntu';
680
- }
681
- // Detect Android browsers.
682
- else if ((manufacturer && manufacturer != 'Google' &&
683
- ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) ||
684
- (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) {
685
- name = 'Android Browser';
686
- os = /\bAndroid\b/.test(os) ? os : 'Android';
687
- }
688
- // Detect Silk desktop/accelerated modes.
689
- else if (name == 'Silk') {
690
- if (!/\bMobi/i.test(ua)) {
691
- os = 'Android';
692
- description.unshift('desktop mode');
693
- }
694
- if (/Accelerated *= *true/i.test(ua)) {
695
- description.unshift('accelerated');
696
- }
697
- }
698
- // Detect UC Browser speed mode.
699
- else if (name == 'UC Browser' && /\bUCWEB\b/.test(ua)) {
700
- description.push('speed mode');
701
- }
702
- // Detect PaleMoon identifying as Firefox.
703
- else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) {
704
- description.push('identifying as Firefox ' + data[1]);
705
- }
706
- // Detect Firefox OS and products running Firefox.
707
- else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) {
708
- os || (os = 'Firefox OS');
709
- product || (product = data[1]);
710
- }
711
- // Detect false positives for Firefox/Safari.
712
- else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) {
713
- // Escape the `/` for Firefox 1.
714
- if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) {
715
- // Clear name of false positives.
716
- name = null;
717
- }
718
- // Reassign a generic name.
719
- if ((data = product || manufacturer || os) &&
720
- (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) {
721
- name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser';
722
- }
723
- }
724
- // Add Chrome version to description for Electron.
725
- else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) {
726
- description.push('Chromium ' + data);
727
- }
728
- // Detect non-Opera (Presto-based) versions (order is important).
729
- if (!version) {
730
- version = getVersion([
731
- '(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|HeadlessChrome|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$)|UCBrowser|YaBrowser)',
732
- 'Version',
733
- qualify(name),
734
- '(?:Firefox|Minefield|NetFront)'
735
- ]);
736
- }
737
- // Detect stubborn layout engines.
738
- if ((data =
739
- layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' ||
740
- /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') ||
741
- /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' ||
742
- !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') ||
743
- layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront'
744
- )) {
745
- layout = [data];
746
- }
747
- // Detect Windows Phone 7 desktop mode.
748
- if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) {
749
- name += ' Mobile';
750
- os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x');
751
- description.unshift('desktop mode');
752
- }
753
- // Detect Windows Phone 8.x desktop mode.
754
- else if (/\bWPDesktop\b/i.test(ua)) {
755
- name = 'IE Mobile';
756
- os = 'Windows Phone 8.x';
757
- description.unshift('desktop mode');
758
- version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]);
759
- }
760
- // Detect IE 11 identifying as other browsers.
761
- else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) {
762
- if (name) {
763
- description.push('identifying as ' + name + (version ? ' ' + version : ''));
764
- }
765
- name = 'IE';
766
- version = data[1];
767
- }
768
- // Leverage environment features.
769
- if (useFeatures) {
770
- // Detect server-side environments.
771
- // Rhino has a global function while others have a global object.
772
- if (isHostType(context, 'global')) {
773
- if (java) {
774
- data = java.lang.System;
775
- arch = data.getProperty('os.arch');
776
- os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version');
777
- }
778
- if (rhino) {
779
- try {
780
- version = context.require('ringo/engine').version.join('.');
781
- name = 'RingoJS';
782
- } catch(e) {
783
- if ((data = context.system) && data.global.system == context.system) {
784
- name = 'Narwhal';
785
- os || (os = data[0].os || null);
786
- }
787
- }
788
- if (!name) {
789
- name = 'Rhino';
790
- }
791
- }
792
- else if (
793
- typeof context.process == 'object' && !context.process.browser &&
794
- (data = context.process)
795
- ) {
796
- if (typeof data.versions == 'object') {
797
- if (typeof data.versions.electron == 'string') {
798
- description.push('Node ' + data.versions.node);
799
- name = 'Electron';
800
- version = data.versions.electron;
801
- } else if (typeof data.versions.nw == 'string') {
802
- description.push('Chromium ' + version, 'Node ' + data.versions.node);
803
- name = 'NW.js';
804
- version = data.versions.nw;
805
- }
806
- }
807
- if (!name) {
808
- name = 'Node.js';
809
- arch = data.arch;
810
- os = data.platform;
811
- version = /[\d.]+/.exec(data.version);
812
- version = version ? version[0] : null;
813
- }
814
- }
815
- }
816
- // Detect Adobe AIR.
817
- else if (getClassOf((data = context.runtime)) == airRuntimeClass) {
818
- name = 'Adobe AIR';
819
- os = data.flash.system.Capabilities.os;
820
- }
821
- // Detect PhantomJS.
822
- else if (getClassOf((data = context.phantom)) == phantomClass) {
823
- name = 'PhantomJS';
824
- version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch);
825
- }
826
- // Detect IE compatibility modes.
827
- else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) {
828
- // We're in compatibility mode when the Trident version + 4 doesn't
829
- // equal the document mode.
830
- version = [version, doc.documentMode];
831
- if ((data = +data[1] + 4) != version[1]) {
832
- description.push('IE ' + version[1] + ' mode');
833
- layout && (layout[1] = '');
834
- version[1] = data;
835
- }
836
- version = name == 'IE' ? String(version[1].toFixed(1)) : version[0];
837
- }
838
- // Detect IE 11 masking as other browsers.
839
- else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) {
840
- description.push('masking as ' + name + ' ' + version);
841
- name = 'IE';
842
- version = '11.0';
843
- layout = ['Trident'];
844
- os = 'Windows';
845
- }
846
- os = os && format(os);
847
- }
848
- // Detect prerelease phases.
849
- if (version && (data =
850
- /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) ||
851
- /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) ||
852
- /\bMinefield\b/i.test(ua) && 'a'
853
- )) {
854
- prerelease = /b/i.test(data) ? 'beta' : 'alpha';
855
- version = version.replace(RegExp(data + '\\+?$'), '') +
856
- (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || '');
857
- }
858
- // Detect Firefox Mobile.
859
- if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS|KaiOS)\b/.test(os)) {
860
- name = 'Firefox Mobile';
861
- }
862
- // Obscure Maxthon's unreliable version.
863
- else if (name == 'Maxthon' && version) {
864
- version = version.replace(/\.[\d.]+/, '.x');
865
- }
866
- // Detect Xbox 360 and Xbox One.
867
- else if (/\bXbox\b/i.test(product)) {
868
- if (product == 'Xbox 360') {
869
- os = null;
870
- }
871
- if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) {
872
- description.unshift('mobile mode');
873
- }
874
- }
875
- // Add mobile postfix.
876
- else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) &&
877
- (os == 'Windows CE' || /Mobi/i.test(ua))) {
878
- name += ' Mobile';
879
- }
880
- // Detect IE platform preview.
881
- else if (name == 'IE' && useFeatures) {
882
- try {
883
- if (context.external === null) {
884
- description.unshift('platform preview');
885
- }
886
- } catch(e) {
887
- description.unshift('embedded');
888
- }
889
- }
890
- // Detect BlackBerry OS version.
891
- // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp
892
- else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data =
893
- (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] ||
894
- version
895
- )) {
896
- data = [data, /BB10/.test(ua)];
897
- os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0];
898
- version = null;
899
- }
900
- // Detect Opera identifying/masking itself as another browser.
901
- // http://www.opera.com/support/kb/view/843/
902
- else if (this != forOwn && product != 'Wii' && (
903
- (useFeatures && opera) ||
904
- (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) ||
905
- (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) ||
906
- (name == 'IE' && (
907
- (os && !/^Win/.test(os) && version > 5.5) ||
908
- /\bWindows XP\b/.test(os) && version > 8 ||
909
- version == 8 && !/\bTrident\b/.test(ua)
910
- ))
911
- ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) {
912
- // When "identifying", the UA contains both Opera and the other browser's name.
913
- data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : '');
914
- if (reOpera.test(name)) {
915
- if (/\bIE\b/.test(data) && os == 'Mac OS') {
916
- os = null;
917
- }
918
- data = 'identify' + data;
919
- }
920
- // When "masking", the UA contains only the other browser's name.
921
- else {
922
- data = 'mask' + data;
923
- if (operaClass) {
924
- name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2'));
925
- } else {
926
- name = 'Opera';
927
- }
928
- if (/\bIE\b/.test(data)) {
929
- os = null;
930
- }
931
- if (!useFeatures) {
932
- version = null;
933
- }
934
- }
935
- layout = ['Presto'];
936
- description.push(data);
937
- }
938
- // Detect WebKit Nightly and approximate Chrome/Safari versions.
939
- if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
940
- // Correct build number for numeric comparison.
941
- // (e.g. "532.5" becomes "532.05")
942
- data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data];
943
- // Nightly builds are postfixed with a "+".
944
- if (name == 'Safari' && data[1].slice(-1) == '+') {
945
- name = 'WebKit Nightly';
946
- prerelease = 'alpha';
947
- version = data[1].slice(0, -1);
948
- }
949
- // Clear incorrect browser versions.
950
- else if (version == data[1] ||
951
- version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) {
952
- version = null;
953
- }
954
- // Use the full Chrome version when available.
955
- data[1] = (/\b(?:Headless)?Chrome\/([\d.]+)/i.exec(ua) || 0)[1];
956
- // Detect Blink layout engine.
957
- if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') {
958
- layout = ['Blink'];
959
- }
960
- // Detect JavaScriptCore.
961
- // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi
962
- if (!useFeatures || (!likeChrome && !data[1])) {
963
- layout && (layout[1] = 'like Safari');
964
- 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 : data < 602 ? 9 : data < 604 ? 10 : data < 606 ? 11 : data < 608 ? 12 : '12');
965
- } else {
966
- layout && (layout[1] = 'like Chrome');
967
- 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');
968
- }
969
- // Add the postfix of ".x" or "+" for approximate versions.
970
- layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+'));
971
- // Obscure version for some Safari 1-2 releases.
972
- if (name == 'Safari' && (!version || parseInt(version) > 45)) {
973
- version = data;
974
- } else if (name == 'Chrome' && /\bHeadlessChrome/i.test(ua)) {
975
- description.unshift('headless');
976
- }
977
- }
978
- // Detect Opera desktop modes.
979
- if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) {
980
- name += ' ';
981
- description.unshift('desktop mode');
982
- if (data == 'zvav') {
983
- name += 'Mini';
984
- version = null;
985
- } else {
986
- name += 'Mobile';
987
- }
988
- os = os.replace(RegExp(' *' + data + '$'), '');
989
- }
990
- // Detect Chrome desktop mode.
991
- else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) {
992
- description.unshift('desktop mode');
993
- name = 'Chrome Mobile';
994
- version = null;
995
-
996
- if (/\bOS X\b/.test(os)) {
997
- manufacturer = 'Apple';
998
- os = 'iOS 4.3+';
999
- } else {
1000
- os = null;
1001
- }
1002
- }
1003
- // Newer versions of SRWare Iron uses the Chrome tag to indicate its version number.
1004
- else if (/\bSRWare Iron\b/.test(name) && !version) {
1005
- version = getVersion('Chrome');
1006
- }
1007
- // Strip incorrect OS versions.
1008
- if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 &&
1009
- ua.indexOf('/' + data + '-') > -1) {
1010
- os = trim(os.replace(data, ''));
1011
- }
1012
- // Ensure OS does not include the browser name.
1013
- if (os && os.indexOf(name) != -1 && !RegExp(name + ' OS').test(os)) {
1014
- os = os.replace(RegExp(' *' + qualify(name) + ' *'), '');
1015
- }
1016
- // Add layout engine.
1017
- if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
1018
- /Browser|Lunascape|Maxthon/.test(name) ||
1019
- name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) ||
1020
- /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|SRWare Iron|Vivaldi|Web)/.test(name) && layout[1])) {
1021
- // Don't add layout details to description if they are falsey.
1022
- (data = layout[layout.length - 1]) && description.push(data);
1023
- }
1024
- // Combine contextual information.
1025
- if (description.length) {
1026
- description = ['(' + description.join('; ') + ')'];
1027
- }
1028
- // Append manufacturer to description.
1029
- if (manufacturer && product && product.indexOf(manufacturer) < 0) {
1030
- description.push('on ' + manufacturer);
1031
- }
1032
- // Append product to description.
1033
- if (product) {
1034
- description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product);
1035
- }
1036
- // Parse the OS into an object.
1037
- if (os) {
1038
- data = / ([\d.+]+)$/.exec(os);
1039
- isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/';
1040
- os = {
1041
- 'architecture': 32,
1042
- 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os,
1043
- 'version': data ? data[1] : null,
1044
- 'toString': function() {
1045
- var version = this.version;
1046
- return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : '');
1047
- }
1048
- };
1049
- }
1050
- // Add browser/OS architecture.
1051
- if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) {
1052
- if (os) {
1053
- os.architecture = 64;
1054
- os.family = os.family.replace(RegExp(' *' + data), '');
1055
- }
1056
- if (
1057
- name && (/\bWOW64\b/i.test(ua) ||
1058
- (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua)))
1059
- ) {
1060
- description.unshift('32-bit');
1061
- }
1062
- }
1063
- // Chrome 39 and above on OS X is always 64-bit.
1064
- else if (
1065
- os && /^OS X/.test(os.family) &&
1066
- name == 'Chrome' && parseFloat(version) >= 39
1067
- ) {
1068
- os.architecture = 64;
1069
- }
1070
-
1071
- ua || (ua = null);
1072
-
1073
- /*------------------------------------------------------------------------*/
1074
-
1075
- /**
1076
- * The platform object.
1077
- *
1078
- * @name platform
1079
- * @type Object
1080
- */
1081
- var platform = {};
1082
-
1083
- /**
1084
- * The platform description.
1085
- *
1086
- * @memberOf platform
1087
- * @type string|null
1088
- */
1089
- platform.description = ua;
1090
-
1091
- /**
1092
- * The name of the browser's layout engine.
1093
- *
1094
- * The list of common layout engines include:
1095
- * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit"
1096
- *
1097
- * @memberOf platform
1098
- * @type string|null
1099
- */
1100
- platform.layout = layout && layout[0];
1101
-
1102
- /**
1103
- * The name of the product's manufacturer.
1104
- *
1105
- * The list of manufacturers include:
1106
- * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry",
1107
- * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo",
1108
- * "Nokia", "Samsung" and "Sony"
1109
- *
1110
- * @memberOf platform
1111
- * @type string|null
1112
- */
1113
- platform.manufacturer = manufacturer;
1114
-
1115
- /**
1116
- * The name of the browser/environment.
1117
- *
1118
- * The list of common browser names include:
1119
- * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE",
1120
- * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk",
1121
- * "Opera Mini" and "Opera"
1122
- *
1123
- * Mobile versions of some browsers have "Mobile" appended to their name:
1124
- * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile"
1125
- *
1126
- * @memberOf platform
1127
- * @type string|null
1128
- */
1129
- platform.name = name;
1130
-
1131
- /**
1132
- * The alpha/beta release indicator.
1133
- *
1134
- * @memberOf platform
1135
- * @type string|null
1136
- */
1137
- platform.prerelease = prerelease;
1138
-
1139
- /**
1140
- * The name of the product hosting the browser.
1141
- *
1142
- * The list of common products include:
1143
- *
1144
- * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle",
1145
- * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer"
1146
- *
1147
- * @memberOf platform
1148
- * @type string|null
1149
- */
1150
- platform.product = product;
1151
-
1152
- /**
1153
- * The browser's user agent string.
1154
- *
1155
- * @memberOf platform
1156
- * @type string|null
1157
- */
1158
- platform.ua = ua;
1159
-
1160
- /**
1161
- * The browser/environment version.
1162
- *
1163
- * @memberOf platform
1164
- * @type string|null
1165
- */
1166
- platform.version = name && version;
1167
-
1168
- /**
1169
- * The name of the operating system.
1170
- *
1171
- * @memberOf platform
1172
- * @type Object
1173
- */
1174
- platform.os = os || {
1175
-
1176
- /**
1177
- * The CPU architecture the OS is built for.
1178
- *
1179
- * @memberOf platform.os
1180
- * @type number|null
1181
- */
1182
- 'architecture': null,
1183
-
1184
- /**
1185
- * The family of the OS.
1186
- *
1187
- * Common values include:
1188
- * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista",
1189
- * "Windows XP", "OS X", "Linux", "Ubuntu", "Debian", "Fedora", "Red Hat",
1190
- * "SuSE", "Android", "iOS" and "Windows Phone"
1191
- *
1192
- * @memberOf platform.os
1193
- * @type string|null
1194
- */
1195
- 'family': null,
1196
-
1197
- /**
1198
- * The version of the OS.
1199
- *
1200
- * @memberOf platform.os
1201
- * @type string|null
1202
- */
1203
- 'version': null,
1204
-
1205
- /**
1206
- * Returns the OS string.
1207
- *
1208
- * @memberOf platform.os
1209
- * @returns {string} The OS string.
1210
- */
1211
- 'toString': function() { return 'null'; }
1212
- };
1213
-
1214
- platform.parse = parse;
1215
- platform.toString = toStringPlatform;
1216
-
1217
- if (platform.version) {
1218
- description.unshift(version);
1219
- }
1220
- if (platform.name) {
1221
- description.unshift(name);
1222
- }
1223
- if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) {
1224
- description.push(product ? '(' + os + ')' : 'on ' + os);
1225
- }
1226
- if (description.length) {
1227
- platform.description = description.join(' ');
1228
- }
1229
- return platform;
1230
- }
1231
-
1232
- /*--------------------------------------------------------------------------*/
1233
-
1234
- // Export platform.
1235
- var platform = parse();
1236
-
1237
- // Some AMD build optimizers, like r.js, check for condition patterns like the following:
1238
- if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
1239
- // Expose platform on the global object to prevent errors when platform is
1240
- // loaded by a script tag in the presence of an AMD loader.
1241
- // See http://requirejs.org/docs/errors.html#mismatch for more details.
1242
- root.platform = platform;
1243
-
1244
- // Define as an anonymous module so platform can be aliased through path mapping.
1245
- define(function() {
1246
- return platform;
1247
- });
1248
- }
1249
- // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
1250
- else if (freeExports && freeModule) {
1251
- // Export for CommonJS support.
1252
- forOwn(platform, function(value, key) {
1253
- freeExports[key] = value;
1254
- });
1255
- }
1256
- else {
1257
- // Export to the global object.
1258
- root.platform = platform;
1259
- }
1260
- }.call(this));