1// SpryValidationPassword.js - version 0.4 - Spry Pre-Release 1.6.1 2// 3// Copyright (c) 2006. Adobe Systems Incorporated. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are met: 8// 9// * Redistributions of source code must retain the above copyright notice, 10// this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above copyright notice, 12// this list of conditions and the following disclaimer in the documentation 13// and/or other materials provided with the distribution. 14// * Neither the name of Adobe Systems Incorporated nor the names of its 15// contributors may be used to endorse or promote products derived from this 16// software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28// POSSIBILITY OF SUCH DAMAGE. 29 30(function() { // BeginSpryComponent 31 32if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {}; 33 34Spry.Widget.BrowserSniff = function() 35{ 36 var b = navigator.appName.toString(); 37 var up = navigator.platform.toString(); 38 var ua = navigator.userAgent.toString(); 39 40 this.mozilla = this.ie = this.opera = this.safari = false; 41 var re_opera = /Opera.([0-9\.]*)/i; 42 var re_msie = /MSIE.([0-9\.]*)/i; 43 var re_gecko = /gecko/i; 44 var re_safari = /(applewebkit|safari)\/([\d\.]*)/i; 45 var r = false; 46 47 if ( (r = ua.match(re_opera))) { 48 this.opera = true; 49 this.version = parseFloat(r[1]); 50 } else if ( (r = ua.match(re_msie))) { 51 this.ie = true; 52 this.version = parseFloat(r[1]); 53 } else if ( (r = ua.match(re_safari))) { 54 this.safari = true; 55 this.version = parseFloat(r[2]); 56 } else if (ua.match(re_gecko)) { 57 var re_gecko_version = /rv:\s*([0-9\.]+)/i; 58 r = ua.match(re_gecko_version); 59 this.mozilla = true; 60 this.version = parseFloat(r[1]); 61 } 62 this.windows = this.mac = this.linux = false; 63 64 this.Platform = ua.match(/windows/i) ? "windows" : 65 (ua.match(/linux/i) ? "linux" : 66 (ua.match(/mac/i) ? "mac" : 67 ua.match(/unix/i)? "unix" : "unknown")); 68 this[this.Platform] = true; 69 this.v = this.version; 70 71 if (this.safari && this.mac && this.mozilla) { 72 this.mozilla = false; 73 } 74}; 75 76Spry.is = new Spry.Widget.BrowserSniff(); 77 78Spry.Widget.ValidationPassword = function(element, options) 79{ 80 options = Spry.Widget.Utils.firstValid(options, {}); 81 82 if (!this.isBrowserSupported()) 83 return; 84 85 if (this.init(element, options) === false) 86 return false; 87 88 var validateOn = ['submit'].concat(Spry.Widget.Utils.firstValid(this.options.validateOn, [])); 89 validateOn = validateOn.join(","); 90 91 this.validateOn = 0; 92 this.validateOn = this.validateOn | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationPassword.ONSUBMIT : 0); 93 this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationPassword.ONBLUR : 0); 94 this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationPassword.ONCHANGE : 0); 95 96 if (Spry.Widget.ValidationPassword.onloadDidFire) 97 this.attachBehaviors(); 98 else 99 Spry.Widget.ValidationPassword.loadQueue.push(this); 100}; 101 102Spry.Widget.ValidationPassword.ONCHANGE = 1; 103Spry.Widget.ValidationPassword.ONBLUR = 2; 104Spry.Widget.ValidationPassword.ONSUBMIT = 4; 105 106Spry.Widget.ValidationPassword.prototype.init = function(element, options) 107{ 108 options = Spry.Widget.Utils.firstValid(options, []); 109 this.options = []; 110 this.element = this.getElement(element); 111 if (!this.element) 112 { 113 return false;
114 } 115 else 116 { 117 if (this.element.nodeName.toUpperCase() == 'INPUT' && typeof this.element.type != 'undefined' && this.element.type.toUpperCase() == 'PASSWORD') 118 { 119 this.input = this.element; 120 } 121 else 122 { 123 var inputs = Spry.Widget.Utils.getValidChildrenWithNodeNameAtAnyLevel(this.element, 'INPUT', 'PASSWORD'); 124 if (inputs && inputs.length > 0) 125 this.input = inputs[0]; 126 else { 127 var inputs = Spry.Widget.Utils.getValidChildrenWithNodeNameAtAnyLevel(this.element, 'INPUT', 'TEXT'); 128 if (inputs && inputs.length > 0) 129 this.input = inputs[0]; 130 else 131 this.input = false; 132 } 133 } 134 } 135 if (!this.input) 136 return false; 137 138 this.event_handlers = []; 139 140 this.validClass = "passwordValidState"; 141 this.focusClass = "passwordFocusState"; 142 this.requiredClass = "passwordRequiredState"; 143 this.invalidStrengthClass = "passwordInvalidStrengthState"; 144 this.invalidCharsMinClass = "passwordMinCharsState"; 145 this.invalidCharsMaxClass = "passwordMaxCharsState"; 146 this.invalidCustomClass = "passwordCustomState"; 147 148 options.isRequired = Spry.Widget.Utils.firstValid(options.isRequired, true); 149 150 options.additionalError = Spry.Widget.Utils.firstValid(options.additionalError, false); 151 if (options.additionalError) 152 options.additionalError = this.getElement(options.additionalError); 153 154 var getRealValue = Spry.Widget.Utils.getOptionRealValue; 155 options.minChars = getRealValue(options.minChars, false); 156 options.maxChars = getRealValue(options.maxChars, false); 157 // copy the default textfield behavior 158 if (options.maxChars) 159 this.input.removeAttribute("maxLength"); 160 161 options.minAlphaChars = getRealValue(options.minAlphaChars, false); 162 options.maxAlphaChars = getRealValue(options.maxAlphaChars, false); 163 options.minUpperAlphaChars = getRealValue(options.minUpperAlphaChars, false); 164 options.maxUpperAlphaChars = getRealValue(options.maxUpperAlphaChars, false); 165 options.minSpecialChars = getRealValue(options.minSpecialChars, false); 166 options.maxSpecialChars = getRealValue(options.maxSpecialChars, false); 167 options.minNumbers = getRealValue(options.minNumbers, false); 168 options.maxNumbers = getRealValue(options.maxNumbers, false); 169 170 if ((options.minAlphaChars !== false && options.maxAlphaChars !== false && options.minAlphaChars > options.maxAlphaChars) || 171 (options.minUpperAlphaChars !== false && options.maxUpperAlphaChars !== false && options.minUpperAlphaChars > options.maxUpperAlphaChars) || 172 (options.minSpecialChars !== false && options.maxSpecialChars !== false && options.minSpecialChars > options.maxSpecialChars) || 173 (options.minNumbers !== false && options.maxNumbers !== false && options.minNumbers > options.maxNumbers) || 174 (options.maxUpperAlphaChars !== false && options.maxAlphaChars !== false && options.maxUpperAlphaChars > options.maxAlphaChars) || 175 (options.maxChars !== false && options.minAlphaChars + options.minUpperAlphaChars + options.minSpecialChars + options.minNumbers > options.maxChars) 176 ) 177 { 178 this.showError('Invalid Strength Options!'); 179 return false; 180 } 181 182 Spry.Widget.Utils.setOptions(this, options); 183 Spry.Widget.Utils.setOptions(this.options, options); 184}; 185 186Spry.Widget.ValidationPassword.loadQueue = []; 187Spry.Widget.ValidationPassword.onloadDidFire = false; 188 189Spry.Widget.ValidationPassword.prototype.getElement = function(ele) 190{ 191 if (ele && typeof ele == "string") 192 ele=document.getElementById(ele); 193 return ele; 194}; 195 196Spry.Widget.ValidationPassword.processLoadQueue = function(handler) 197{ 198 Spry.Widget.ValidationPassword.onloadDidFire = true; 199 var q = Spry.Widget.ValidationPassword.loadQueue; 200 var qlen = q.length; 201 for (var i = 0; i < qlen; i++) 202 q[i].attachBehaviors(); 203}; 204Spry.Widget.ValidationPassword.addLoadListener = function(handler) 205{ 206 if (typeof window.addEventListener != 'undefined') 207 window.addEventListener('load', handler, false); 208 else if (typeof document.addEventListener != 'undefined') 209 document.addEventListener('load', handler, false); 210 else if (typeof window.attachEvent != 'undefined') 211 window.attachEvent('onload', handler); 212}; 213Spry.Widget.ValidationPassword.addLoadListener(Spry.Widget.ValidationPassword.processLoadQueue); 214 215 216Spry.Widget.ValidationPassword.prototype.destroy = function() 217{ 218 if (this.event_handlers) 219 for (var i=0; i<this.event_handlers.length; i++) 220 Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 221 222 try { delete this.element;} catch(err) {}; 223 try { delete this.input;} catch(err) {}; 224 try { delete this.event_handlers;} catch(err) {}; 225 try { delete this.options;}catch(err) {}; 226 227 var q = Spry.Widget.Form.onSubmitWidgetQueue; 228 var qlen = q.length; 229 for (var i = 0; i < qlen; i++) 230 if (q[i] == this) 231 { 232 q.splice(i, 1); 233 break; 234 } 235}; 236Spry.Widget.ValidationPassword.prototype.attachBehaviors = function() 237{ 238 if (this.event_handlers && this.event_handlers.length > 0) 239 return; 240 241 var handlers = this.event_handlers; 242 if (this.input) 243 { 244 var self = this; 245 this.input.setAttribute("AutoComplete", "off"); 246 if (this.validateOn & Spry.Widget.ValidationPassword.ONCHANGE) 247 { 248 var changeEvent = 249 Spry.is.mozilla || Spry.is.opera || Spry.is.safari?"input": 250 Spry.is.ie?"propertychange": 251 "change"; 252 handlers.push([this.input, changeEvent, function(e){if (self.isDisabled()) return true; return self.validate(e||event);}]); 253 254 if (Spry.is.mozilla || Spry.is.safari) 255 handlers.push([this.input, "dragdrop", function(e){if (self.isDisabled()) return true; return self.validate(e);}]); 256 else if (Spry.is.ie) 257 handlers.push([this.input, "drop", function(e){if (self.isDisabled()) return true; return self.validate(event);}]); 258 } 259 handlers.push([this.input, "blur", function(e) {if (self.isDisabled()) return true; return self.onBlur(e||event);}]);
260 handlers.push([this.input, "focus", function(e) { if (self.isDisabled()) return true; return self.onFocus(e || event); }]); 261 262 for (var i=0; i<this.event_handlers.length; i++) 263 Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 264 265 // submit 266 this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.input, "FORM"); 267 if (this.form) 268 { 269 // if no "onSubmit" handler has been attached to the current form, attach one 270 if (!this.form.attachedSubmitHandler && !this.form.onsubmit) 271 { 272 this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) }; 273 this.form.attachedSubmitHandler = true; 274 } 275 if (!this.form.attachedResetHandler) 276 { 277 Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) {var e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false); 278 this.form.attachedResetHandler = true; 279 } 280 // add the currrent widget to the "onSubmit" check queue; 281 Spry.Widget.Form.onSubmitWidgetQueue.push(this); 282 } 283 } 284}; 285Spry.Widget.ValidationPassword.prototype.reset = function() 286{ 287 this.switchClassName(this.element, ''); 288 this.switchClassName(this.additionalError, ''); 289 this.removeClassName(this.element, this.focusClass); 290 this.removeClassName(this.additionalError, this.focusClass); 291 if (Spry.is.ie) 292 { 293 this.input.forceFireFirstOnPropertyChange = true; 294 this.input.removeAttribute("forceFireFirstOnPropertyChange"); 295 } 296}; 297Spry.Widget.ValidationPassword.prototype.validateLength = function(e) 298{ 299 var opt = this.options; 300 301 if (this.isRequired && this.input.value == '') 302 return this.requiredClass; 303 304 if (opt.minChars > 0 && this.input.value.length < opt.minChars) 305 return this.invalidCharsMinClass; 306 307 if (opt.maxChars !== false && this.input.value.length > opt.maxChars) 308 return this.invalidCharsMaxClass; 309 310 return true; 311}; 312Spry.Widget.ValidationPassword.prototype.validateStrength = function(e) 313{ 314 var opt = this.options; 315 316 var value = this.input.value; 317 if (opt.minAlphaChars !== false || opt.maxAlphaChars !== false) 318 { 319 var alphaChars = value.replace(/[^a-z]/ig, '').length; 320 if ((opt.maxAlphaChars !== false && alphaChars > opt.maxAlphaChars) || (opt.minAlphaChars !== false && alphaChars < opt.minAlphaChars)) 321 return false; 322 } 323 if (opt.minUpperAlphaChars !== false || opt.maxUpperAlphaChars !== false) 324 { 325 var upperAlphaChars = value.replace(/[^A-Z]/g, '').length; 326 if ((opt.maxUpperAlphaChars !== false && upperAlphaChars > opt.maxUpperAlphaChars) || (opt.minUpperAlphaChars !== false && upperAlphaChars < opt.minUpperAlphaChars)) 327 return false; 328 } 329 if (opt.minNumbers !== false || opt.maxNumbers !== false) 330 { 331 var numbers = value.replace(/[^0-9]/g, '').length; 332 if ((opt.maxNumbers !== false && numbers > opt.maxNumbers) || (opt.minNumbers !== false && numbers < opt.minNumbers)) 333 return false; 334 } 335 if (opt.minSpecialChars !== false || opt.maxSpecialChars !== false) 336 { 337 var specials = value.replace(/[a-z0-9]/ig, '').length; 338 if ((opt.maxSpecialChars !== false && specials > opt.maxSpecialChars) || (opt.minSpecialChars !== false && specials < opt.minSpecialChars)) 339 return false; 340 } 341 342 return true; 343}; 344 345Spry.Widget.ValidationPassword.prototype.validate = function(e) 346{ 347 var vLength = this.validateLength(e); 348 if (vLength !== true) 349 { 350 this.switchClassName(this.element, vLength); 351 this.switchClassName(this.additionalError, vLength); 352 return false; 353 } 354 var vStrength = this.validateStrength(e); 355 if (vStrength !== true) 356 { 357 this.switchClassName(this.element, this.invalidStrengthClass); 358 this.switchClassName(this.additionalError, this.invalidStrengthClass); 359 return false; 360 } 361 if (typeof this.options.validation == 'function') 362 { 363 var customValidation = this.options.validation(this.input.value, this.options); 364 if (customValidation !== true) 365 { 366 this.switchClassName(this.element, this.invalidCustomClass); 367 return false; 368 } 369 370 } 371 this.switchClassName(this.element, this.validClass); 372 this.switchClassName(this.additionalError, this.validClass); 373 return true; 374}; 375 376Spry.Widget.ValidationPassword.prototype.onBlur = function(e) 377{ 378 this.removeClassName(this.element, this.focusClass); 379 this.removeClassName(this.additionalError, this.focusClass); 380 381 if (this.validateOn & Spry.Widget.ValidationPassword.ONBLUR) 382 this.validate(e); 383}; 384Spry.Widget.ValidationPassword.prototype.onFocus = function() 385{ 386 this.addClassName(this.element, this.focusClass); 387 this.addClassName(this.additionalError, this.focusClass); 388}; 389Spry.Widget.ValidationPassword.prototype.switchClassName = function(ele, className) 390{ 391 var classes = [this.validClass, this.requiredClass, this.invalidCharsMaxClass, this.invalidCharsMinClass, this.invalidStrengthClass, this.invalidCustomClass]; 392 for (var i =0; i< classes.length; i++) 393 this.removeClassName(ele, classes[i]); 394 395 this.addClassName(ele, className); 396}; 397Spry.Widget.ValidationPassword.prototype.addClassName = function(ele, className) 398{ 399 if (!ele || !className || (ele.className && ele.className.indexOf(className) != -1 && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1)) 400 return; 401 ele.className += (ele.className ? " " : "") + className; 402}; 403Spry.Widget.ValidationPassword.prototype.removeClassName = function(ele, className) 404{ 405 if (!ele || !className || (ele.className && ele.className.indexOf(className) != -1 && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)) 406 return; 407 ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), ""); 408}; 409Spry.Widget.ValidationPassword.prototype.isBrowserSupported = function() 410{ 411 return Spry.is.ie && Spry.is.v >= 5 && Spry.is.windows 412 || 413 Spry.is.mozilla && Spry.is.v >= 1.4 414 || 415 Spry.is.safari 416 || 417 Spry.is.opera && Spry.is.v >= 9; 418}; 419 420Spry.Widget.ValidationPassword.prototype.isDisabled = function() 421{ 422 return this.input && (this.input.disabled || this.input.readOnly) || !this.input; 423}; 424Spry.Widget.ValidationPassword.prototype.showError = function(msg) 425{ 426 alert('Spry.ValidationPassword ERR: ' + msg); 427}; 428 429////////////////////////////////////////////////////////////////////// 430// 431// Spry.Widget.Form - common for all widgets 432// 433////////////////////////////////////////////////////////////////////// 434 435if (!Spry.Widget.Form) Spry.Widget.Form = {}; 436if (!Spry.Widget.Form.onSubmitWidgetQueue) Spry.Widget.Form.onSubmitWidgetQueue = []; 437 438if (!Spry.Widget.Form.validate) 439{ 440 Spry.Widget.Form.validate = function(vform) 441 { 442 var isValid = true; 443 var isElementValid = true; 444 var q = Spry.Widget.Form.onSubmitWidgetQueue; 445 var qlen = q.length; 446 for (var i = 0; i < qlen; i++) 447 if (!q[i].isDisabled() && q[i].form == vform) 448 { 449 isElementValid = q[i].validate(); 450 isValid = isElementValid && isValid; 451 } 452 return isValid; 453 }; 454}; 455 456if (!Spry.Widget.Form.onSubmit) 457{ 458 Spry.Widget.Form.onSubmit = function(e, form) 459 { 460 if (Spry.Widget.Form.validate(form) == false) 461 return false;
462 return true; 463 }; 464}; 465 466if (!Spry.Widget.Form.onReset) 467{ 468 Spry.Widget.Form.onReset = function(e, vform) 469 { 470 var q = Spry.Widget.Form.onSubmitWidgetQueue; 471 var qlen = q.length; 472 for (var i = 0; i < qlen; i++) 473 if (!q[i].isDisabled() && q[i].form == vform && typeof(q[i].reset) == 'function') 474 q[i].reset(); 475 return true; 476 }; 477}; 478 479if (!Spry.Widget.Form.destroy) 480{ 481 Spry.Widget.Form.destroy = function(form) 482 { 483 var q = Spry.Widget.Form.onSubmitWidgetQueue; 484 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) 485 if (q[i].form == form && typeof(q[i].destroy) == 'function') 486 { 487 q[i].destroy(); 488 i--; 489 } 490 } 491}; 492 493if (!Spry.Widget.Form.destroyAll) 494{ 495 Spry.Widget.Form.destroyAll = function() 496 { 497 var q = Spry.Widget.Form.onSubmitWidgetQueue; 498 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) 499 if (typeof(q[i].destroy) == 'function') 500 { 501 q[i].destroy(); 502 i--; 503 } 504 } 505}; 506 507////////////////////////////////////////////////////////////////////// 508// 509// Spry.Widget.Utils 510// 511////////////////////////////////////////////////////////////////////// 512 513if (!Spry.Widget.Utils) Spry.Widget.Utils = {}; 514Spry.Widget.Utils.setOptions = function(obj, optionsObj, ignoreUndefinedProps) 515{ 516 if (!optionsObj) 517 return; 518 for (var optionName in optionsObj) 519 { 520 if (ignoreUndefinedProps && optionsObj[optionName] == undefined) 521 continue; 522 obj[optionName] = optionsObj[optionName]; 523 } 524}; 525 526Spry.Widget.Utils.firstValid = function() 527{ 528 var ret = null; 529 for(var i=0; i<Spry.Widget.Utils.firstValid.arguments.length; i++) 530 if (typeof Spry.Widget.Utils.firstValid.arguments[i] != 'undefined') 531 { 532 ret = Spry.Widget.Utils.firstValid.arguments[i]; 533 break; 534 } 535 return ret; 536}; 537 538Spry.Widget.Utils.getOptionRealValue = function(option, alternate) 539{ 540 var value = Spry.Widget.Utils.firstValid(option, alternate); 541 if (value !== false) 542 value = parseInt(value, 10); 543 544 if (isNaN(value) || value < 0) 545 value = false; 546 547 return value; 548}; 549 550Spry.Widget.Utils.getValidChildrenWithNodeNameAtAnyLevel = function(node, nodeName, type) 551{ 552 var elements = node.getElementsByTagName(nodeName); 553 var to_return = []; 554 var j=0; 555 if (elements) 556 { 557 for (var i=0; i < elements.length; i++) 558 if (typeof elements[i].type != 'undefined' && elements[i].type.toUpperCase() == type.toUpperCase()) 559 { 560 to_return[j] = elements[i]; 561 j++; 562 } 563 } 564 return to_return; 565}; 566Spry.Widget.Utils.getFirstParentWithNodeName = function(node, nodeName) 567{ 568 while (node.parentNode 569 && node.parentNode.nodeName.toLowerCase() != nodeName.toLowerCase() 570 && node.parentNode.nodeName != 'BODY') 571 node = node.parentNode; 572 573 574 if (node.parentNode && node.parentNode.nodeName.toLowerCase() == nodeName.toLowerCase()) 575 return node.parentNode; 576 else 577 return null; 578}; 579Spry.Widget.Utils.addEventListener = function(element, eventType, handler, capture) 580{ 581 try 582 { 583 if (element.addEventListener) 584 element.addEventListener(eventType, handler, capture); 585 else if (element.attachEvent) 586 element.attachEvent("on" + eventType, handler, capture); 587 } 588 catch (e) {} 589}; 590 591Spry.Widget.Utils.removeEventListener = function(element, eventType, handler, capture) 592{ 593 try 594 { 595 if (element.removeEventListener) 596 element.removeEventListener(eventType, handler, capture); 597 else if (element.detachEvent) 598 element.detachEvent("on" + eventType, handler, capture); 599 } 600 catch (e) {} 601}; 602 603})(); // EndSpryComponent
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.