1/* makeURLAbsolute is cribbed from jQuery Mobile, and modified to suit our needs.*/ 2/*! 3* jQuery Mobile 1.4.5 4* Git HEAD hash: 68e55e78b292634d3991c795f06f5e37a512decc <> Date: Fri Oct 31 2014 17:33:30 UTC 5* http:/ /jquerymobile.com 6* 7* Copyright 2010, 2014 jQuery Foundation, Inc. and other contributors 8* Released under the MIT license. 9* http:/ /jquery.org/license 10* 11*/ 12 13/*Parse a URL into a structure that allows easy access to 14all of the URL components by name.*/ 15function parseUrl( url ) { 16 var matches = new RegExp('^\\s*(((([^:\\/#\\?]+:)?(?:(\\/\\/)((?:(([^:@\\/#\\?]+)(?:\\:([^:@\\/#\\?]+))?)@)?(([^:\\/#\\?\\]\\[]+|\\[[^\\/\\]@#?]+\\])(?:\\:([0-9]+))?))?)?)?((\\/?(?:[^\\/\\?#]+\\/+)*)([^\\?#]*)))?(\\?[^#]+)?)(#.*)?').exec( url || "" ) || []; 17 18 /* Create an object that allows the caller to access the sub-matches 19 by name. Note that IE returns an empty string instead of undefined, 20 like all other browsers do, so we normalize everything so its consistent 21 no matter what browser we're running on. */ 22 return { 23 href: matches[ 0 ] || "", 24 hrefNoHash: matches[ 1 ] || "", 25 hrefNoSearch: matches[ 2 ] || "", 26 domain: matches[ 3 ] || "", 27 protocol: matches[ 4 ] || "", 28 doubleSlash: matches[ 5 ] || "", 29 authority: matches[ 6 ] || "", 30 username: matches[ 8 ] || "", 31 password: matches[ 9 ] || "", 32 host: matches[ 10 ] || "", 33 hostname: matches[ 11 ] || "", 34 port: matches[ 12 ] || "", 35 pathname: matches[ 13 ] || "", 36 directory: matches[ 14 ] || "", 37 filename: matches[ 15 ] || "", 38 search: matches[ 16 ] || "", 39 hash: matches[ 17 ] || "" 40 }; 41} 42 43/*Turn relPath into an asbolute path. absPath is 44an optional absolute path which describes what 45relPath is relative to.*/ 46function makePathAbsolute( relPath, absPath ) { 47 var absStack, 48 relStack, 49 i, d; 50 51 if ( relPath && relPath.charAt( 0 ) === "/" ) { 52 return relPath; 53 } 54 55 relPath = relPath || ""; 56 absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : ""; 57 58 absStack = absPath ? absPath.split( "/" ) : []; 59 relStack = relPath.split( "/" ); 60 61 for ( i = 0; i < relStack.length; i++ ) { 62 d = relStack[ i ]; 63 switch ( d ) { 64 case ".": 65 break; 66 case "..": 67 if ( absStack.length ) { 68 absStack.pop(); 69 } 70 break; 71 default: 72 absStack.push( d ); 73 break; 74 } 75 } 76 return "/" + absStack.join( "/" ); 77} 78 79/*Turn the specified relative URL into an absolute one. This function 80can handle all relative variants (protocol, site, document, query, fragment). 81 modified to omit the search and hash part of the URL.*/ 82function makeUrlAbsolute( relUrl, absUrl ) { 83 var relObj = parseUrl( relUrl ); 84 if (relObj.protocol !== "") { 85 return relUrl; 86 } 87 if ( absUrl === undefined ) { 88 absUrl = window.location.href; 89 } 90 var absObj = parseUrl( absUrl ); 91 92 93 var protocol = relObj.protocol || absObj.protocol; 94 var doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ); 95 var authority = relObj.authority || absObj.authority; 96 var hasPath = relObj.pathname !== ""; 97 var pathname = makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ); 98 99 return protocol + doubleSlash + authority + pathname; 100} 101 102function compareURLs(url1, url2) { 103 var absUrl1 = makeUrlAbsolute(url1); 104 var absUrl2 = makeUrlAbsolute(url2); 105 return absUrl1 === absUrl2; 106} 107 108function injectlinks(source, target) { 109 /* iterate over all source links.*/ 110 $("#"+source+" li>a").each(function() { 111 /* check for duplicate href.*/ 112 var sourceHref = $( this ).attr('href'); 113 if (sourceHref != "") { 114 var inject = true; 115 $("#mobileNavbar > ul > ul > li>a").each(function() { 116 if (compareURLs(sourceHref,$( this ).attr('href'))) { 117 inject=false; 118 } 119 }); 120 /* inject non-duplicates.*/ 121 if (inject) { 122 var injectedLinks = $( this ).clone(); 123 injectedLinks.attr("id", "mobile" + this.id); 124 $("#"+target).append($(injectedLinks).wrap("<li></li>").parent()); 125 $(document).trigger("linkInjected", this); 126 } 127 } 128 129 }); 130} 131//================================================================================================================== 132// jQuery prototypes 133//------------------------------------------------------------------------------------------------------------------ 134jQuery.fn.extend({ 135 //------------------------------------------------------------------------------------------------------------------ 136 // locate the input group (returns the ancestor containing the Group class or the parent of the current element) 137 //------------------------------------------------------------------------------------------------------------------ 138 inputGroup: function() { 139 var $rv = $(); 140 this.each(function() { 141 $rv = $rv.add($($(this).closest("."+$(this).attr("id")+"Group")[0] || 142 $(this).closest("."+$(this).attr("name")+"Group")[0] || 143 $(this).parent()[0])); 144 }); 145 return $rv; 146 }, 147 148 //------------------------------------------------------------------------------------------------------------------ 149 // addError to input (returns the elements that have had errors added) 150 //------------------------------------------------------------------------------------------------------------------ 151 addInputError: function(errorMessage, alert) { 152 alert = (alert !== undefined) ? alert : true; 153 errorMsg = (errorMessage !== undefined) ? errorMessage : this.attr('error-msg'); 154 155 var $rv = $(); 156 this.each(function () { 157 var alertRoleAttr = alert?' role="alert"':''; 158 if(!$(this).attr("aria-invalid")){ 159 $rv=$rv.add($(this)); 160 fieldErrorId = typeof ($(this).attr("name")) !== 'undefined' ? $(this).attr("name") + "Error" : ""; 161 $(this).inputGroup().children(".validation-error").length 162 ? $(this).inputGroup().children(".validation-error") 163 : $(this).inputGroup().append('<div id="' + fieldErrorId + '" class="validation-error"' + alertRoleAttr + '></div>'); 164 var error = $(this).inputGroup().children(".validation-error"); 165 $(this).attr("aria-invalid", "true"); 166 $(this).inputGroup().addClass("has-validation-error"); 167 error.html('<span class="message-icon"><svg data-name="Outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">' + 168 '<path d="M18.67,17.67l-8-16a.79.79,0,0,0-1.34,0l-8,16A.75.75,0,0,0,2,18.75H18a.75.75,0,0,0,.67-1.08ZM3.21,17.25,10,3.68l6.79,13.57ZM9.25,8h1.5v5H9.25Zm1.46,6.29a1.15,1.15,0,0,1,.21.33.94.94,0,0,1,0,.76,1.15,1.15,0,0,1-.21.33,1,1,0,0,1-1.63-1.09,1,1,0,0,1,.21-.33,1,1,0,0,1,.9-.27.6.6,0,0,1,.19.06l.18.09Z"/>' + 169 '</svg></span>
169<p>' + errorMessage + '</p>'); 170 } 171 }); 172 return $rv; 173 }, 174 175 //------------------------------------------------------------------------------------------------------------------ 176 //Check for Errors (returns the elements have are invalid) 177 //------------------------------------------------------------------------------------------------------------------ 178 checkForErrors: function() { 179 var $rv = $(); 180 this.each(function() { 181 var isValid=false; 182 if(this.validity.valid){ 183 var visibleId = $(this).attr('id'); 184 if(visibleId && visibleId.match("^visible")){ 185 var hiddenInput = $(this).next(); 186 if(hiddenInput.length && hiddenInput[0].validity.valid){ 187 isValid=true; 188 } 189 } else { 190 isValid=true; 191 } 192 } 193 if(!isValid){ 194 $rv=$rv.add($(this)); 195 $(this).trigger( "invalid" ); 196 } 197 }); 198 return $rv; 199 }, 200 201 //================================================================================================================== 202 // Remove Errors 203 //------------------------------------------------------------------------------------------------------------------ 204 removeErrors: function() { 205 var $rv = $(); 206 this.each(function () { 207 $(this).inputGroup().children(".validation-error").remove(); 208 $(this).inputGroup().removeClass("has-validation-error"); 209 $(this).removeAttr( "aria-invalid" ); 210 $rv=$rv.add($(this)); 211 }); 212 return $rv; 213 }, 214 215 //================================================================================================================== 216 // add focus class from FORM LABEL 217 //------------------------------------------------------------------------------------------------------------------ 218 addFocusClass: function() { 219 this.inputGroup().children("label").removeClass("input-label").addClass("input-focus-label"); 220 return this; 221 }, 222 223 //================================================================================================================== 224 // remove focus class from FORM LABEL 225 //------------------------------------------------------------------------------------------------------------------ 226 removeFocusClass: function() { 227 var $rv = this.filter(function () { 228 if (this.value) {return false;} 229 if ($(this).prevAll(".input-group-addon")[0]) {return false;} 230 return $(this).is('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"]),:not(select)'); 231 }); 232 $rv.inputGroup().children("label").addClass("input-label").removeClass("input-focus-label"); 233 return $rv; 234 }, 235 236 //================================================================================================================== 237 // Initialize focus class for FORM LABEL 238 //------------------------------------------------------------------------------------------------------------------ 239 initializeFocusClass: function() { 240 return this.addFocusClass().removeFocusClass(); 241 }, 242 243 //================================================================================================================== 244 // Return whether the first element is required, 245 // OR 246 // Set the required attribute for all elements, show/hide the Helper text if it is "(Optional)", 247 // and check for errors, which may show or hide a field level error message. 248 //------------------------------------------------------------------------------------------------------------------ 249 required: function(isRequired) { 250 if (isRequired == undefined) { 251 // return the value of the required property for the first matched field. 252 return $(this).first().prop("required"); 253 } 254 // add/remove the required attribute, set/remove the (Optional) helper text, and fire the change method 255 $(this).inputGroup().children("[id$="+$(this).attr("id")+"Help]").filter(":contains(Optional),:contains(Opcional)").toggle(!isRequired); 256 if (isRequired) { 257 return $(this).filter(function(index){return !$(this).prop("required")}).attr("required",true).removeErrors().checkForErrors(); 258 } else { 259 return $(this).filter(function(index){return $(this).prop("required")}).removeAttr("required").removeErrors().checkForErrors(); 260 } 261 } 262}); 263 264//================================================================================================================== 265// addError to input. This function is suitable for using in a jQuery event handler 266//------------------------------------------------------------------------------------------------------------------ 267function addInputError(errorField, errorMsg){ 268 errorMsg = (typeof errorMsg !== undefined) ? errorMsg : ""; 269 if(errorField.originalEvent instanceof Event || (typeof errorField === 'object' && errorField.type == 'invali
269d')) { 270 $(this).addInputError($(this).attr('error-msg') ? $(this).attr('error-msg') : $(this)[0].title ? $(this)[0].title : $(this)[0].validationMessage, true); 271 } else { 272 $(this).addInputError(errorMsg, false); 273 } 274} 275 276//================================================================================================================== 277// Check for Errors. This function is suitable for using in a jQuery event handler 278//------------------------------------------------------------------------------------------------------------------ 279function checkForErrors(){ 280 $(this).checkForErrors(); 281 return true; 282} 283 284//================================================================================================================== 285// Remove Errors. This function is suitable for using in a jQuery event handler 286//------------------------------------------------------------------------------------------------------------------ 287function removeErrors(){ 288 $(this).removeErrors(); 289} 290 291//================================================================================================================== 292// add focus class from FORM LABEL. This function is suitable for using in a jQuery event handler 293//------------------------------------------------------------------------------------------------------------------ 294function addFocusClass(){ 295 $(this).addFocusClass(); 296} 297 298//================================================================================================================== 299// remove focus class from FORM LABEL. This function is suitable for using in a jQuery event handler 300//------------------------------------------------------------------------------------------------------------------ 301function removeFocusClass(){ 302 $(this).removeFocusClass(); 303} 304 305//================================================================================================================== 306// Initialize focus class for FORM LABEL. This function is suitable for using in a jQuery event handler 307//------------------------------------------------------------------------------------------------------------------ 308function initializeFocusClass(){ 309 $(this).initializeFocusClass(); 310} 311 312//================================================================================================================== 313// Format Currency amount to two decimal points for FORM INPUT 314//------------------------------------------------------------------------------------------------------------------ 315function formatCurrencyAmount(num) { 316 if (num == '') {return '';} 317 318 num = Number(num.toString().replace(/\$|\,/g, '')); 319 num = Math.round((num + Number.EPSILON) * 100) / 100; 320 if (isNaN(num)) { 321 return "0.00"; 322 } 323 return num.toFixed(2); 324} 325 326//================================================================================================================== 327// Apply Standard focus class to FORM LABEL 328//------------------------------------------------------------------------------------------------------------------ 329$(document).ready(function() { 330 $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').initializeFocusClass(); 331 $("[id^=visible]").initializeFocusClass(); 332 $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').focus(addFocusClass); 333 $('input:not([type="date"],[type="hidden"],[type="checkbox"],[type="radio"],[type="button"],[type="submit"])').focusout(removeFocusClass); 334 $('input, select, textarea').focus(removeErrors); 335 $('input, select, textarea').blur(checkForErrors); 336 $('input, select, textarea').on('invalid', addInputError); 337}); 338 339/*! 340 * Platform.js 341 * Copyright 2014-2018 Benjamin Tan 342 * Copyright 2011-2013 John-David Dalton 343 * Available under MIT license 344 */ 345;(function() { 346 'use strict'; 347 348 /** Used to determine if values are of the language type `Object`. */ 349 var objectTypes = { 350 'function': true, 351 'object': true 352 }; 353 354 /** Used as a reference to the global object. */ 355 var root = (objectTypes[typeof window] && window) || this; 356 357 /** Backup possible global object. */ 358 var oldRoot = root; 359 360 /** Detect free variable `exports`. */ 361 var freeExports = objectTypes[typeof exports] && exports; 362 363 /** Detect free variable `module`. */ 364 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; 365 366 /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ 367 var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; 368 if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { 369 root = freeGlobal; 370 } 371 372 /** 373 * Used as the maximum length of an array-like object. 374 * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) 375 * for more details. 376 */ 377 var maxSafeInteger = Math.pow(2, 53) - 1; 378 379 /** Regular expression to detect Opera. */ 380 var reOpera = /\bOpera/; 381 382 /** Possible global object. */ 383 var thisBinding = this; 384 385 /** Used for native method references. */ 386 var objectProto = Object.prototype; 387 388 /** Used to check for own properties of an object. */ 389 var hasOwnProperty = objectProto.hasOwnProperty; 390 391 /** Used to resolve the internal `[[Class]]` of values. */ 392 var toString = objectProto.toString; 393 394 /*--------------------------------------------------------------------------*/ 395 396 /** 397 * Capitalizes a string value. 398 * 399 * @private 400 * @param {string} string The string to capitalize. 401 * @returns {string} The capitalized string. 402 */ 403 function capitalize(string) { 404 string = String(string); 405 return string.charAt(0).toUpperCase() + string.slice(1); 406 } 407 408 /** 409 * A utility function to clean up the OS name. 410 * 411 * @private 412 * @param {string} os The OS name to clean up. 413 * @param {string} [pattern] A `RegExp` pattern matching the OS name. 414 * @param {string} [label] A label for the OS. 415 */ 416 function cleanupOS(os, pattern, label) { 417 // Platform tokens are defined at:
vendor: 8,661 bytes, lines 418-697
418 // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx 419 // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx 420 var data = { 421 '10.0': '10', 422 '6.4': '10 Technical Preview', 423 '6.3': '8.1', 424 '6.2': '8', 425 '6.1': 'Server 2008 R2 / 7', 426 '6.0': 'Server 2008 / Vista', 427 '5.2': 'Server 2003 / XP 64-bit', 428 '5.1': 'XP', 429 '5.01': '2000 SP1', 430 '5.0': '2000', 431 '4.0': 'NT', 432 '4.90': 'ME' 433 }; 434 // Detect Windows version from platform tokens. 435 if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && 436 (data = data[/[\d.]+$/.exec(os)])) { 437 os = 'Windows ' + data; 438 } 439 // Correct character case and cleanup string. 440 os = String(os); 441 442 if (pattern && label) { 443 os = os.replace(RegExp(pattern, 'i'), label); 444 } 445 446 os = format( 447 os.replace(/ ce$/i, ' CE') 448 .replace(/\bhpw/i, 'web') 449 .replace(/\bMacintosh\b/, 'Mac OS') 450 .replace(/_PowerPC\b/i, ' OS') 451 .replace(/\b(OS X) [^ \d]+/i, '$1') 452 .replace(/\bMac (OS X)\b/, '$1') 453 .replace(/\/(\d)/, ' $1') 454 .replace(/_/g, '.') 455 .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') 456 .replace(/\bx86\.64\b/gi, 'x86_64') 457 .replace(/\b(Windows Phone) OS\b/, '$1') 458 .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') 459 .split(' on ')[0] 460 ); 461 462 return os; 463 } 464 465 /** 466 * An iteration utility for arrays and objects. 467 * 468 * @private 469 * @param {Array|Object} object The object to iterate over. 470 * @param {Function} callback The function called per iteration. 471 */ 472 function each(object, callback) { 473 var index = -1, 474 length = object ? object.length : 0; 475 476 if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { 477 while (++index < length) { 478 callback(object[index], index, object); 479 } 480 } else { 481 forOwn(object, callback); 482 } 483 } 484 485 /** 486 * Trim and conditionally capitalize string values. 487 * 488 * @private 489 * @param {string} string The string to format. 490 * @returns {string} The formatted string. 491 */ 492 function format(string) { 493 string = trim(string); 494 return /^(?:webOS|i(?:OS|P))/.test(string) 495 ? string 496 : capitalize(string); 497 } 498 499 /** 500 * Iterates over an object's own properties, executing the `callback` for each. 501 * 502 * @private 503 * @param {Object} object The object to iterate over. 504 * @param {Function} callback The function executed per own property. 505 */ 506 function forOwn(object, callback) { 507 for (var key in object) { 508 if (hasOwnProperty.call(object, key)) { 509 callback(object[key], key, object); 510 } 511 } 512 } 513 514 /** 515 * Gets the internal `[[Class]]` of a value. 516 * 517 * @private 518 * @param {*} value The value. 519 * @returns {string} The `[[Class]]`. 520 */ 521 function getClassOf(value) { 522 return value == null 523 ? capitalize(value) 524 : toString.call(value).slice(8, -1); 525 } 526 527 /** 528 * Host objects can return type values that are different from their actual 529 * data type. The objects we are concerned with usually return non-primitive 530 * types of "object", "function", or "unknown". 531 * 532 * @private 533 * @param {*} object The owner of the property. 534 * @param {string} property The property to check. 535 * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. 536 */ 537 function isHostType(object, property) { 538 var type = object != null ? typeof object[property] : 'number'; 539 return !/^(?:boolean|number|string|undefined)$/.test(type) && 540 (type == 'object' ? !!object[property] : true); 541 } 542 543 /** 544 * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. 545 * 546 * @private 547 * @param {string} string The string to qualify. 548 * @returns {string} The qualified string. 549 */ 550 function qualify(string) { 551 return String(string).replace(/([ -])(?!$)/g, '$1?'); 552 } 553 554 /** 555 * A bare-bones `Array#reduce` like utility function. 556 * 557 * @private 558 * @param {Array} array The array to iterate over. 559 * @param {Function} callback The function called per iteration. 560 * @returns {*} The accumulated result. 561 */ 562 function reduce(array, callback) { 563 var accumulator = null; 564 each(array, function(value, index) { 565 accumulator = callback(accumulator, value, index, array); 566 }); 567 return accumulator; 568 } 569 570 /** 571 * Removes leading and trailing whitespace from a string. 572 * 573 * @private 574 * @param {string} string The string to trim. 575 * @returns {string} The trimmed string. 576 */ 577 function trim(string) { 578 return String(string).replace(/^ +| +$/g, ''); 579 } 580 581 /*--------------------------------------------------------------------------*/ 582 583 /** 584 * Creates a new platform object. 585 * 586 * @memberOf platform 587 * @param {Object|string} [ua=navigator.userAgent] The user agent string or 588 * context object. 589 * @returns {Object} A platform object. 590 */ 591 function parse(ua) { 592 593 /** The environment context object. */ 594 var context = root; 595 596 /** Used to flag when a custom context is provided. */ 597 var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; 598 599 // Juggle arguments. 600 if (isCustomContext) { 601 context = ua; 602 ua = null; 603 } 604 605 /** Browser navigator object. */ 606 var nav = context.navigator || {}; 607 608 /** Browser user agent string. */ 609 var userAgent = nav.userAgent || ''; 610 611 ua || (ua = userAgent); 612 613 /** Used to flag when `thisBinding` is the [ModuleScope]. */ 614 var isModuleScope = isCustomContext || thisBinding == oldRoot; 615 616 /** Used to detect if browser is like Chrome. */ 617 var likeChrome = isCustomContext 618 ? !!nav.likeChrome 619 : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); 620 621 /** Internal `[[Class]]` value shortcuts. */ 622 var objectClass = 'Object', 623 airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', 624 enviroClass = isCustomContext ? objectClass : 'Environment', 625 javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), 626 phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; 627 628 /** Detect Java environments. */ 629 var java = /\bJava/.test(javaClass) && context.java; 630 631 /** Detect Rhino. */ 632 var rhino = java && getClassOf(context.environment) == enviroClass; 633 634 /** A character to represent alpha. */ 635 var alpha = java ? 'a' : '\u03b1'; 636 637 /** A character to represent beta. */ 638 var beta = java ? 'b' : '\u03b2'; 639 640 /** Browser document object. */ 641 var doc = context.document || {}; 642 643 /** 644 * Detect Opera browser (Presto-based). 645 * http://www.howtocreate.co.uk/operaStuff/operaObject.html 646 * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini 647 */ 648 var opera = context.operamini || context.opera; 649 650 /** Opera `[[Class]]`. */ 651 var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) 652 ? operaClass 653 : (opera = null); 654 655 /*------------------------------------------------------------------------*/ 656 657 /** Temporary variable used over the script's lifetime. */ 658 var data; 659 660 /** The CPU architecture. */ 661 var arch = ua; 662 663 /** Platform description array. */ 664 var description = []; 665 666 /** Platform alpha/beta indicator. */ 667 var prerelease = null; 668 669 /** A flag to indicate that environment features should be used to resolve the platform. */ 670 var useFeatures = ua == userAgent; 671 672 /** The browser/environment version. */ 673 var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); 674 675 /** A flag to indicate if the OS ends with "/ Version" */ 676 var isSpecialCasedOS; 677 678 /* Detectable layout engines (order is important). */ 679 var layout = getLayout([ 680 { 'label': 'EdgeHTML', 'pattern': '(?:Edge|EdgA|EdgiOS)' }, 681 'Trident', 682 { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, 683 'iCab', 684 'Presto', 685 'NetFront', 686 'Tasman', 687 'KHTML', 688 'Gecko' 689 ]); 690 691 /* Detectable browser names (order is important). */ 692 var name = getName([ 693 'Adobe AIR', 694 'Arora', 695 'Avant Browser', 696 'Breach', 697 'Camino',
vendor: 11,309 bytes, lines 698-1029
698 'Electron', 699 'Epiphany', 700 'Fennec', 701 'Flock', 702 'Galeon', 703 'GreenBrowser', 704 'iCab', 705 'Iceweasel', 706 'K-Meleon', 707 'Konqueror', 708 'Lunascape', 709 'Maxthon', 710 { 'label': 'Microsoft Edge', 'pattern': '(?:Edge|Edg|EdgA|EdgiOS)' }, 711 'Midori', 712 'Nook Browser', 713 'PaleMoon', 714 'PhantomJS', 715 'Raven', 716 'Rekonq', 717 'RockMelt', 718 { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, 719 'SeaMonkey', 720 { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, 721 'Sleipnir', 722 'SlimBrowser', 723 { 'label': 'SRWare Iron', 'pattern': 'Iron' }, 724 'Sunrise', 725 'Swiftfox', 726 'Waterfox', 727 'WebPositive', 728 'Opera Mini', 729 { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, 730 'Opera', 731 { 'label': 'Opera', 'pattern': 'OPR' }, 732 'Chrome', 733 { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, 734 { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, 735 { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, 736 { 'label': 'IE', 'pattern': 'IEMobile' }, 737 { 'label': 'IE', 'pattern': 'MSIE' }, 738 'Safari' 739 ]); 740 741 /* Detectable products (order is important). */ 742 var product = getProduct([ 743 { 'label': 'BlackBerry', 'pattern': 'BB10' }, 744 'BlackBerry', 745 { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, 746 { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, 747 { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, 748 { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, 749 { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, 750 { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, 751 { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, 752 { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, 753 { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, 754 'Google TV', 755 'Lumia', 756 'iPad', 757 'iPod', 758 'iPhone', 759 'Kindle', 760 { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, 761 'Nexus', 762 'Nook', 763 'PlayBook', 764 'PlayStation Vita', 765 'PlayStation', 766 'TouchPad', 767 'Transformer', 768 { 'label': 'Wii U', 'pattern': 'WiiU' }, 769 'Wii', 770 'Xbox One', 771 { 'label': 'Xbox 360', 'pattern': 'Xbox' }, 772 'Xoom' 773 ]); 774 775 /* Detectable manufacturers. */ 776 var manufacturer = getManufacturer({ 777 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, 778 'Archos': {}, 779 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, 780 'Asus': { 'Transformer': 1 }, 781 'Barnes & Noble': { 'Nook': 1 }, 782 'BlackBerry': { 'PlayBook': 1 }, 783 'Google': { 'Google TV': 1, 'Nexus': 1 }, 784 'HP': { 'TouchPad': 1 }, 785 'HTC': {}, 786 'LG': {}, 787 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, 788 'Motorola': { 'Xoom': 1 }, 789 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, 790 'Nokia': { 'Lumia': 1 }, 791 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, 792 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } 793 }); 794 795 /* Detectable operating systems (order is important). */ 796 var os = getOS([ 797 'Windows Phone', 798 'Android', 799 'CentOS', 800 { 'label': 'Chrome OS', 'pattern': 'CrOS' }, 801 'Debian', 802 'Fedora', 803 'FreeBSD', 804 'Gentoo', 805 'Haiku', 806 'Kubuntu', 807 'Linux Mint', 808 'OpenBSD', 809 'Red Hat', 810 'SuSE', 811 'Ubuntu', 812 'Xubuntu', 813 'Cygwin', 814 'Symbian OS', 815 'hpwOS', 816 'webOS ', 817 'webOS', 818 'Tablet OS', 819 'Tizen', 820 'Linux', 821 'Mac OS X', 822 'Macintosh', 823 'Mac', 824 'Windows 98;', 825 'Windows ' 826 ]); 827 828 /*------------------------------------------------------------------------*/ 829 830 /** 831 * Picks the layout engine from an array of guesses. 832 * 833 * @private 834 * @param {Array} guesses An array of guesses. 835 * @returns {null|string} The detected layout engine. 836 */ 837 function getLayout(guesses) { 838 return reduce(guesses, function(result, guess) { 839 return result || RegExp('\\b' + ( 840 guess.pattern || qualify(guess) 841 ) + '\\b', 'i').exec(ua) && (guess.label || guess); 842 }); 843 } 844 845 /** 846 * Picks the manufacturer from an array of guesses. 847 * 848 * @private 849 * @param {Array} guesses An object of guesses. 850 * @returns {null|string} The detected manufacturer. 851 */ 852 function getManufacturer(guesses) { 853 return reduce(guesses, function(result, value, key) { 854 // Lookup the manufacturer by product or scan the UA for the manufacturer. 855 return result || ( 856 value[product] || 857 value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || 858 RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) 859 ) && key; 860 }); 861 } 862 863 /** 864 * Picks the browser name from an array of guesses. 865 * 866 * @private 867 * @param {Array} guesses An array of guesses. 868 * @returns {null|string} The detected browser name. 869 */ 870 function getName(guesses) { 871 return reduce(guesses, function(result, guess) { 872 return result || RegExp('\\b' + ( 873 guess.pattern || qualify(guess) 874 ) + '\\b', 'i').exec(ua) && (guess.label || guess); 875 }); 876 } 877 878 /** 879 * Picks the OS name from an array of guesses. 880 * 881 * @private 882 * @param {Array} guesses An array of guesses. 883 * @returns {null|string} The detected OS name. 884 */ 885 function getOS(guesses) { 886 return reduce(guesses, function(result, guess) { 887 var pattern = guess.pattern || qualify(guess); 888 if (!result && (result = 889 RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) 890 )) { 891 result = cleanupOS(result, pattern, guess.label || guess); 892 } 893 return result; 894 }); 895 } 896 897 /** 898 * Picks the product name from an array of guesses. 899 * 900 * @private 901 * @param {Array} guesses An array of guesses. 902 * @returns {null|string} The detected product name. 903 */ 904 function getProduct(guesses) { 905 return reduce(guesses, function(result, guess) { 906 var pattern = guess.pattern || qualify(guess); 907 if (!result && (result = 908 RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || 909 RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || 910 RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) 911 )) { 912 // Split by forward slash and append product version if needed. 913 if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { 914 result[0] += ' ' + result[1]; 915 } 916 // Correct character case and cleanup string. 917 guess = guess.label || guess; 918 result = format(result[0] 919 .replace(RegExp(pattern, 'i'), guess) 920 .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') 921 .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); 922 } 923 return result; 924 }); 925 } 926 927 /** 928 * Resolves the version using an array of UA patterns. 929 * 930 * @private 931 * @param {Array} patterns An array of UA patterns. 932 * @returns {null|string} The detected version. 933 */ 934 function getVersion(patterns) { 935 return reduce(patterns, function(result, pattern) { 936 return result || (RegExp(pattern + 937 '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; 938 }); 939 } 940 941 /** 942 * Returns `platform.description` when the platform object is coerced to a string. 943 * 944 * @name toString 945 * @memberOf platform 946 * @returns {string} Returns `platform.description` if available, else an empty string. 947 */ 948 function toStringPlatform() { 949 return this.description || ''; 950 } 951 952 /*------------------------------------------------------------------------*/ 953 954 // Convert layout to an array so we can add extra details. 955 layout && (layout = [layout]); 956 957 // Detect product names that contain their manufacturer's name. 958 if (manufacturer && !product) { 959 product = getProduct([manufacturer]); 960 } 961 // Clean up Google TV. 962 if ((data = /\bGoogle TV\b/.exec(product))) { 963 product = data[0]; 964 } 965 // Detect simulators. 966 if (/\bSimulator\b/i.test(ua)) { 967 product = (product ? product + ' ' : '') + 'Simulator'; 968 } 969 // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. 970 if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { 971 description.push('running in Turbo/Uncompressed mode'); 972 } 973 // Detect IE Mobile 11. 974 if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { 975 data = parse(ua.replace(/like iPhone OS/, '')); 976 manufacturer = data.manufacturer; 977 product = data.product; 978 } 979 // Detect iOS. 980 else if (/^iP/.test(product)) { 981 name || (name = 'Safari'); 982 os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) 983 ? ' ' + data[1].replace(/_/g, '.') 984 : ''); 985 } 986 // Detect Kubuntu. 987 else if (name == 'Konqueror' && !/buntu/i.test(os)) { 988 os = 'Kubuntu'; 989 } 990 // Detect Android browsers. 991 else if ((manufacturer && manufacturer != 'Google' && 992 ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || 993 (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { 994 name = 'Android Browser'; 995 os = /\bAndroid\b/.test(os) ? os : 'Android'; 996 } 997 // Detect Silk desktop/accelerated modes. 998 else if (name == 'Silk') { 999 if (!/\bMobi/i.test(ua)) { 1000 os = 'Android'; 1001 description.unshift('desktop mode'); 1002 } 1003 if (/Accelerated *= *true/i.test(ua)) { 1004 description.unshift('accelerated'); 1005 } 1006 } 1007 // Detect PaleMoon identifying as Firefox. 1008 else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { 1009 description.push('identifying as Firefox ' + data[1]); 1010 } 1011 // Detect Firefox OS and products running Firefox. 1012 else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { 1013 os || (os = 'Firefox OS'); 1014 product || (product = data[1]); 1015 } 1016 // Detect false positives for Firefox/Safari. 1017 else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { 1018 // Escape the `/` for Firefox 1. 1019 if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { 1020 // Clear name of false positives. 1021 name = null; 1022 } 1023 // Reassign a generic name. 1024 if ((data = product || manufacturer || os) && 1025 (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { 1026 name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; 1027 } 1028 } 1029 // Add Chrome version to description for Electron.
vendor: 6,712 bytes, lines 1030-1196
1030 else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { 1031 description.push('Chromium ' + data); 1032 } 1033 // Detect non-Opera (Presto-based) versions (order is important). 1034 if (!version) { 1035 version = getVersion([ 1036 '(?:Cloud9|CriOS|CrMo|Edge|Edg|EdgA|EdgiOS|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', 1037 'Version', 1038 qualify(name), 1039 '(?:Firefox|Minefield|NetFront)' 1040 ]); 1041 } 1042 // Detect stubborn layout engines. 1043 if ((data = 1044 layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || 1045 /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || 1046 /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || 1047 !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || 1048 layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' 1049 )) { 1050 layout = [data]; 1051 } 1052 // Detect Windows Phone 7 desktop mode. 1053 if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { 1054 name += ' Mobile'; 1055 os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); 1056 description.unshift('desktop mode'); 1057 } 1058 // Detect Windows Phone 8.x desktop mode. 1059 else if (/\bWPDesktop\b/i.test(ua)) { 1060 name = 'IE Mobile'; 1061 os = 'Windows Phone 8.x'; 1062 description.unshift('desktop mode'); 1063 version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); 1064 } 1065 // Detect IE 11 identifying as other browsers. 1066 else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { 1067 if (name) { 1068 description.push('identifying as ' + name + (version ? ' ' + version : '')); 1069 } 1070 name = 'IE'; 1071 version = data[1]; 1072 } 1073 // Leverage environment features. 1074 if (useFeatures) { 1075 // Detect server-side environments. 1076 // Rhino has a global function while others have a global object. 1077 if (isHostType(context, 'global')) { 1078 if (java) { 1079 data = java.lang.System; 1080 arch = data.getProperty('os.arch'); 1081 os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); 1082 } 1083 if (rhino) { 1084 try { 1085 version = context.require('ringo/engine').version.join('.'); 1086 name = 'RingoJS'; 1087 } catch(e) { 1088 if ((data = context.system) && data.global.system == context.system) { 1089 name = 'Narwhal'; 1090 os || (os = data[0].os || null); 1091 } 1092 } 1093 if (!name) { 1094 name = 'Rhino'; 1095 } 1096 } 1097 else if ( 1098 typeof context.process == 'object' && !context.process.browser && 1099 (data = context.process) 1100 ) { 1101 if (typeof data.versions == 'object') { 1102 if (typeof data.versions.electron == 'string') { 1103 description.push('Node ' + data.versions.node); 1104 name = 'Electron'; 1105 version = data.versions.electron; 1106 } else if (typeof data.versions.nw == 'string') { 1107 description.push('Chromium ' + version, 'Node ' + data.versions.node); 1108 name = 'NW.js'; 1109 version = data.versions.nw; 1110 } 1111 } 1112 if (!name) { 1113 name = 'Node.js'; 1114 arch = data.arch; 1115 os = data.platform; 1116 version = /[\d.]+/.exec(data.version); 1117 version = version ? version[0] : null; 1118 } 1119 } 1120 } 1121 // Detect Adobe AIR. 1122 else if (getClassOf((data = context.runtime)) == airRuntimeClass) { 1123 name = 'Adobe AIR'; 1124 os = data.flash.system.Capabilities.os; 1125 } 1126 // Detect PhantomJS. 1127 else if (getClassOf((data = context.phantom)) == phantomClass) { 1128 name = 'PhantomJS'; 1129 version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); 1130 } 1131 // Detect IE compatibility modes. 1132 else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { 1133 // We're in compatibility mode when the Trident version + 4 doesn't 1134 // equal the document mode. 1135 version = [version, doc.documentMode]; 1136 if ((data = +data[1] + 4) != version[1]) { 1137 description.push('IE ' + version[1] + ' mode'); 1138 layout && (layout[1] = ''); 1139 version[1] = data; 1140 } 1141 version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; 1142 } 1143 // Detect IE 11 masking as other browsers. 1144 else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { 1145 description.push('masking as ' + name + ' ' + version); 1146 name = 'IE'; 1147 version = '11.0'; 1148 layout = ['Trident']; 1149 os = 'Windows'; 1150 } 1151 os = os && format(os); 1152 } 1153 // Detect prerelease phases. 1154 if (version && (data = 1155 /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || 1156 /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || 1157 /\bMinefield\b/i.test(ua) && 'a' 1158 )) { 1159 prerelease = /b/i.test(data) ? 'beta' : 'alpha'; 1160 version = version.replace(RegExp(data + '\\+?$'), '') + 1161 (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); 1162 } 1163 // Detect Firefox Mobile. 1164 if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { 1165 name = 'Firefox Mobile'; 1166 } 1167 // Obscure Maxthon's unreliable version. 1168 else if (name == 'Maxthon' && version) { 1169 version = version.replace(/\.[\d.]+/, '.x'); 1170 } 1171 // Detect Xbox 360 and Xbox One. 1172 else if (/\bXbox\b/i.test(product)) { 1173 if (product == 'Xbox 360') { 1174 os = null; 1175 } 1176 if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { 1177 description.unshift('mobile mode'); 1178 } 1179 } 1180 // Add mobile postfix. 1181 else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && 1182 (os == 'Windows CE' || /Mobi/i.test(ua))) { 1183 name += ' Mobile'; 1184 } 1185 // Detect IE platform preview. 1186 else if (name == 'IE' && useFeatures) { 1187 try { 1188 if (context.external === null) { 1189 description.unshift('platform preview'); 1190 } 1191 } catch(e) { 1192 description.unshift('embedded'); 1193 } 1194 } 1195 // Detect BlackBerry OS version. 1196 // http://docs.blackberry.com/en/developers/deliverables/18169/
vendor: 5,386 bytes, lines 1196-1312
1196HTTP_headers_sent_by_BB_Browser_1234911_11.jsp 1197 else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = 1198 (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || 1199 version 1200 )) { 1201 data = [data, /BB10/.test(ua)]; 1202 os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; 1203 version = null; 1204 } 1205 // Detect Opera identifying/masking itself as another browser. 1206 // http://www.opera.com/support/kb/view/843/ 1207 else if (this != forOwn && product != 'Wii' && ( 1208 (useFeatures && opera) || 1209 (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || 1210 (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || 1211 (name == 'IE' && ( 1212 (os && !/^Win/.test(os) && version > 5.5) || 1213 /\bWindows XP\b/.test(os) && version > 8 || 1214 version == 8 && !/\bTrident\b/.test(ua) 1215 )) 1216 ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { 1217 // When "identifying", the UA contains both Opera and the other browser's name. 1218 data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); 1219 if (reOpera.test(name)) { 1220 if (/\bIE\b/.test(data) && os == 'Mac OS') { 1221 os = null; 1222 } 1223 data = 'identify' + data; 1224 } 1225 // When "masking", the UA contains only the other browser's name. 1226 else { 1227 data = 'mask' + data; 1228 if (operaClass) { 1229 name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); 1230 } else { 1231 name = 'Opera'; 1232 } 1233 if (/\bIE\b/.test(data)) { 1234 os = null; 1235 } 1236 if (!useFeatures) { 1237 version = null; 1238 } 1239 } 1240 layout = ['Presto']; 1241 description.push(data); 1242 } 1243 // Detect WebKit Nightly and approximate Chrome/Safari versions. 1244 if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { 1245 // Correct build number for numeric comparison. 1246 // (e.g. "532.5" becomes "532.05") 1247 data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; 1248 // Nightly builds are postfixed with a "+". 1249 if (name == 'Safari' && data[1].slice(-1) == '+') { 1250 name = 'WebKit Nightly'; 1251 prerelease = 'alpha'; 1252 version = data[1].slice(0, -1); 1253 } 1254 // Clear incorrect browser versions. 1255 else if (version == data[1] || 1256 version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { 1257 version = null; 1258 } 1259 // Use the full Chrome version when available. 1260 data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; 1261 // Detect Blink layout engine. 1262 if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { 1263 layout = ['Blink']; 1264 } 1265 // Detect JavaScriptCore. 1266 // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi 1267 if (!useFeatures || (!likeChrome && !data[1])) { 1268 layout && (layout[1] = 'like Safari'); 1269 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'); 1270 } else { 1271 layout && (layout[1] = 'like Chrome'); 1272 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'); 1273 } 1274 // Add the postfix of ".x" or "+" for approximate versions. 1275 layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); 1276 // Obscure version for some Safari 1-2 releases. 1277 if (name == 'Safari' && (!version || parseInt(version) > 45)) { 1278 version = data; 1279 } 1280 } 1281 // Detect Opera desktop modes. 1282 if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { 1283 name += ' '; 1284 description.unshift('desktop mode'); 1285 if (data == 'zvav') { 1286 name += 'Mini'; 1287 version = null; 1288 } else { 1289 name += 'Mobile'; 1290 } 1291 os = os.replace(RegExp(' *' + data + '$'), ''); 1292 } 1293 // Detect Chrome desktop mode. 1294 else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { 1295 description.unshift('desktop mode'); 1296 name = 'Chrome Mobile'; 1297 version = null; 1298 1299 if (/\bOS X\b/.test(os)) { 1300 manufacturer = 'Apple'; 1301 os = 'iOS 4.3+'; 1302 } else { 1303 os = null; 1304 } 1305 } 1306 // Strip incorrect OS versions. 1307 if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && 1308 ua.indexOf('/' + data + '-') > -1) { 1309 os = trim(os.replace(data, '')); 1310 } 1311 // Add layout engine. 1312 if (layout && !/\b(?:Avant|Nook)\b/.test(name) && (
vendor: 9,088 bytes, lines 1313-1596
1313 /Browser|Lunascape|Maxthon/.test(name) || 1314 name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || 1315 /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { 1316 // Don't add layout details to description if they are falsey. 1317 (data = layout[layout.length - 1]) && description.push(data); 1318 } 1319 // Combine contextual information. 1320 if (description.length) { 1321 description = ['(' + description.join('; ') + ')']; 1322 } 1323 // Append manufacturer to description. 1324 if (manufacturer && product && product.indexOf(manufacturer) < 0) { 1325 description.push('on ' + manufacturer); 1326 } 1327 // Append product to description. 1328 if (product) { 1329 description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); 1330 } 1331 // Parse the OS into an object. 1332 if (os) { 1333 data = / ([\d.+]+)$/.exec(os); 1334 isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; 1335 os = { 1336 'architecture': 32, 1337 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, 1338 'version': data ? data[1] : null, 1339 'toString': function() { 1340 var version = this.version; 1341 return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); 1342 } 1343 }; 1344 } 1345 // Add browser/OS architecture. 1346 if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { 1347 if (os) { 1348 os.architecture = 64; 1349 os.family = os.family.replace(RegExp(' *' + data), ''); 1350 } 1351 if ( 1352 name && (/\bWOW64\b/i.test(ua) || 1353 (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) 1354 ) { 1355 description.unshift('32-bit'); 1356 } 1357 } 1358 // Chrome 39 and above on OS X is always 64-bit. 1359 else if ( 1360 os && /^OS X/.test(os.family) && 1361 name == 'Chrome' && parseFloat(version) >= 39 1362 ) { 1363 os.architecture = 64; 1364 } 1365 1366 ua || (ua = null); 1367 1368 /*------------------------------------------------------------------------*/ 1369 1370 /** 1371 * The platform object. 1372 * 1373 * @name platform 1374 * @type Object 1375 */ 1376 var platform = {}; 1377 1378 /** 1379 * The platform description. 1380 * 1381 * @memberOf platform 1382 * @type string|null 1383 */ 1384 platform.description = ua; 1385 1386 /** 1387 * The name of the browser's layout engine. 1388 * 1389 * The list of common layout engines include: 1390 * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" 1391 * 1392 * @memberOf platform 1393 * @type string|null 1394 */ 1395 platform.layout = layout && layout[0]; 1396 1397 /** 1398 * The name of the product's manufacturer. 1399 * 1400 * The list of manufacturers include: 1401 * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", 1402 * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", 1403 * "Nokia", "Samsung" and "Sony" 1404 * 1405 * @memberOf platform 1406 * @type string|null 1407 */ 1408 platform.manufacturer = manufacturer; 1409 1410 /** 1411 * The name of the browser/environment. 1412 * 1413 * The list of common browser names include: 1414 * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", 1415 * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", 1416 * "Opera Mini" and "Opera" 1417 * 1418 * Mobile versions of some browsers have "Mobile" appended to their name: 1419 * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" 1420 * 1421 * @memberOf platform 1422 * @type string|null 1423 */ 1424 platform.name = name; 1425 1426 /** 1427 * The alpha/beta release indicator. 1428 * 1429 * @memberOf platform 1430 * @type string|null 1431 */ 1432 platform.prerelease = prerelease; 1433 1434 /** 1435 * The name of the product hosting the browser. 1436 * 1437 * The list of common products include: 1438 * 1439 * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", 1440 * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" 1441 * 1442 * @memberOf platform 1443 * @type string|null 1444 */ 1445 platform.product = product; 1446 1447 /** 1448 * The browser's user agent string. 1449 * 1450 * @memberOf platform 1451 * @type string|null 1452 */ 1453 platform.ua = ua; 1454 1455 /** 1456 * The browser/environment version. 1457 * 1458 * @memberOf platform 1459 * @type string|null 1460 */ 1461 platform.version = name && version; 1462 1463 /** 1464 * The name of the operating system. 1465 * 1466 * @memberOf platform 1467 * @type Object 1468 */ 1469 platform.os = os || { 1470 1471 /** 1472 * The CPU architecture the OS is built for. 1473 * 1474 * @memberOf platform.os 1475 * @type number|null 1476 */ 1477 'architecture': null, 1478 1479 /** 1480 * The family of the OS. 1481 * 1482 * Common values include: 1483 * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", 1484 * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", 1485 * "Android", "iOS" and "Windows Phone" 1486 * 1487 * @memberOf platform.os 1488 * @type string|null 1489 */ 1490 'family': null, 1491 1492 /** 1493 * The version of the OS. 1494 * 1495 * @memberOf platform.os 1496 * @type string|null 1497 */ 1498 'version': null, 1499 1500 /** 1501 * Returns the OS string. 1502 * 1503 * @memberOf platform.os 1504 * @returns {string} The OS string. 1505 */ 1506 'toString': function() { return 'null'; } 1507 }; 1508 1509 platform.parse = parse; 1510 platform.toString = toStringPlatform; 1511 1512 if (platform.version) { 1513 description.unshift(version); 1514 } 1515 if (platform.name) { 1516 description.unshift(name); 1517 } 1518 if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { 1519 description.push(product ? '(' + os + ')' : 'on ' + os); 1520 } 1521 if (description.length) { 1522 platform.description = description.join(' '); 1523 } 1524 return platform; 1525 } 1526 1527 /*--------------------------------------------------------------------------*/ 1528 1529 // Export platform. 1530 var platform = parse(); 1531 1532 // Some AMD build optimizers, like r.js, check for condition patterns like the following: 1533 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { 1534 // Expose platform on the global object to prevent errors when platform is 1535 // loaded by a script tag in the presence of an AMD loader. 1536 // See http://requirejs.org/docs/errors.html#mismatch for more details. 1537 root.platform = platform; 1538 1539 // Define as an anonymous module so platform can be aliased through path mapping. 1540 define(function() { 1541 return platform; 1542 }); 1543 } 1544 // Check for `exports` after `define` in case a build optimizer adds an `exports` object. 1545 else if (freeExports && freeModule) { 1546 // Export for CommonJS support. 1547 forOwn(platform, function(value, key) { 1548 freeExports[key] = value; 1549 }); 1550 } 1551 else { 1552 // Export to the global object. 1553 root.platform = platform; 1554 } 1555}.call(this)); 1556 1557// 1558// +----------------------------------------------------------------------+ 1559// | Unobtrusive Javascript Validation for YUI v2.0 (2007-03-04) | 1560// | http://blog.jc21.com | 1561// +----------------------------------------------------------------------+ 1562// | Attaches Events to all forms on a page and checks their form | 1563// | elements classes to provide some validation. | 1564// +----------------------------------------------------------------------+ 1565// | Copyright: jc21.com 2008 | 1566// +----------------------------------------------------------------------+ 1567// | Licence: Absolutely free. Don't mention it. | 1568// +----------------------------------------------------------------------+ 1569// | Author: Jamie Curnow <[email protected]> | 1570// +----------------------------------------------------------------------+ 1571// 1572// 1573 1574 1575 1576//================================================================================================================== 1577// Trim Whitespace 1578//------------------------------------------------------------------------------------------------------------------ 1579String.prototype.trim=function(){ 1580 return this.replace(/^\s*|\s*$/g,''); 1581} 1582String.prototype.ltrim=function(){ 1583 return this.replace(/^\s*/g,''); 1584} 1585String.prototype.rtrim=function(){ 1586 return this.replace(/\s*$/g,''); 1587} 1588 1589//================================================================================================================== 1590// FIC_checkForm 1591// Form Input Checking by JC 1592/* 1593 Apply these class names to form elements: 1594 1595 * required (not blank) 1596 * validate-number (a valid number)
1597 * validate-digits (digits only, spaces allowed.) 1598 * validate-alpha (letters only) 1599 * validate-alphanum (only letters and numbers) 1600 * validate-date (a valid date value) 1601 * validate-email (a valid email address) 1602 * validate-url (a valid URL) 1603 * validate-date-au (a date formatted as; dd/mm/yyyy) 1604 * validate-currency-dollar (a valid dollar value) 1605 * validate-one-required (At least one checkbox/radio element must be selected in a group) 1606 * validate-not-first (Selects only, must choose an option other than the first) 1607 * validate-not-empty (Selects only, must choose an option with a value that is not empty) 1608 * validate-regex (requires the element to have a 'regex=' attribute applied) 1609 1610 Also, you can specify this attribute for text, passwird and textarea elements: 1611 * minlength="x" (where x is the minimum number of characters) 1612*/ 1613//------------------------------------------------------------------------------------------------------------------ 1614function FIC_checkForm(e) { 1615 var errs = new Array(); 1616 1617 //this function is called when a form is submitted. 1618 if (typeof(e) == "string") { 1619 //the id was supplied, get the object reference 1620 e = xGetElementById(e); 1621 if (!e) { 1622 return true; 1623 } 1624 } 1625 1626 var elm=e; 1627 if (!e.nodeName) { 1628 //was fired by yahoo 1629 elm = (e.srcElement) ? e.srcElement : e.target; 1630 } 1631 if (elm.nodeName.toLowerCase() != 'form') { 1632 elm = searchUp(elm,'form'); 1633 } 1634 1635 var all_valid = true; 1636 1637 //access form elements 1638 //inputs 1639 var f_in = elm.getElementsByTagName('input'); 1640 //selects 1641 var f_sl = elm.getElementsByTagName('select'); 1642 //textareas 1643 var f_ta = elm.getElementsByTagName('textarea'); 1644 1645 //check inputs 1646 for (i=0;i<f_in.length;i++) { 1647 if (f_in[i].type.toLowerCase() != 'submit' && f_in[i].type.toLowerCase() != 'button' && f_in[i].type.toLowerCase() != 'hidden') { 1648 if (isVisible(f_in[i])) { 1649 var cname = ' '+f_in[i].className.replace(/^\s*|\s*$/g,'')+' '; 1650 cname = cname.toLowerCase(); 1651 alert(cname); 1652 var inv = f_in[i].value.trim(); 1653 var t = f_in[i].type.toLowerCase(); 1654 var cext = ''; 1655 if (t == 'text' || t == 'password') { 1656 //text box 1657 var valid = FIC_checkField(cname,f_in[i]); 1658 } else if(t == 'radio' || t == 'checkbox'){ 1659 // radio or checkbox 1660 var valid = FIC_checkRadCbx(cname,f_in[i],f_in); 1661 cext = '-cr'; 1662 } else { 1663 var valid = true; 1664 } 1665 1666 if (valid) { 1667 removeClassName(f_in[i],'validation-failed'+cext); 1668 addClassName(f_in[i],'validation-passed'+cext); 1669 } else { 1670 removeClassName(f_in[i],'validation-passed'+cext); 1671 addClassName(f_in[i],'validation-failed'+cext); 1672 //try to get title 1673 if (f_in[i].getAttribute('title')){ 1674 errs[errs.length] = f_in[i].getAttribute('title'); 1675 } 1676 all_valid = false; 1677 } 1678 } 1679 } 1680 } //end for i 1681 1682 //check textareas 1683 for (i=0;i<f_ta.length;i++) { 1684 if (isVisible(f_ta[i])) { 1685 var cname = ' '+f_ta[i].className.replace(/^\s*|\s*$/g,'')+' '; 1686 cname = cname.toLowerCase(); 1687 var valid = FIC_checkField(cname,f_ta[i]); 1688 1689 if (valid) { 1690 removeClassName(f_ta[i],'validation-failed'); 1691 addClassName(f_ta[i],'validation-passed'); 1692 } else { 1693 removeClassName(f_ta[i],'validation-passed'); 1694 addClassName(f_ta[i],'validation-failed'); 1695 //try to get title 1696 if (f_ta[i].getAttribute('title')){ 1697 errs[errs.length] = f_ta[i].getAttribute('title'); 1698 } 1699 all_valid = false; 1700 } 1701 } 1702 } //end for i 1703 1704 //check selects 1705 for (i=0;i<f_sl.length;i++) { 1706 if (isVisible(f_sl[i])) { 1707 var cname = ' '+f_sl[i].className.replace(/^\s*|\s*$/g,'')+' '; 1708 cname = cname.toLowerCase(); 1709 var valid = FIC_checkSel(cname,f_sl[i]); 1710 if (valid) { 1711 removeClassName(f_sl[i],'validation-failed-sel'); 1712 addClassName(f_sl[i],'validation-passed-sel'); 1713 } else { 1714 removeClassName(f_sl[i],'validation-passed-sel'); 1715 addClassName(f_sl[i],'validation-failed-sel'); 1716 //try to get title 1717 if (f_sl[i].getAttribute('title')){ 1718 errs[errs.length] = f_sl[i].getAttribute('title'); 1719 } 1720 all_valid = false; 1721 } 1722 } 1723 } //end for i 1724
1725 if (!all_valid) { 1726 if (errs.length > 0){ 1727 alert("We have found the following error(s):\n\n * "+errs.join("\n * ")+"\n\nPlease check the fields and try again"); 1728 } else { 1729 alert('Some required values are not correct. Please check the items in red.'); 1730 } 1731 1732 e.preventDefault(); 1733 e.stopPropagation(); 1734 1735 } 1736 return all_valid; 1737} // end FIC_checkForm 1738 1739//================================================================================================================== 1740// FIC_checkField 1741// c = className 1742// e = the element 1743//------------------------------------------------------------------------------------------------------------------ 1744function FIC_checkField(c,e) { 1745 var valid = true; 1746 var t = e.value.trim(); 1747 1748 //search for required 1749 if (c.indexOf(' required ') != -1 && t.length == 0) { 1750 //required found, and not filled in 1751 valid = false; 1752 } 1753 1754 //check length 1755 if (c.indexOf(' required ') != -1){ 1756 //check for minlength. 1757 var m = e.getAttribute('minlength'); 1758 if (m && Math.abs(m) > 0){ 1759 if (e.value.length < Math.abs(m)){ 1760 valid = false; 1761 } 1762 } 1763 } 1764 1765 //search for validate- 1766 if (c.indexOf(' validate-number ') != -1 && isNaN(t) && t.match(/[^\d]/)) { 1767 //number bad 1768 valid = false; 1769 } else if (c.indexOf(' validate-digits ') != -1 && t.replace(/ /,'').match(/[^\d]/)) { 1770 //digit bad 1771 valid = false; 1772 } else if (c.indexOf(' validate-alpha ') != -1 && !t.match(/^[a-zA-Z]+$/)) { 1773 //alpha bad 1774 valid = false; 1775 } else if (c.indexOf(' validate-alphanum ') != -1 && t.match(/\W/)) { 1776 //alpha bad 1777 valid = false; 1778 } else if (c.indexOf(' validate-date ') != -1) { 1779 var d = new date(t); 1780 if (isNaN(d)) { 1781 //date bad 1782 valid = false; 1783 } 1784 } else if (c.indexOf(' validate-email ') != -1 && !t.match(/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/)) { 1785 //email bad 1786 valid = false; 1787 if (c.indexOf(' required ') == -1 && t.length == 0) { 1788 valid = true; 1789 } 1790 } else if (c.indexOf(' validate-url ') != -1 && !t.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) { 1791 //url bad 1792 valid = false; 1793 } else if (c.indexOf(' validate-date-au ') != -1 && !t.match(/^(\d{2})\/(\d{2})\/(\d{4})$/)) { 1794 valid = false; 1795// } else if (c.indexOf(' validate-currency-dollar ') != -1 && !t.match(/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/)) { 1796 } else if (c.indexOf(' validate-currency-dollar ') != -1 && 1797 (!t.match(/(^(0|[1-9][0-9]*)$)|((^(0?|[1-9][0-9]*)\.(0*[1-9][0-9]*)$)|(^[1-9]+[0-9]*\.0+$)|(^0\.0+$))/) || 1798 t.length && 0)) { 1799 valid = false; 1800 } else if (c.indexOf(' validate-regex ') != -1) { 1801 var r = RegExp(e.getAttribute('regex')); 1802 if (r && ! t.match(r)) { 1803 valid = false; 1804 } 1805 } 1806 1807 return valid; 1808} 1809 1810//================================================================================================================== 1811// FIC_checkRadCbx 1812// c = className 1813// e = this element, radio or checkbox 1814// f = input fields dom element 1815//------------------------------------------------------------------------------------------------------------------ 1816function FIC_checkRadCbx(c,e,f){ 1817 var valid = true; 1818 1819 //search for required 1820 if (c.indexOf(' validate-one-required ') != -1) { 1821 //required found 1822 //check if other checkboxes or radios have been selected. 1823 valid = false; 1824 for (var i=0;i<f.length;i++){ 1825 if(f[i].name.toLowerCase() == e.name.toLowerCase() && f[i].checked){ 1826 valid = true; 1827 break; 1828 } 1829 } 1830 } 1831 1832 return valid; 1833} 1834 1835//================================================================================================================== 1836// FIC_checkSel 1837// c = className 1838// e = this select element 1839//------------------------------------------------------------------------------------------------------------------ 1840function FIC_checkSel(c,e){ 1841 var valid = true; 1842 //search for validate- 1843 if (c.indexOf(' validate-not-first ') != -1 && e.selectedIndex == 0) { 1844 //bad 1845 valid = false; 1846 } else if (c.indexOf(' validate-not-empty ') != -1 && e.options[e.selectedIndex].value.length == 0) { 1847 //bad 1848 valid = false; 1849 } 1850 return valid; 1851} 1852 1853//================================================================================================================== 1854// addClassName 1855//------------------------------------------------------------------------------------------------------------------ 1856function addClassName(e,t) { 1857 if (typeof e == "string") { 1858 e = xGetElementById(e); 1859 } 1860 //code to change and replace strings 1861 var ec = ' ' + e.className.replace(/^\s*|\s*$/g,'') + ' '; 1862 var nc = ec; 1863 t = t.replace(/^\s*|\s*$/g,''); 1864 //check if not already there 1865 if (ec.indexOf(' '+t+' ') == -1) { 1866 //not found, add it 1867 nc = ec + t; 1868 } 1869 //return the changed text! 1870 e.className = nc.replace(/^\s*|\s*$/g,''); //trimmed whitespace 1871 return true; 1872} 1873 1874//================================================================================================================== 1875// removeClassName 1876//------------------------------------------------------------------------------------------------------------------ 1877function removeClassName(e,t) { 1878 if (typeof e == "string") { 1879 e = xGetElementById(e); 1880 } 1881 //code to change and replace strings 1882 var ec = ' ' + e.className.replace(/^\s*|\s*$/g,'') + ' '; 1883 var nc = ec; 1884 t = t.replace(/^\s*|\s*$/g,''); 1885 //check if not already there 1886 if (ec.indexOf(' '+t+' ') != -1) { 1887 //found, so lets remove it 1888 nc = ec.replace(' ' + t.replace(/^\s*|\s*$/g,'') + ' ',' '); 1889 } 1890 //return the changed text! 1891 e.className = nc.replace(/^\s*|\s*$/g,''); //trimmed whitespace 1892 return true; 1893} 1894 1895//================================================================================================================== 1896// attachToForms 1897//------------------------------------------------------------------------------------------------------------------ 1898function attachToForms(e) { 1899 //search dom for all forms 1900 var frms = document.getElementsByTagName('form'); 1901 for(var i=0;i<frms.length;i++) { 1902 //YAHOO.util.Event.addListener(frms[i], "submit", FIC_checkForm); 1903 if(frms[i].addEventListener){ 1904 frms[i].addEventListener("submit", FIC_checkForm, false); //Modern browsers 1905 }else if(frms[i].attachEvent){ 1906 frms[i].attachEvent('onsubmit', FIC_checkForm); //Old IE 1907 } 1908 } 1909} 1910 1911//================================================================================================================== 1912// isVisible 1913//------------------------------------------------------------------------------------------------------------------ 1914function isVisible(e) { 1915 //returns true is should be visible to user. 1916 if (typeof e == "string") { 1917 e = xGetElementById(e); 1918 } 1919 while (e.nodeName.toLowerCase() != 'body' && e.style.display.toLowerCase() != 'none' && e.style.visibility.toLowerCase() != 'hidden') { 1920 e = e.parentNode; 1921 } 1922 if (e.nodeName.toLowerCase() == 'body') { 1923 return true; 1924 } else{ 1925 return false; 1926 } 1927} 1928 1929 1930//================================================================================================================== 1931// searchUp 1932//------------------------------------------------------------------------------------------------------------------ 1933function searchUp(elm,findElm,debug) { 1934 //this function searches the dom tree upwards for the findElm node starting from elm. 1935 //check if elm is reference 1936 1937 if(typeof(elm) == 'string') { 1938 elm = xGetElementById(elm); 1939 } 1940 //search up 1941 //get the parent findElm 1942 while (elm && elm.parentNode && elm.nodeName.toLowerCase() != findElm && elm.nodeName.toLowerCase() != 'body') { 1943 elm = elm.parentNode; 1944 } 1945 return elm; 1946} 1947 1948//================================================================================================================== 1949// xGetElementById 1950//------------------------------------------------------------------------------------------------------------------ 1951function xGetElementById(e) { 1952 if(typeof(e)!='string') return e; 1953 if(document.getElementById) e=document.getElementById(e); 1954 else if(document.all) e=document.all[e]; 1955 else e=null; 1956 return e; 1957} 1958 1959//YAHOO.util.Event.addListener(window, "load", attachToForms); 1960 1961 1962//================================================================================================================== 1963// TO HIDE THE LANGUAGE CONVERSION OPTION IN A PAGE 1964//------------------------------------------------------------------------------------------------------------------ 1965 1966function fnHideLangConversion() { 1967 $("[href*='/c/portal/update_language']").parent().hide().next(":contains(|)").hide(); 1968 $('[name="changeLanguageLink"]').parent().hide().next(":contains(|)").hide(); 1969} 1970 1971//================================================================================ 1972//----------------------------------------------------------------------------------
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.