vendor: 12,127 bytes, lines 1-389
1/*! 2 * jQuery Validation Plugin v1.14.0 3 * 4 * http://jqueryvalidation.org/ 5 * 6 * Copyright (c) 2015 Jörn Zaefferer 7 * Released under the MIT license 8 */ 9(function( factory ) { 10 if ( typeof define === "function" && define.amd ) { 11 define( ["jquery"], factory ); 12 } else { 13 factory( jQuery ); 14 } 15}(function( $ ) { 16 17$.extend($.fn, { 18 // http://jqueryvalidation.org/validate/ 19 validate: function( options ) { 20 21 // if nothing is selected, return nothing; can't chain anyway 22 if ( !this.length ) { 23 if ( options && options.debug && window.console ) { 24 console.warn( "Nothing selected, can't validate, returning nothing." ); 25 } 26 return; 27 } 28 29 // check if a validator for this form was already created 30 var validator = $.data( this[ 0 ], "validator" ); 31 if ( validator ) { 32 return validator; 33 } 34 35 // Add novalidate tag if HTML5. 36 this.attr( "novalidate", "novalidate" ); 37 38 validator = new $.validator( options, this[ 0 ] ); 39 $.data( this[ 0 ], "validator", validator ); 40 41 if ( validator.settings.onsubmit ) { 42 43 this.on( "click.validate", ":submit", function( event ) { 44 if ( validator.settings.submitHandler ) { 45 validator.submitButton = event.target; 46 } 47 48 // allow suppressing validation by adding a cancel class to the submit button 49 if ( $( this ).hasClass( "cancel" ) ) { 50 validator.cancelSubmit = true; 51 } 52 53 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 54 if ( $( this ).attr( "formnovalidate" ) !== undefined ) { 55 validator.cancelSubmit = true; 56 } 57 }); 58 59 // validate the form on submit 60 this.on( "submit.validate", function( event ) { 61 if ( validator.settings.debug ) { 62 // prevent form submit to be able to see console output 63 event.preventDefault(); 64 } 65 function handle() { 66 var hidden, result; 67 if ( validator.settings.submitHandler ) { 68 if ( validator.submitButton ) { 69 // insert a hidden input as a replacement for the missing submit button 70 hidden = $( "<input type='hidden'/>" ) 71 .attr( "name", validator.submitButton.name ) 72 .val( $( validator.submitButton ).val() ) 73 .appendTo( validator.currentForm ); 74 } 75 result = validator.settings.submitHandler.call( validator, validator.currentForm, event ); 76 if ( validator.submitButton ) { 77 // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 78 hidden.remove(); 79 } 80 if ( result !== undefined ) { 81 return result; 82 } 83 return false; 84 } 85 return true; 86 } 87 88 // prevent submit for invalid forms or custom submit handlers 89 if ( validator.cancelSubmit ) { 90 validator.cancelSubmit = false; 91 return handle(); 92 } 93 if ( validator.form() ) { 94 if ( validator.pendingRequest ) { 95 validator.formSubmitted = true; 96 return false; 97 } 98 return handle(); 99 } else { 100 validator.focusInvalid(); 101 return false; 102 } 103 }); 104 } 105 106 return validator; 107 }, 108 // http://jqueryvalidation.org/valid/ 109 valid: function() { 110 var valid, validator, errorList; 111 112 if ( $( this[ 0 ] ).is( "form" ) ) { 113 valid = this.validate().form(); 114 } else { 115 errorList = []; 116 valid = true; 117 validator = $( this[ 0 ].form ).validate(); 118 this.each( function() { 119 valid = validator.element( this ) && valid; 120 errorList = errorList.concat( validator.errorList ); 121 }); 122 validator.errorList = errorList; 123 } 124 return valid; 125 }, 126 127 // http://jqueryvalidation.org/rules/ 128 rules: function( command, argument ) { 129 var element = this[ 0 ], 130 settings, staticRules, existingRules, data, param, filtered; 131 132 if ( command ) { 133 settings = $.data( element.form, "validator" ).settings; 134 staticRules = settings.rules; 135 existingRules = $.validator.staticRules( element ); 136 switch ( command ) { 137 case "add": 138 $.extend( existingRules, $.validator.normalizeRule( argument ) ); 139 // remove messages from rules, but allow them to be set separately 140 delete existingRules.messages; 141 staticRules[ element.name ] = existingRules; 142 if ( argument.messages ) { 143 settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages ); 144 } 145 break; 146 case "remove": 147 if ( !argument ) { 148 delete staticRules[ element.name ]; 149 return existingRules; 150 } 151 filtered = {}; 152 $.each( argument.split( /\s/ ), function( index, method ) { 153 filtered[ method ] = existingRules[ method ]; 154 delete existingRules[ method ]; 155 if ( method === "required" ) { 156 $( element ).removeAttr( "aria-required" ); 157 } 158 }); 159 return filtered; 160 } 161 } 162 163 data = $.validator.normalizeRules( 164 $.extend( 165 {}, 166 $.validator.classRules( element ), 167 $.validator.attributeRules( element ), 168 $.validator.dataRules( element ), 169 $.validator.staticRules( element ) 170 ), element ); 171 172 // make sure required is at front 173 if ( data.required ) { 174 param = data.required; 175 delete data.required; 176 data = $.extend( { required: param }, data ); 177 $( element ).attr( "aria-required", "true" ); 178 } 179 180 // make sure remote is at back 181 if ( data.remote ) { 182 param = data.remote; 183 delete data.remote; 184 data = $.extend( data, { remote: param }); 185 } 186 187 return data; 188 } 189}); 190 191// Custom selectors 192$.extend( $.expr[ ":" ], { 193 // http://jqueryvalidation.org/blank-selector/ 194 blank: function( a ) { 195 return !$.trim( "" + $( a ).val() ); 196 }, 197 // http://jqueryvalidation.org/filled-selector/ 198 filled: function( a ) { 199 return !!$.trim( "" + $( a ).val() ); 200 }, 201 // http://jqueryvalidation.org/unchecked-selector/ 202 unchecked: function( a ) { 203 return !$( a ).prop( "checked" ); 204 } 205}); 206 207// constructor for validator 208$.validator = function( options, form ) { 209 this.settings = $.extend( true, {}, $.validator.defaults, options ); 210 this.currentForm = form; 211 this.init(); 212}; 213 214// http://jqueryvalidation.org/jQuery.validator.format/ 215$.validator.format = function( source, params ) { 216 if ( arguments.length === 1 ) { 217 return function() { 218 var args = $.makeArray( arguments ); 219 args.unshift( source ); 220 return $.validator.format.apply( this, args ); 221 }; 222 } 223 if ( arguments.length > 2 && params.constructor !== Array ) { 224 params = $.makeArray( arguments ).slice( 1 ); 225 } 226 if ( params.constructor !== Array ) { 227 params = [ params ]; 228 } 229 $.each( params, function( i, n ) { 230 source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() { 231 return n; 232 }); 233 }); 234 return source; 235}; 236 237$.extend( $.validator, { 238 239 defaults: { 240 messages: {}, 241 groups: {}, 242 rules: {}, 243 errorClass: "error", 244 validClass: "valid", 245 errorElement: "label", 246 focusCleanup: false, 247 focusInvalid: true, 248 errorContainer: $( [] ), 249 errorLabelContainer: $( [] ), 250 onsubmit: true, 251 ignore: ":hidden", 252 ignoreTitle: false, 253 onfocusin: function( element ) { 254 this.lastActive = element; 255 256 // Hide error label and remove error class on focus if enabled 257 if ( this.settings.focusCleanup ) { 258 if ( this.settings.unhighlight ) { 259 this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); 260 } 261 this.hideThese( this.errorsFor( element ) ); 262 } 263 }, 264 onfocusout: function( element ) { 265 if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) { 266 this.element( element ); 267 } 268 }, 269 onkeyup: function( element, event ) { 270 // Avoid revalidate the field when pressing one of the following keys 271 // Shift => 16 272 // Ctrl => 17 273 // Alt => 18 274 // Caps lock => 20 275 // End => 35 276 // Home => 36 277 // Left arrow => 37 278 // Up arrow => 38 279 // Right arrow => 39 280 // Down arrow => 40 281 // Insert => 45 282 // Num lock => 144 283 // AltGr key => 225 284 var excludedKeys = [ 285 16, 17, 18, 20, 35, 36, 37, 286 38, 39, 40, 45, 144, 225 287 ]; 288 289 if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { 290 return; 291 } else if ( element.name in this.submitted || element === this.lastElement ) { 292 this.element( element ); 293 } 294 }, 295 onclick: function( element ) { 296 // click on selects, radiobuttons and checkboxes 297 if ( element.name in this.submitted ) { 298 this.element( element ); 299 300 // or option elements, check parent select in that case 301 } else if ( element.parentNode.name in this.submitted ) { 302 this.element( element.parentNode ); 303 } 304 }, 305 highlight: function( element, errorClass, validClass ) { 306 if ( element.type === "radio" ) { 307 this.findByName( element.name ).addClass( errorClass ).removeClass( validClass ); 308 } else { 309 $( element ).addClass( errorClass ).removeClass( validClass ); 310 } 311 }, 312 unhighlight: function( element, errorClass, validClass ) { 313 if ( element.type === "radio" ) { 314 this.findByName( element.name ).removeClass( errorClass ).addClass( validClass ); 315 } else { 316 $( element ).removeClass( errorClass ).addClass( validClass ); 317 } 318 } 319 }, 320 321 // http://jqueryvalidation.org/jQuery.validator.setDefaults/ 322 setDefaults: function( settings ) { 323 $.extend( $.validator.defaults, settings ); 324 }, 325 326 messages: { 327 required: "This field is required.", 328 remote: "Please fix this field.", 329 email: "Please enter a valid email address.", 330 url: "Please enter a valid URL.", 331 date: "Please enter a valid date.", 332 dateISO: "Please enter a valid date ( ISO ).", 333 number: "Please enter a valid number.", 334 digits: "Please enter only digits.", 335 creditcard: "Please enter a valid credit card number.", 336 equalTo: "Please enter the same value again.", 337 maxlength: $.validator.format( "Please enter no more than {0} characters." ), 338 minlength: $.validator.format( "Please enter at least {0} characters." ), 339 rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ), 340 range: $.validator.format( "Please enter a value between {0} and {1}." ), 341 max: $.validator.format( "Please enter a value less than or equal to {0}." ), 342 min: $.validator.format( "Please enter a value greater than or equal to {0}." ) 343 }, 344 345 autoCreateRanges: false, 346 347 prototype: { 348 349 init: function() { 350 this.labelContainer = $( this.settings.errorLabelContainer ); 351 this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm ); 352 this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer ); 353 this.submitted = {}; 354 this.valueCache = {}; 355 this.pendingRequest = 0; 356 this.pending = {}; 357 this.invalid = {}; 358 this.reset(); 359 360 var groups = ( this.groups = {} ), 361 rules; 362 $.each( this.settings.groups, function( key, value ) { 363 if ( typeof value === "string" ) { 364 value = value.split( /\s/ ); 365 } 366 $.each( value, function( index, name ) { 367 groups[ name ] = key; 368 }); 369 }); 370 rules = this.settings.rules; 371 $.each( rules, function( key, value ) { 372 rules[ key ] = $.validator.normalizeRule( value ); 373 }); 374 375 function delegate( event ) { 376 var validator = $.data( this.form, "validator" ), 377 eventType = "on" + event.type.replace( /^validate/, "" ), 378 settings = validator.settings; 379 if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) { 380 settings[ eventType ].call( validator, this, event ); 381 } 382 } 383 384 $( this.currentForm ) 385 .on( "focusin.validate focusout.validate keyup.validate", 386 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + 387 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + 388 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + 389 "[type='radio'], [type='checkbox']", delegate)
390 // Support: Chrome, oldIE 391 // "select" is provided as event.target when clicking a option 392 .on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate); 393 394 if ( this.settings.invalidHandler ) { 395 $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler ); 396 } 397 398 // Add aria-required to any Static/Data/Class required fields before first validation 399 // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html 400 $( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" ); 401 }, 402 403 // http://jqueryvalidation.org/Validator.form/ 404 form: function() { 405 this.checkForm(); 406 $.extend( this.submitted, this.errorMap ); 407 this.invalid = $.extend({}, this.errorMap ); 408 if ( !this.valid() ) { 409 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 410 } 411 this.showErrors(); 412 return this.valid(); 413 }, 414 415 checkForm: function() { 416 this.prepareForm(); 417 for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { 418 this.check( elements[ i ] ); 419 } 420 return this.valid(); 421 }, 422 423 // http://jqueryvalidation.org/Validator.element/ 424 element: function( element ) { 425 var cleanElement = this.clean( element ), 426 checkElement = this.validationTargetFor( cleanElement ), 427 result = true; 428 429 this.lastElement = checkElement; 430 431 if ( checkElement === undefined ) { 432 delete this.invalid[ cleanElement.name ]; 433 } else { 434 this.prepareElement( checkElement ); 435 this.currentElements = $( checkElement ); 436 437 result = this.check( checkElement ) !== false; 438 if ( result ) { 439 delete this.invalid[ checkElement.name ]; 440 } else { 441 this.invalid[ checkElement.name ] = true; 442 } 443 } 444 // Add aria-invalid status for screen readers 445 $( element ).attr( "aria-invalid", !result ); 446 447 if ( !this.numberOfInvalids() ) { 448 // Hide error containers on last error 449 this.toHide = this.toHide.add( this.containers ); 450 } 451 this.showErrors(); 452 return result; 453 }, 454 455 // http://jqueryvalidation.org/Validator.showErrors/ 456 showErrors: function( errors ) { 457 if ( errors ) { 458 // add items to error list and map 459 $.extend( this.errorMap, errors ); 460 this.errorList = []; 461 for ( var name in errors ) { 462 this.errorList.push({ 463 message: errors[ name ], 464 element: this.findByName( name )[ 0 ] 465 }); 466 } 467 // remove items from success list 468 this.successList = $.grep( this.successList, function( element ) { 469 return !( element.name in errors ); 470 }); 471 } 472 if ( this.settings.showErrors ) { 473 this.settings.showErrors.call( this, this.errorMap, this.errorList ); 474 } else { 475 this.defaultShowErrors(); 476 } 477 }, 478 479 // http://jqueryvalidation.org/Validator.resetForm/ 480 resetForm: function() { 481 if ( $.fn.resetForm ) { 482 $( this.currentForm ).resetForm(); 483 } 484 this.submitted = {}; 485 this.lastElement = null; 486 this.prepareForm(); 487 this.hideErrors(); 488 var i, elements = this.elements() 489 .removeData( "previousValue" ) 490 .removeAttr( "aria-invalid" ); 491 492 if ( this.settings.unhighlight ) { 493 for ( i = 0; elements[ i ]; i++ ) { 494 this.settings.unhighlight.call( this, elements[ i ], 495 this.settings.errorClass, "" ); 496 } 497 } else { 498 elements.removeClass( this.settings.errorClass ); 499 } 500 }, 501 502 numberOfInvalids: function() { 503 return this.objectLength( this.invalid ); 504 }, 505 506 objectLength: function( obj ) { 507 /* jshint unused: false */ 508 var count = 0, 509 i; 510 for ( i in obj ) { 511 count++; 512 } 513 return count; 514 }, 515 516 hideErrors: function() { 517 this.hideThese( this.toHide ); 518 }, 519 520 hideThese: function( errors ) { 521 errors.not( this.containers ).text( "" ); 522 this.addWrapper( errors ).hide(); 523 }, 524 525 valid: function() { 526 return this.size() === 0; 527 }, 528 529 size: function() { 530 return this.errorList.length; 531 }, 532 533 focusInvalid: function() { 534 if ( this.settings.focusInvalid ) { 535 try { 536 $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || []) 537 .filter( ":visible" ) 538 .focus() 539 // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 540 .trigger( "focusin" ); 541 } catch ( e ) {
vendor: 6,286 bytes, lines 542-743
542 // ignore IE throwing errors when focusing hidden elements 543 } 544 } 545 }, 546 547 findLastActive: function() { 548 var lastActive = this.lastActive; 549 return lastActive && $.grep( this.errorList, function( n ) { 550 return n.element.name === lastActive.name; 551 }).length === 1 && lastActive; 552 }, 553 554 elements: function() { 555 var validator = this, 556 rulesCache = {}; 557 558 // select all valid inputs inside the form (no submit or reset buttons) 559 return $( this.currentForm ) 560 .find( "input, select, textarea" ) 561 .not( ":submit, :reset, :image, :disabled" ) 562 .not( this.settings.ignore ) 563 .filter( function() { 564 if ( !this.name && validator.settings.debug && window.console ) { 565 console.error( "%o has no name assigned", this ); 566 } 567 568 // select only the first element for each name, and only those with rules specified 569 if ( this.name in rulesCache || !validator.objectLength( $( this ).rules() ) ) { 570 return false; 571 } 572 573 rulesCache[ this.name ] = true; 574 return true; 575 }); 576 }, 577 578 clean: function( selector ) { 579 return $( selector )[ 0 ]; 580 }, 581 582 errors: function() { 583 var errorClass = this.settings.errorClass.split( " " ).join( "." ); 584 return $( this.settings.errorElement + "." + errorClass, this.errorContext ); 585 }, 586 587 reset: function() { 588 this.successList = []; 589 this.errorList = []; 590 this.errorMap = {}; 591 this.toShow = $( [] ); 592 this.toHide = $( [] ); 593 this.currentElements = $( [] ); 594 }, 595 596 prepareForm: function() { 597 this.reset(); 598 this.toHide = this.errors().add( this.containers ); 599 }, 600 601 prepareElement: function( element ) { 602 this.reset(); 603 this.toHide = this.errorsFor( element ); 604 }, 605 606 elementValue: function( element ) { 607 var val, 608 $element = $( element ), 609 type = element.type; 610 611 if ( type === "radio" || type === "checkbox" ) { 612 return this.findByName( element.name ).filter(":checked").val(); 613 } else if ( type === "number" && typeof element.validity !== "undefined" ) { 614 return element.validity.badInput ? false : $element.val(); 615 } 616 617 val = $element.val(); 618 if ( typeof val === "string" ) { 619 return val.replace(/\r/g, "" ); 620 } 621 return val; 622 }, 623 624 check: function( element ) { 625 element = this.validationTargetFor( this.clean( element ) ); 626 627 var rules = $( element ).rules(), 628 rulesCount = $.map( rules, function( n, i ) { 629 return i; 630 }).length, 631 dependencyMismatch = false, 632 val = this.elementValue( element ), 633 result, method, rule; 634 635 for ( method in rules ) { 636 rule = { method: method, parameters: rules[ method ] }; 637 try { 638 639 result = $.validator.methods[ method ].call( this, val, element, rule.parameters ); 640 641 // if a method indicates that the field is optional and therefore valid, 642 // don't mark it as valid when there are no other rules 643 if ( result === "dependency-mismatch" && rulesCount === 1 ) { 644 dependencyMismatch = true; 645 continue; 646 } 647 dependencyMismatch = false; 648 649 if ( result === "pending" ) { 650 this.toHide = this.toHide.not( this.errorsFor( element ) ); 651 return; 652 } 653 654 if ( !result ) { 655 this.formatAndAdd( element, rule ); 656 return false; 657 } 658 } catch ( e ) { 659 if ( this.settings.debug && window.console ) { 660 console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e ); 661 } 662 if ( e instanceof TypeError ) { 663 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; 664 } 665 666 throw e; 667 } 668 } 669 if ( dependencyMismatch ) { 670 return; 671 } 672 if ( this.objectLength( rules ) ) { 673 this.successList.push( element ); 674 } 675 return true; 676 }, 677 678 // return the custom message for the given element and validation method 679 // specified in the element's HTML5 data attribute 680 // return the generic message if present and no method specific message is present 681 customDataMessage: function( element, method ) { 682 return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() + 683 method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" ); 684 }, 685 686 // return the custom message for the given element name and validation method 687 customMessage: function( name, method ) { 688 var m = this.settings.messages[ name ]; 689 return m && ( m.constructor === String ? m : m[ method ]); 690 }, 691 692 // return the first defined argument, allowing empty strings 693 findDefined: function() { 694 for ( var i = 0; i < arguments.length; i++) { 695 if ( arguments[ i ] !== undefined ) { 696 return arguments[ i ]; 697 } 698 } 699 return undefined; 700 }, 701 702 defaultMessage: function( element, method ) { 703 return this.findDefined( 704 this.customMessage( element.name, method ), 705 this.customDataMessage( element, method ), 706 // title is never undefined, so handle empty string as undefined 707 !this.settings.ignoreTitle && element.title || undefined, 708 $.validator.messages[ method ], 709 "<strong>Warning: No message defined for " + element.name + "</strong>" 710 ); 711 }, 712 713 formatAndAdd: function( element, rule ) { 714 var message = this.defaultMessage( element, rule.method ), 715 theregex = /\$?\{(\d+)\}/g; 716 if ( typeof message === "function" ) { 717 message = message.call( this, rule.parameters, element ); 718 } else if ( theregex.test( message ) ) { 719 message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters ); 720 } 721 this.errorList.push({ 722 message: message, 723 element: element, 724 method: rule.method 725 }); 726 727 this.errorMap[ element.name ] = message; 728 this.submitted[ element.name ] = message; 729 }, 730 731 addWrapper: function( toToggle ) { 732 if ( this.settings.wrapper ) { 733 toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); 734 } 735 return toToggle; 736 }, 737 738 defaultShowErrors: function() { 739 var i, elements, error; 740 for ( i = 0; this.errorList[ i ]; i++ ) { 741 error = this.errorList[ i ]; 742 if ( this.settings.highlight ) { 743 this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
743idClass ); 744 } 745 this.showLabel( error.element, error.message ); 746 } 747 if ( this.errorList.length ) { 748 this.toShow = this.toShow.add( this.containers ); 749 } 750 if ( this.settings.success ) { 751 for ( i = 0; this.successList[ i ]; i++ ) { 752 this.showLabel( this.successList[ i ] ); 753 } 754 } 755 if ( this.settings.unhighlight ) { 756 for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) { 757 this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass ); 758 } 759 } 760 this.toHide = this.toHide.not( this.toShow ); 761 this.hideErrors(); 762 this.addWrapper( this.toShow ).show(); 763 }, 764 765 validElements: function() { 766 return this.currentElements.not( this.invalidElements() ); 767 }, 768 769 invalidElements: function() { 770 return $( this.errorList ).map(function() { 771 return this.element; 772 }); 773 }, 774 775 showLabel: function( element, message ) { 776 var place, group, errorID, 777 error = this.errorsFor( element ), 778 elementID = this.idOrName( element ), 779 describedBy = $( element ).attr( "aria-describedby" ); 780 if ( error.length ) { 781 // refresh error/success class 782 error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass ); 783 // replace message on existing label 784 error.html( message ); 785 } else { 786 // create error element 787 error = $( "<" + this.settings.errorElement + ">" ) 788 .attr( "id", elementID + "-error" ) 789 .addClass( this.settings.errorClass ) 790 .html( message || "" ); 791 792 // Maintain reference to the element to be placed into the DOM 793 place = error; 794 if ( this.settings.wrapper ) { 795 // make sure the element is visible, even in IE 796 // actually showing the wrapped element is handled elsewhere 797 place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent(); 798 } 799 if ( this.labelContainer.length ) { 800 this.labelContainer.append( place ); 801 } else if ( this.settings.errorPlacement ) { 802 this.settings.errorPlacement( place, $( element ) ); 803 } else { 804 place.insertAfter( element ); 805 } 806 807 // Link error back to the element 808 if ( error.is( "label" ) ) { 809 // If the error is a label, then associate using 'for' 810 error.attr( "for", elementID ); 811 } else if ( error.parents( "label[for='" + elementID + "']" ).length === 0 ) { 812 // If the element is not a child of an associated label, then it's necessary 813 // to explicitly apply aria-describedby 814 815 errorID = error.attr( "id" ).replace( /(:|\.|\[|\]|\$)/g, "\\$1"); 816 // Respect existing non-error aria-describedby 817 if ( !describedBy ) { 818 describedBy = errorID; 819 } else if ( !describedBy.match( new RegExp( "\\b" + errorID + "\\b" ) ) ) { 820 // Add to end of list if not already present 821 describedBy += " " + errorID; 822 } 823 $( element ).attr( "aria-describedby", describedBy ); 824 825 // If this element is grouped, then assign to all elements in the same group 826 group = this.groups[ element.name ]; 827 if ( group ) { 828 $.each( this.groups, function( name, testgroup ) { 829 if ( testgroup === group ) { 830 $( "[name='" + name + "']", this.currentForm ) 831 .attr( "aria-describedby", error.attr( "id" ) ); 832 } 833 }); 834 } 835 } 836 } 837 if ( !message && this.settings.success ) { 838 error.text( "" ); 839 if ( typeof this.settings.success === "string" ) { 840 error.addClass( this.settings.success ); 841 } else { 842 this.settings.success( error, element ); 843 } 844 } 845 this.toShow = this.toShow.add( error ); 846 }, 847 848 errorsFor: function( element ) { 849 var name = this.idOrName( element ), 850 describer = $( element ).attr( "aria-describedby" ), 851 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 852 853 // aria-describedby should directly reference the error element 854 if ( describer ) { 855 selector = selector + ", #" + describer.replace( /\s+/g, ", #" ); 856 } 857 return this 858 .errors() 859 .filter( selector ); 860 }, 861 862 idOrName: function( element ) { 863 return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.i
vendor: 9,923 bytes, lines 863-1195
863d || element.name ); 864 }, 865 866 validationTargetFor: function( element ) { 867 868 // If radio/checkbox, validate first element in group instead 869 if ( this.checkable( element ) ) { 870 element = this.findByName( element.name ); 871 } 872 873 // Always apply ignore filter 874 return $( element ).not( this.settings.ignore )[ 0 ]; 875 }, 876 877 checkable: function( element ) { 878 return ( /radio|checkbox/i ).test( element.type ); 879 }, 880 881 findByName: function( name ) { 882 return $( this.currentForm ).find( "[name='" + name + "']" ); 883 }, 884 885 getLength: function( value, element ) { 886 switch ( element.nodeName.toLowerCase() ) { 887 case "select": 888 return $( "option:selected", element ).length; 889 case "input": 890 if ( this.checkable( element ) ) { 891 return this.findByName( element.name ).filter( ":checked" ).length; 892 } 893 } 894 return value.length; 895 }, 896 897 depend: function( param, element ) { 898 return this.dependTypes[typeof param] ? this.dependTypes[typeof param]( param, element ) : true; 899 }, 900 901 dependTypes: { 902 "boolean": function( param ) { 903 return param; 904 }, 905 "string": function( param, element ) { 906 return !!$( param, element.form ).length; 907 }, 908 "function": function( param, element ) { 909 return param( element ); 910 } 911 }, 912 913 optional: function( element ) { 914 var val = this.elementValue( element ); 915 return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch"; 916 }, 917 918 startRequest: function( element ) { 919 if ( !this.pending[ element.name ] ) { 920 this.pendingRequest++; 921 this.pending[ element.name ] = true; 922 } 923 }, 924 925 stopRequest: function( element, valid ) { 926 this.pendingRequest--; 927 // sometimes synchronization fails, make sure pendingRequest is never < 0 928 if ( this.pendingRequest < 0 ) { 929 this.pendingRequest = 0; 930 } 931 delete this.pending[ element.name ]; 932 if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { 933 $( this.currentForm ).submit(); 934 this.formSubmitted = false; 935 } else if (!valid && this.pendingRequest === 0 && this.formSubmitted ) { 936 $( this.currentForm ).triggerHandler( "invalid-form", [ this ]); 937 this.formSubmitted = false; 938 } 939 }, 940 941 previousValue: function( element ) { 942 return $.data( element, "previousValue" ) || $.data( element, "previousValue", { 943 old: null, 944 valid: true, 945 message: this.defaultMessage( element, "remote" ) 946 }); 947 }, 948 949 // cleans up all forms and elements, removes validator-specific events 950 destroy: function() { 951 this.resetForm(); 952 953 $( this.currentForm ) 954 .off( ".validate" ) 955 .removeData( "validator" ); 956 } 957 958 }, 959 960 classRuleSettings: { 961 required: { required: true }, 962 email: { email: true }, 963 url: { url: true }, 964 date: { date: true }, 965 dateISO: { dateISO: true }, 966 number: { number: true }, 967 digits: { digits: true }, 968 creditcard: { creditcard: true } 969 }, 970 971 addClassRules: function( className, rules ) { 972 if ( className.constructor === String ) { 973 this.classRuleSettings[ className ] = rules; 974 } else { 975 $.extend( this.classRuleSettings, className ); 976 } 977 }, 978 979 classRules: function( element ) { 980 var rules = {}, 981 classes = $( element ).attr( "class" ); 982 983 if ( classes ) { 984 $.each( classes.split( " " ), function() { 985 if ( this in $.validator.classRuleSettings ) { 986 $.extend( rules, $.validator.classRuleSettings[ this ]); 987 } 988 }); 989 } 990 return rules; 991 }, 992 993 normalizeAttributeRule: function( rules, type, method, value ) { 994 995 // convert the value to a number for number inputs, and for text for backwards compability 996 // allows type="date" and others to be compared as strings 997 if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) { 998 value = Number( value ); 999 1000 // Support Opera Mini, which returns NaN for undefined minlength 1001 if ( isNaN( value ) ) { 1002 value = undefined; 1003 } 1004 } 1005 1006 if ( value || value === 0 ) { 1007 rules[ method ] = value; 1008 } else if ( type === method && type !== "range" ) { 1009 1010 // exception: the jquery validate 'range' method 1011 // does not test for the html5 'range' type 1012 rules[ method ] = true; 1013 } 1014 }, 1015 1016 attributeRules: function( element ) { 1017 var rules = {}, 1018 $element = $( element ), 1019 type = element.getAttribute( "type" ), 1020 method, value; 1021 1022 for ( method in $.validator.methods ) { 1023 1024 // support for <input required> in both html5 and older browsers 1025 if ( method === "required" ) { 1026 value = element.getAttribute( method ); 1027 1028 // Some browsers return an empty string for the required attribute 1029 // and non-HTML5 browsers might have required="" markup 1030 if ( value === "" ) { 1031 value = true; 1032 } 1033 1034 // force non-HTML5 browsers to return bool 1035 value = !!value; 1036 } else { 1037 value = $element.attr( method ); 1038 } 1039 1040 this.normalizeAttributeRule( rules, type, method, value ); 1041 } 1042 1043 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 1044 if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) { 1045 delete rules.maxlength; 1046 } 1047 1048 return rules; 1049 }, 1050 1051 dataRules: function( element ) { 1052 var rules = {}, 1053 $element = $( element ), 1054 type = element.getAttribute( "type" ), 1055 method, value; 1056 1057 for ( method in $.validator.methods ) { 1058 value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() ); 1059 this.normalizeAttributeRule( rules, type, method, value ); 1060 } 1061 return rules; 1062 }, 1063 1064 staticRules: function( element ) { 1065 var rules = {}, 1066 validator = $.data( element.form, "validator" ); 1067 1068 if ( validator.settings.rules ) { 1069 rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {}; 1070 } 1071 return rules; 1072 }, 1073 1074 normalizeRules: function( rules, element ) { 1075 // handle dependency check 1076 $.each( rules, function( prop, val ) { 1077 // ignore rule when param is explicitly false, eg. required:false 1078 if ( val === false ) { 1079 delete rules[ prop ]; 1080 return; 1081 } 1082 if ( val.param || val.depends ) { 1083 var keepRule = true; 1084 switch ( typeof val.depends ) { 1085 case "string": 1086 keepRule = !!$( val.depends, element.form ).length; 1087 break; 1088 case "function": 1089 keepRule = val.depends.call( element, element ); 1090 break; 1091 } 1092 if ( keepRule ) { 1093 rules[ prop ] = val.param !== undefined ? val.param : true; 1094 } else { 1095 delete rules[ prop ]; 1096 } 1097 } 1098 }); 1099 1100 // evaluate parameters 1101 $.each( rules, function( rule, parameter ) { 1102 rules[ rule ] = $.isFunction( parameter ) ? parameter( element ) : parameter; 1103 }); 1104 1105 // clean number parameters 1106 $.each([ "minlength", "maxlength" ], function() { 1107 if ( rules[ this ] ) { 1108 rules[ this ] = Number( rules[ this ] ); 1109 } 1110 }); 1111 $.each([ "rangelength", "range" ], function() { 1112 var parts; 1113 if ( rules[ this ] ) { 1114 if ( $.isArray( rules[ this ] ) ) { 1115 rules[ this ] = [ Number( rules[ this ][ 0 ]), Number( rules[ this ][ 1 ] ) ]; 1116 } else if ( typeof rules[ this ] === "string" ) { 1117 parts = rules[ this ].replace(/[\[\]]/g, "" ).split( /[\s,]+/ ); 1118 rules[ this ] = [ Number( parts[ 0 ]), Number( parts[ 1 ] ) ]; 1119 } 1120 } 1121 }); 1122 1123 if ( $.validator.autoCreateRanges ) { 1124 // auto-create ranges 1125 if ( rules.min != null && rules.max != null ) { 1126 rules.range = [ rules.min, rules.max ]; 1127 delete rules.min; 1128 delete rules.max; 1129 } 1130 if ( rules.minlength != null && rules.maxlength != null ) { 1131 rules.rangelength = [ rules.minlength, rules.maxlength ]; 1132 delete rules.minlength; 1133 delete rules.maxlength; 1134 } 1135 } 1136 1137 return rules; 1138 }, 1139 1140 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 1141 normalizeRule: function( data ) { 1142 if ( typeof data === "string" ) { 1143 var transformed = {}; 1144 $.each( data.split( /\s/ ), function() { 1145 transformed[ this ] = true; 1146 }); 1147 data = transformed; 1148 } 1149 return data; 1150 }, 1151 1152 // http://jqueryvalidation.org/jQuery.validator.addMethod/ 1153 addMethod: function( name, method, message ) { 1154 $.validator.methods[ name ] = method; 1155 $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ]; 1156 if ( method.length < 3 ) { 1157 $.validator.addClassRules( name, $.validator.normalizeRule( name ) ); 1158 } 1159 }, 1160 1161 methods: { 1162 1163 // http://jqueryvalidation.org/required-method/ 1164 required: function( value, element, param ) { 1165 // check if dependency is met 1166 if ( !this.depend( param, element ) ) { 1167 return "dependency-mismatch"; 1168 } 1169 if ( element.nodeName.toLowerCase() === "select" ) { 1170 // could be an array for select-multiple or a string, both are fine this way 1171 var val = $( element ).val(); 1172 return val && val.length > 0; 1173 } 1174 if ( this.checkable( element ) ) { 1175 return this.getLength( value, element ) > 0; 1176 } 1177 return value.length > 0; 1178 }, 1179 1180 // http://jqueryvalidation.org/email-method/ 1181 email: function( value, element ) { 1182 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address 1183 // Retrieved 2014-01-14 1184 // If you have a problem with this implementation, report a bug against the above spec 1185 // Or use custom methods to implement your own email validation 1186 return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value ); 1187 }, 1188 1189 // http://jqueryvalidation.org/url-method/ 1190 url: function( value, element ) { 1191 1192 // Copyright (c) 2010-2013 Diego Perini, MIT licensed 1193 // https://gist.github.com/dperini/729294 1194 // see also https://mathiasbynens.be/demo/url-regex 1195 // modified to allow protocol-relative URLs
1196 return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value ); 1197 }, 1198 1199 // http://jqueryvalidation.org/date-method/ 1200 date: function( value, element ) { 1201 return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() ); 1202 }, 1203 1204 // http://jqueryvalidation.org/dateISO-method/ 1205 dateISO: function( value, element ) { 1206 return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value ); 1207 }, 1208 1209 // http://jqueryvalidation.org/number-method/ 1210 number: function( value, element ) { 1211 return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value ); 1212 }, 1213 1214 // http://jqueryvalidation.org/digits-method/ 1215 digits: function( value, element ) { 1216 return this.optional( element ) || /^\d+$/.test( value ); 1217 }, 1218 1219 // http://jqueryvalidation.org/creditcard-method/ 1220 // based on http://en.wikipedia.org/wiki/Luhn_algorithm 1221 creditcard: function( value, element ) { 1222 if ( this.optional( element ) ) { 1223 return "dependency-mismatch"; 1224 } 1225 // accept only spaces, digits and dashes 1226 if ( /[^0-9 \-]+/.test( value ) ) { 1227 return false; 1228 } 1229 var nCheck = 0, 1230 nDigit = 0, 1231 bEven = false, 1232 n, cDigit; 1233 1234 value = value.replace( /\D/g, "" ); 1235 1236 // Basing min and max length on 1237 // http://developer.ean.com/general_info/Valid_Credit_Card_Types 1238 if ( value.length < 13 || value.length > 19 ) { 1239 return false; 1240 } 1241 1242 for ( n = value.length - 1; n >= 0; n--) { 1243 cDigit = value.charAt( n ); 1244 nDigit = parseInt( cDigit, 10 ); 1245 if ( bEven ) { 1246 if ( ( nDigit *= 2 ) > 9 ) { 1247 nDigit -= 9; 1248 } 1249 } 1250 nCheck += nDigit; 1251 bEven = !bEven; 1252 } 1253 1254 return ( nCheck % 10 ) === 0; 1255 }, 1256 1257 // http://jqueryvalidation.org/minlength-method/ 1258 minlength: function( value, element, param ) { 1259 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1260 return this.optional( element ) || length >= param; 1261 }, 1262 1263 // http://jqueryvalidation.org/maxlength-method/ 1264 maxlength: function( value, element, param ) { 1265 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1266 return this.optional( element ) || length <= param; 1267 }, 1268 1269 // http://jqueryvalidation.org/rangelength-method/ 1270 rangelength: function( value, element, param ) { 1271 var length = $.isArray( value ) ? value.length : this.getLength( value, element ); 1272 return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] ); 1273 }, 1274 1275 // http://jqueryvalidation.org/min-method/ 1276 min: function( value, element, param ) { 1277 return this.optional( element ) || value >= param; 1278 }, 1279 1280 // http://jqueryvalidation.org/max-method/ 1281 max: function( value, element, param ) { 1282 return this.optional( element ) || value <= param; 1283 }, 1284 1285 // http://jqueryvalidation.org/range-method/ 1286 range: function( value, element, param ) { 1287 return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] ); 1288 }, 1289 1290 // http://jqueryvalidation.org/equalTo-method/ 1291 equalTo: function( value, element, param ) {
1292 // bind to the blur event of the target in order to revalidate whenever the target field is updated 1293 // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1294 var target = $( param ); 1295 if ( this.settings.onfocusout ) { 1296 target.off( ".validate-equalTo" ).on( "blur.validate-equalTo", function() { 1297 $( element ).valid(); 1298 }); 1299 } 1300 return value === target.val(); 1301 }, 1302 1303 // http://jqueryvalidation.org/remote-method/ 1304 remote: function( value, element, param ) { 1305 if ( this.optional( element ) ) { 1306 return "dependency-mismatch"; 1307 } 1308 1309 var previous = this.previousValue( element ), 1310 validator, data; 1311 1312 if (!this.settings.messages[ element.name ] ) { 1313 this.settings.messages[ element.name ] = {}; 1314 } 1315 previous.originalMessage = this.settings.messages[ element.name ].remote; 1316 this.settings.messages[ element.name ].remote = previous.message; 1317 1318 param = typeof param === "string" && { url: param } || param; 1319 1320 if ( previous.old === value ) { 1321 return previous.valid; 1322 } 1323 1324 previous.old = value; 1325 validator = this; 1326 this.startRequest( element ); 1327 data = {}; 1328 data[ element.name ] = value; 1329 $.ajax( $.extend( true, { 1330 mode: "abort", 1331 port: "validate" + element.name, 1332 dataType: "json", 1333 data: data, 1334 context: validator.currentForm, 1335 success: function( response ) { 1336 var valid = response === true || response === "true", 1337 errors, message, submitted; 1338 1339 validator.settings.messages[ element.name ].remote = previous.originalMessage; 1340 if ( valid ) { 1341 submitted = validator.formSubmitted; 1342 validator.prepareElement( element ); 1343 validator.formSubmitted = submitted; 1344 validator.successList.push( element ); 1345 delete validator.invalid[ element.name ]; 1346 validator.showErrors(); 1347 } else { 1348 errors = {}; 1349 message = response || validator.defaultMessage( element, "remote" ); 1350 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message; 1351 validator.invalid[ element.name ] = true; 1352 validator.showErrors( errors ); 1353 } 1354 previous.valid = valid; 1355 validator.stopRequest( element, valid ); 1356 } 1357 }, param ) ); 1358 return "pending"; 1359 } 1360 } 1361 1362}); 1363 1364// ajax mode: abort 1365// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1366// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1367 1368var pendingRequests = {}, 1369 ajax; 1370// Use a prefilter if available (1.5+) 1371if ( $.ajaxPrefilter ) { 1372 $.ajaxPrefilter(function( settings, _, xhr ) { 1373 var port = settings.port; 1374 if ( settings.mode === "abort" ) { 1375 if ( pendingRequests[port] ) { 1376 pendingRequests[port].abort(); 1377 } 1378 pendingRequests[port] = xhr; 1379 } 1380 }); 1381} else { 1382 // Proxy ajax 1383 ajax = $.ajax; 1384 $.ajax = function( settings ) { 1385 var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, 1386 port = ( "port" in settings ? settings : $.ajaxSettings ).port; 1387 if ( mode === "abort" ) { 1388 if ( pendingRequests[port] ) { 1389 pendingRequests[port].abort(); 1390 } 1391 pendingRequests[port] = ajax.apply(this, arguments); 1392 return pendingRequests[port]; 1393 } 1394 return ajax.apply(this, arguments); 1395 }; 1396} 1397 1398})); 1399function strlen (string) { 1400 // discuss at: http://phpjs.org/functions/strlen/ 1401 // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1402 // improved by: Sakimori 1403 // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1404 // input by: Kirk Strobeck 1405 // bugfixed by: Onno Marsman 1406 // revised by: Brett Zamir (http://brett-zamir.me) 1407 // note: May look like overkill, but in order to be truly faithful to handling all Unicode 1408 // note: characters and to this function in PHP which does not count the number of bytes 1409 // note: but counts the number of characters, something like this is really necessary. 1410 // example 1: strlen('Kevin van Zonneveld'); 1411 // returns 1: 19 1412 // example 2: ini_set('unicode.semantics', 'on'); 1413 // example 2: strlen('A\ud87e\udc04Z'); 1414 // returns 2: 3 1415 1416 var str = string + '' 1417 var i = 0, 1418 chr = '', 1419 lgth = 0 1420 1421 if (!this.php_js || !this.php_js.ini || !this.php_js.ini['unicode.semantics'] || this.php_js.ini[ 1422 'unicode.semantics'].local_value.toLowerCase() !== 'on') { 1423 return string.length 1424 } 1425 1426 var getWholeChar = function (str, i) { 1427 var code = str.charCodeAt(i) 1428 var next = '', 1429 prev = '' 1430 if (0xD800 <= code && code <= 0xDBFF) { 1431 // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters) 1432 if (str.length <= (i + 1)) { 1433 throw 'High surrogate without following low surrogate' 1434 } 1435 next = str.charCodeAt(i + 1) 1436 if (0xDC00 > next || next > 0xDFFF) { 1437 throw 'High surrogate without following low surrogate' 1438 } 1439 return str.charAt(i) + str.charAt(i + 1) 1440 } else if (0xDC00 <= code && code <= 0xDFFF) { 1441 // Low surrogate 1442 if (i === 0) { 1443 throw 'Low surrogate without preceding high surrogate' 1444 } 1445 prev = str.charCodeAt(i - 1) 1446 if (0xD800 > prev || prev > 0xDBFF) { 1447 // (could change last hex to 0xDB7F to treat high private surrogates as single characters) 1448 throw 'Low surrogate without preceding high surrogate' 1449 } 1450 // We can pass over low surrogates now as the second component in a pair which we have already processed 1451 return false 1452 } 1453 return str.charAt(i) 1454 } 1455 1456 for (i = 0, lgth = 0; i < str.length; i++) { 1457 if ((chr = getWholeChar(str, i)) === false) { 1458 continue 1459 } // Adapt this line at the top of any loop, passing in the whole string and the current iteration and returning a variable to represent the individual character; purpose is to treat the first part of a surrogate pair as the whole character and then ignore the second part 1460 lgth++ 1461 } 1462 return lgth 1463} 1464 1465function array_diff (arr1) { 1466 // discuss at: http://phpjs.org/functions/array_diff/ 1467 // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1468 // improved by: Sanjoy Roy 1469 // revised by: Brett Zamir (http://brett-zamir.me) 1470 // example 1: array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']); 1471 // returns 1: {0:'Kevin'} 1472 1473 var retArr = {}, 1474 argl = arguments.length, 1475 k1 = '', 1476 i = 1, 1477 k = '', 1478 arr = {} 1479 1480 arr1keys: for (k1 in arr1) { 1481 for (i = 1; i < argl; i++) { 1482 arr = arguments[i] 1483 for (k in arr) { 1484 if (arr[k] === arr1[k1]) { 1485 // If it reaches here, it was found in at least one array, so try next value 1486 continue arr1keys 1487 } 1488 }
1489 retArr[k1] = arr1[k1] 1490 } 1491 } 1492 1493 return retArr 1494} 1495 1496function strtotime (text, now) { 1497 // discuss at: http://phpjs.org/functions/strtotime/ 1498 // version: 1109.2016 1499 // original by: Caio Ariede (http://caioariede.com) 1500 // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1501 // improved by: Caio Ariede (http://caioariede.com) 1502 // improved by: A. MatÃas Quezada (http://amatiasq.com) 1503 // improved by: preuter 1504 // improved by: Brett Zamir (http://brett-zamir.me) 1505 // improved by: Mirko Faber 1506 // input by: David 1507 // bugfixed by: Wagner B. Soares 1508 // bugfixed by: Artur Tchernychev 1509 // bugfixed by: Stephan Bösch-Plepelits (http://github.com/plepe) 1510 // note: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones) 1511 // example 1: strtotime('+1 day', 1129633200); 1512 // returns 1: 1129719600 1513 // example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200); 1514 // returns 2: 1130425202 1515 // example 3: strtotime('last month', 1129633200); 1516 // returns 3: 1127041200 1517 // example 4: strtotime('2009-05-04 08:30:00 GMT'); 1518 // returns 4: 1241425800 1519 // example 5: strtotime('2009-05-04 08:30:00+00'); 1520 // returns 5: 1241425800 1521 // example 6: strtotime('2009-05-04 08:30:00+02:00'); 1522 // returns 6: 1241418600 1523 // example 7: strtotime('2009-05-04T08:30:00Z'); 1524 // returns 7: 1241425800 1525 1526 var parsed, match, today, year, date, days, ranges, len, times, regex, i, fail = false 1527 1528 if (!text) { 1529 return fail 1530 } 1531 1532 // Unecessary spaces 1533 text = text.replace(/^\s+|\s+$/g, '') 1534 .replace(/\s{2,}/g, ' ') 1535 .replace(/[\t\r\n]/g, '') 1536 .toLowerCase() 1537 1538 // in contrast to php, js Date.parse function interprets: 1539 // dates given as yyyy-mm-dd as in timezone: UTC, 1540 // dates with "." or "-" as MDY instead of DMY 1541 // dates with two-digit years differently 1542 // etc...etc... 1543 // ...therefore we manually parse lots of common date formats 1544 match = text.match( 1545 /^(\d{1,4})([\-\.\/\:])(\d{1,2})([\-\.\/\:])(\d{1,4})(?:\s(\d{1,2}):(\d{2})?:?(\d{2})?)?(?:\s([A-Z]+)?)?$/) 1546 1547 if (match && match[2] === match[4]) { 1548 if (match[1] > 1901) { 1549 switch (match[2]) { 1550 case '-': 1551 { 1552 // YYYY-M-D 1553 if (match[3] > 12 || match[5] > 31) { 1554 return fail 1555 } 1556 1557 return new Date(match[1], parseInt(match[3], 10) - 1, match[5], 1558 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1559 } 1560 case '.': 1561 { 1562 // YYYY.M.D is not parsed by strtotime() 1563 return fail 1564 } 1565 case '/': 1566 { 1567 // YYYY/M/D 1568 if (match[3] > 12 || match[5] > 31) { 1569 return fail 1570 } 1571 1572 return new Date(match[1], parseInt(match[3], 10) - 1, match[5], 1573 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1574 } 1575 } 1576 } else if (match[5] > 1901) { 1577 switch (match[2]) { 1578 case '-': 1579 { 1580 // D-M-YYYY 1581 if (match[3] > 12 || match[1] > 31) { 1582 return fail 1583 } 1584 1585 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 1586 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1587 } 1588 case '.': 1589 { 1590 // D.M.YYYY 1591 if (match[3] > 12 || match[1] > 31) { 1592 return fail 1593 } 1594 1595 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 1596 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1597 } 1598 case '/': 1599 { 1600 // M/D/YYYY 1601 if (match[1] > 12 || match[3] > 31) { 1602 return fail 1603 } 1604 1605 return new Date(match[5], parseInt(match[1], 10) - 1, match[3], 1606 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1607 } 1608 } 1609 } else { 1610 switch (match[2]) { 1611 case '-': 1612 { 1613 // YY-M-D 1614 if (match[3] > 12 || match[5] > 31 || (match[1] < 70 && match[1] > 38)) { 1615 return fail 1616 } 1617 1618 year = match[1] >= 0 && match[1] <= 38 ? +match[1] + 2000 : match[1] 1619 return new Date(year, parseInt(match[3], 10) - 1, match[5], 1620 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1621 } 1622 case '.': 1623 { 1624 // D.M.YY or H.MM.SS 1625 if (match[5] >= 70) { 1626 // D.M.YY 1627 if (match[3] > 12 || match[1] > 31) { 1628 return fail 1629 } 1630 1631 return new Date(match[5], parseInt(match[3], 10) - 1, match[1], 1632 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1633 } 1634 if (match[5] < 60 && !match[6]) { 1635 // H.MM.SS 1636 if (match[1] > 23 || match[3] > 59) { 1637 return fail 1638 } 1639 1640 today = new Date() 1641 return new Date(today.getFullYear(), today.getMonth(), today.getDate(), 1642 match[1] || 0, match[3] || 0, match[5] || 0, match[9] || 0) / 1000 1643 } 1644 1645 // invalid format, cannot be parsed 1646 return fail 1647 } 1648 case '/': 1649 { 1650 // M/D/YY 1651 if (match[1] > 12 || match[3] > 31 || (match[5] < 70 && match[5] > 38)) { 1652 return fail 1653 } 1654 1655 year = match[5] >= 0 && match[5] <= 38 ? +match[5] + 2000 : match[5] 1656 return new Date(year, parseInt(match[1], 10) - 1, match[3], 1657 match[6] || 0, match[7] || 0, match[8] || 0, match[9] || 0) / 1000 1658 } 1659 case ':': 1660 { 1661 // HH:MM:SS 1662 if (match[1] > 23 || match[3] > 59 || match[5] > 59) { 1663 return fail 1664 } 1665 1666 today = new Date() 1667 return new Date(today.getFullYear(), today.getMonth(), today.getDate(), 1668 match[1] || 0, match[3] || 0, match[5] || 0) / 1000 1669 } 1670 } 1671 } 1672 } 1673 1674 // other formats and "now" should be parsed by Date.parse() 1675 if (text === 'now') { 1676 return now === null || isNaN(now) ? new Date() 1677 .getTime() / 1000 | 0 : now | 0 1678 } 1679 if (!isNaN(parsed = Date.parse(text))) { 1680 return parsed / 1000 | 0 1681 } 1682 // Browsers != Chrome have problems parsing ISO 8601 date strings, as they do 1683 // not accept lower case characters, space, or shortened time zones. 1684 // Therefore, fix these problems and try again. 1685 // Examples: 1686 // 2015-04-15 20:33:59+02 1687 // 2015-04-15 20:33:59z 1688 // 2015-04-15t20:33:59+02:00 1689 if (match = text.match( 1690 /^([0-9]{4}-[0-9]{2}-[0-9]{2})[ t]([0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)([\+-][0-9]{2}(:[0-9]{2})?|z)/)) { 1691 // fix time zone information 1692 if (match[4] == 'z') { 1693 match[4] = 'Z' 1694 } else if (match[4].match(/^([\+-][0-9]{2})$/)) { 1695 match[4] = match[4] + ':00' 1696 } 1697 1698 if (!isNaN(parsed = Date.parse(match[1] + 'T' + match[2] + match[4]))) { 1699 return parsed / 1000 | 0 1700 } 1701 } 1702 1703 date = now ? new Date(now * 1000) : new Date() 1704 days = { 1705 'sun': 0, 1706 'mon': 1, 1707 'tue': 2, 1708 'wed': 3, 1709 'thu': 4,
1710 'fri': 5, 1711 'sat': 6 1712 } 1713 ranges = { 1714 'yea': 'FullYear', 1715 'mon': 'Month', 1716 'day': 'Date', 1717 'hou': 'Hours', 1718 'min': 'Minutes', 1719 'sec': 'Seconds' 1720 } 1721 1722 function lastNext (type, range, modifier) { 1723 var diff, day = days[range] 1724 1725 if (typeof day !== 'undefined') { 1726 diff = day - date.getDay() 1727 1728 if (diff === 0) { 1729 diff = 7 * modifier 1730 } else if (diff > 0 && type === 'last') { 1731 diff -= 7 1732 } else if (diff < 0 && type === 'next') { 1733 diff += 7 1734 } 1735 1736 date.setDate(date.getDate() + diff) 1737 } 1738 } 1739 1740 function process (val) { 1741 var splt = val.split(' '), // Todo: Reconcile this with regex using \s, taking into account browser issues with split and regexes 1742 type = splt[0], 1743 range = splt[1].substring(0, 3), 1744 typeIsNumber = /\d+/.test(type), 1745 ago = splt[2] === 'ago', 1746 num = (type === 'last' ? -1 : 1) * (ago ? -1 : 1) 1747 1748 if (typeIsNumber) { 1749 num *= parseInt(type, 10) 1750 } 1751 1752 if (ranges.hasOwnProperty(range) && !splt[1].match(/^mon(day|\.)?$/i)) { 1753 return date['set' + ranges[range]](date['get' + ranges[range]]() + num) 1754 } 1755 1756 if (range === 'wee') { 1757 return date.setDate(date.getDate() + (num * 7)) 1758 } 1759 1760 if (type === 'next' || type === 'last') { 1761 lastNext(type, range, num) 1762 } else if (!typeIsNumber) { 1763 return false 1764 } 1765 1766 return true 1767 } 1768 1769 times = '(years?|months?|weeks?|days?|hours?|minutes?|min|seconds?|sec' + 1770 '|sunday|sun\\.?|monday|mon\\.?|tuesday|tue\\.?|wednesday|wed\\.?' + 1771 '|thursday|thu\\.?|friday|fri\\.?|saturday|sat\\.?)' 1772 regex = '([+-]?\\d+\\s' + times + '|' + '(last|next)\\s' + times + ')(\\sago)?' 1773 1774 match = text.match(new RegExp(regex, 'gi')) 1775 if (!match) { 1776 return fail 1777 } 1778 1779 for (i = 0, len = match.length; i < len; i++) { 1780 if (!process(match[i])) { 1781 return fail 1782 } 1783 } 1784 1785 // ECMAScript 5 only 1786 // if (!match.every(process)) 1787 // return false; 1788 1789 return (date.getTime() / 1000) 1790} 1791 1792function is_numeric (mixed_var) { 1793 // discuss at: http://phpjs.org/functions/is_numeric/ 1794 // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) 1795 // improved by: David 1796 // improved by: taith 1797 // bugfixed by: Tim de Koning 1798 // bugfixed by: WebDevHobo (http://webdevhobo.blogspot.com/) 1799 // bugfixed by: Brett Zamir (http://brett-zamir.me) 1800 // bugfixed by: Denis Chenu (http://shnoulle.net) 1801 // example 1: is_numeric(186.31); 1802 // returns 1: true 1803 // example 2: is_numeric('Kevin van Zonneveld'); 1804 // returns 2: false 1805 // example 3: is_numeric(' +186.31e2'); 1806 // returns 3: true 1807 // example 4: is_numeric(''); 1808 // returns 4: false 1809 // example 5: is_numeric([]); 1810 // returns 5: false 1811 // example 6: is_numeric('1 '); 1812 // returns 6: false 1813 1814 var whitespace = 1815 ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000' 1816 return (typeof mixed_var === 'number' || (typeof mixed_var === 'string' && whitespace.indexOf(mixed_var.slice(-1)) === 1817 -1)) && mixed_var !== '' && !isNaN(mixed_var) 1818} 1819 1820/*! 1821 * @copyright Copyright © Kartik Visweswaran, Krajee.com, 2014 - 2017 1822 * @version 1.3.4 1823 * 1824 * Date formatter utility library that allows formatting date/time variables or Date objects using PHP DateTime format. 1825 * This library is a standalone javascript library and does not depend on other libraries or plugins like jQuery. 1826 * 1827 * @see http://php.net/manual/en/function.date.php 1828 * 1829 * For more JQuery plugins visit http://plugins.krajee.com 1830 * For more Yii related demos visit http://demos.krajee.com 1831 */ 1832var DateFormatter; 1833(function () { 1834 "use strict"; 1835 1836 var _compare, _lpad, _extend, _indexOf, defaultSettings, DAY, HOUR; 1837 DAY = 1000 * 60 * 60 * 24; 1838 HOUR = 3600; 1839 1840 _compare = function (str1, str2) { 1841 return typeof(str1) === 'string' && typeof(str2) === 'string' && str1.toLowerCase() === str2.toLowerCase(); 1842 }; 1843 _lpad = function (value, length, chr) { 1844 var val = value.toString(); 1845 chr = chr || '0'; 1846 return val.length < length ? _lpad(chr + val, length) : val; 1847 }; 1848 _extend = function (out) { 1849 var i, obj; 1850 out = out || {}; 1851 for (i = 1; i < arguments.length; i++) { 1852 obj = arguments[i]; 1853 if (!obj) { 1854 continue; 1855 } 1856 for (var key in obj) { 1857 if (obj.hasOwnProperty(key)) { 1858 if (typeof obj[key] === 'object') { 1859 _extend(out[key], obj[key]); 1860 } else { 1861 out[key] = obj[key]; 1862 } 1863 } 1864 } 1865 } 1866 return out; 1867 }; 1868 _indexOf = function (val, arr) { 1869 for (var i = 0; i < arr.length; i++) { 1870 if (arr[i].toLowerCase() === val.toLowerCase()) { 1871 return i; 1872 } 1873 } 1874 return -1; 1875 }; 1876 defaultSettings = { 1877 dateSettings: { 1878 days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 1879 daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 1880 months: [ 1881 'January', 'February', 'March', 'April', 'May', 'June', 'July', 1882 'August', 'September', 'October', 'November', 'December' 1883 ], 1884 monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], 1885 meridiem: ['AM', 'PM'], 1886 ordinal: function (number) { 1887 var n = number % 10, suffixes = {1: 'st', 2: 'nd', 3: 'rd'}; 1888 return Math.floor(number % 100 / 10) === 1 || !suffixes[n] ? 'th' : suffixes[n]; 1889 } 1890 }, 1891 separators: /[ \-+\/\.T:@]/g, 1892 validParts: /[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g, 1893 intParts: /[djwNzmnyYhHgGis]/g, 1894 tzParts: /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g, 1895 tzClip: /[^-+\dA-Z]/g 1896 }; 1897 1898 DateFormatter = function (options) {
1899 var self = this, config = _extend(defaultSettings, options); 1900 self.dateSettings = config.dateSettings; 1901 self.separators = config.separators; 1902 self.validParts = config.validParts; 1903 self.intParts = config.intParts; 1904 self.tzParts = config.tzParts; 1905 self.tzClip = config.tzClip; 1906 }; 1907 1908 DateFormatter.prototype = { 1909 constructor: DateFormatter, 1910 getMonth: function (val) { 1911 var self = this, i; 1912 i = _indexOf(val, self.dateSettings.monthsShort) + 1; 1913 if (i === 0) { 1914 i = _indexOf(val, self.dateSettings.months) + 1; 1915 } 1916 return i; 1917 }, 1918 parseDate: function (vDate, vFormat) { 1919 var self = this, vFormatParts, vDateParts, i, vDateFlag = false, vTimeFlag = false, vDatePart, iDatePart, 1920 vSettings = self.dateSettings, vMonth, vMeriIndex, vMeriOffset, len, mer, 1921 out = {date: null, year: null, month: null, day: null, hour: 0, min: 0, sec: 0}; 1922 if (!vDate) { 1923 return null; 1924 } 1925 if (vDate instanceof Date) { 1926 return vDate; 1927 } 1928 if (vFormat === 'U') { 1929 i = parseInt(vDate); 1930 return i ? new Date(i * 1000) : vDate; 1931 } 1932 switch (typeof vDate) { 1933 case 'number': 1934 return new Date(vDate); 1935 case 'string': 1936 break; 1937 default: 1938 return null; 1939 } 1940 vFormatParts = vFormat.match(self.validParts); 1941 if (!vFormatParts || vFormatParts.length === 0) { 1942 throw new Error("Invalid date format definition."); 1943 } 1944 vDateParts = vDate.replace(self.separators, '\0').split('\0'); 1945 for (i = 0; i < vDateParts.length; i++) { 1946 vDatePart = vDateParts[i]; 1947 iDatePart = parseInt(vDatePart); 1948 switch (vFormatParts[i]) { 1949 case 'y': 1950 case 'Y': 1951 if (iDatePart) { 1952 len = vDatePart.length; 1953 out.year = len === 2 ? parseInt((iDatePart < 70 ? '20' : '19') + vDatePart) : iDatePart; 1954 } else { 1955 return null; 1956 } 1957 vDateFlag = true; 1958 break; 1959 case 'm': 1960 case 'n': 1961 case 'M': 1962 case 'F': 1963 if (isNaN(iDatePart)) { 1964 vMonth = self.getMonth(vDatePart); 1965 if (vMonth > 0) { 1966 out.month = vMonth; 1967 } else { 1968 return null; 1969 } 1970 } else { 1971 if (iDatePart >= 1 && iDatePart <= 12) { 1972 out.month = iDatePart; 1973 } else { 1974 return null; 1975 } 1976 } 1977 vDateFlag = true; 1978 break; 1979 case 'd': 1980 case 'j': 1981 if (iDatePart >= 1 && iDatePart <= 31) { 1982 out.day = iDatePart; 1983 } else { 1984 return null; 1985 } 1986 vDateFlag = true; 1987 break; 1988 case 'g': 1989 case 'h': 1990 vMeriIndex = (vFormatParts.indexOf('a') > -1) ? vFormatParts.indexOf('a') : 1991 (vFormatParts.indexOf('A') > -1) ? vFormatParts.indexOf('A') : -1; 1992 mer = vDateParts[vMeriIndex]; 1993 if (vMeriIndex !== -1) { 1994 vMeriOffset = _compare(mer, vSettings.meridiem[0]) ? 0 : 1995 (_compare(mer, vSettings.meridiem[1]) ? 12 : -1); 1996 if (iDatePart >= 1 && iDatePart <= 12 && vMeriOffset !== -1) { 1997 out.hour = iDatePart % 12 === 0 ? vMeriOffset : iD
1997atePart + vMeriOffset; 1998 } else { 1999 if (iDatePart >= 0 && iDatePart <= 23) { 2000 out.hour = iDatePart; 2001 } 2002 } 2003 } else { 2004 if (iDatePart >= 0 && iDatePart <= 23) { 2005 out.hour = iDatePart; 2006 } else { 2007 return null; 2008 } 2009 } 2010 vTimeFlag = true; 2011 break; 2012 case 'G': 2013 case 'H': 2014 if (iDatePart >= 0 && iDatePart <= 23) { 2015 out.hour = iDatePart; 2016 } else { 2017 return null; 2018 } 2019 vTimeFlag = true; 2020 break; 2021 case 'i': 2022 if (iDatePart >= 0 && iDatePart <= 59) { 2023 out.min = iDatePart; 2024 } else { 2025 return null; 2026 } 2027 vTimeFlag = true; 2028 break; 2029 case 's': 2030 if (iDatePart >= 0 && iDatePart <= 59) { 2031 out.sec = iDatePart; 2032 } else { 2033 return null; 2034 } 2035 vTimeFlag = true; 2036 break; 2037 } 2038 } 2039 if (vDateFlag === true && out.year && out.month && out.day) { 2040 out.date = new Date(out.year, out.month - 1, out.day, out.hour, out.min, out.sec, 0); 2041 } else { 2042 if (vTimeFlag !== true) { 2043 return null; 2044 } 2045 out.date = new Date(0, 0, 0, out.hour, out.min, out.sec, 0); 2046 } 2047 return out.date; 2048 }, 2049 guessDate: function (vDateStr, vFormat) { 2050 if (typeof vDateStr !== 'string') { 2051 return vDateStr; 2052 } 2053 var self = this, vParts = vDateStr.replace(self.separators, '\0').split('\0'), vPattern = /^[djmn]/g, len, 2054 vFormatParts = vFormat.match(self.validParts), vDate = new Date(), vDigit = 0, vYear, i, n, iPart, iSec; 2055 2056 if (!vPattern.test(vFormatParts[0])) { 2057 return vDateStr; 2058 } 2059 2060 for (i = 0; i < vParts.length; i++) { 2061 vDigit = 2; 2062 iPart = vParts[i]; 2063 iSec = parseInt(iPart.substr(0, 2)); 2064 if (isNaN(iSec)) { 2065 return null; 2066 } 2067 switch (i) { 2068 case 0: 2069 if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { 2070 vDate.setMonth(iSec - 1); 2071 } else { 2072 vDate.setDate(iSec); 2073 } 2074 break; 2075 case 1: 2076 if (vFormatParts[0] === 'm' || vFormatParts[0] === 'n') { 2077 vDate.setDate(iSec); 2078 } else { 2079 vDate.setMonth(iSec - 1); 2080 } 2081 break; 2082 case 2: 2083 vYear = vDate.getFullYear(); 2084 len = iPart.length; 2085 vDigit = len < 4 ? len : 4; 2086 vYear = parseInt(len < 4 ? vYear.toString().substr(0, 4 - len) + iPart : iPart.substr(0, 4)); 2087 if (!vYear) { 2088 return null; 2089 } 2090 vDate.setFullYear(vYear); 2091 break; 2092 case 3: 2093 vDate.setHours(iSec); 2094 break; 2095 case 4: 2096 vDate.setMinutes(iSec); 2097 break; 2098 case 5: 2099 vDate.setSeconds(iSec); 2100 break; 2101 } 2102 n = iPart.substr(vDigit); 2103 if (n.length > 0) { 2104 vParts.splice(i + 1, 0, n); 2105 } 2106 } 2107 return vDate; 2108 }, 2109 parseFormat: function (vChar, vDate) { 2110 var self = this, vSettings = self.dateSettings, fmt, backslash = /\\?(.?)/gi, doFormat = function (t, s) { 2111 return fmt[t] ? fmt[t]() : s; 2112 }; 2113 fmt = {
2114 ///////// 2115 // DAY // 2116 ///////// 2117 /** 2118 * Day of month with leading 0: `01..31` 2119 * @return {string} 2120 */ 2121 d: function () { 2122 return _lpad(fmt.j(), 2); 2123 }, 2124 /** 2125 * Shorthand day name: `Mon...Sun` 2126 * @return {string} 2127 */ 2128 D: function () { 2129 return vSettings.daysShort[fmt.w()]; 2130 }, 2131 /** 2132 * Day of month: `1..31` 2133 * @return {number} 2134 */ 2135 j: function () { 2136 return vDate.getDate(); 2137 }, 2138 /** 2139 * Full day name: `Monday...Sunday` 2140 * @return {number} 2141 */ 2142 l: function () { 2143 return vSettings.days[fmt.w()]; 2144 }, 2145 /** 2146 * ISO-8601 day of week: `1[Mon]..7[Sun]` 2147 * @return {number} 2148 */ 2149 N: function () { 2150 return fmt.w() || 7; 2151 }, 2152 /** 2153 * Day of week: `0[Sun]..6[Sat]` 2154 * @return {number} 2155 */ 2156 w: function () { 2157 return vDate.getDay(); 2158 }, 2159 /** 2160 * Day of year: `0..365` 2161 * @return {number} 2162 */ 2163 z: function () { 2164 var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j()), b = new Date(fmt.Y(), 0, 1); 2165 return Math.round((a - b) / DAY); 2166 }, 2167
2168 ////////// 2169 // WEEK // 2170 ////////// 2171 /** 2172 * ISO-8601 week number 2173 * @return {number} 2174 */ 2175 W: function () { 2176 var a = new Date(fmt.Y(), fmt.n() - 1, fmt.j() - fmt.N() + 3), b = new Date(a.getFullYear(), 0, 4); 2177 return _lpad(1 + Math.round((a - b) / DAY / 7), 2); 2178 }, 2179 2180 /////////// 2181 // MONTH // 2182 /////////// 2183 /** 2184 * Full month name: `January...December` 2185 * @return {string} 2186 */ 2187 F: function () { 2188 return vSettings.months[vDate.getMonth()]; 2189 }, 2190 /** 2191 * Month w/leading 0: `01..12` 2192 * @return {string} 2193 */ 2194 m: function () { 2195 return _lpad(fmt.n(), 2); 2196 }, 2197 /** 2198 * Shorthand month name; `Jan...Dec` 2199 * @return {string} 2200 */ 2201 M: function () { 2202 return vSettings.monthsShort[vDate.getMonth()]; 2203 }, 2204 /** 2205 * Month: `1...12` 2206 * @return {number} 2207 */ 2208 n: function () { 2209 return vDate.getMonth() + 1; 2210 }, 2211 /** 2212 * Days in month: `28...31` 2213 * @return {number} 2214 */ 2215 t: function () { 2216 return (new Date(fmt.Y(), fmt.n(), 0)).getDate(); 2217 }, 2218
2219 ////////// 2220 // YEAR // 2221 ////////// 2222 /** 2223 * Is leap year? `0 or 1` 2224 * @return {number} 2225 */ 2226 L: function () { 2227 var Y = fmt.Y(); 2228 return (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) ? 1 : 0; 2229 }, 2230 /** 2231 * ISO-8601 year 2232 * @return {number} 2233 */ 2234 o: function () { 2235 var n = fmt.n(), W = fmt.W(), Y = fmt.Y(); 2236 return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0); 2237 }, 2238 /** 2239 * Full year: `e.g. 1980...2010` 2240 * @return {number} 2241 */ 2242 Y: function () { 2243 return vDate.getFullYear(); 2244 }, 2245 /** 2246 * Last two digits of year: `00...99` 2247 * @return {string} 2248 */ 2249 y: function () { 2250 return fmt.Y().toString().slice(-2); 2251 }, 2252
2253 ////////// 2254 // TIME // 2255 ////////// 2256 /** 2257 * Meridian lower: `am or pm` 2258 * @return {string} 2259 */ 2260 a: function () { 2261 return fmt.A().toLowerCase(); 2262 }, 2263 /** 2264 * Meridian upper: `AM or PM` 2265 * @return {string} 2266 */ 2267 A: function () { 2268 var n = fmt.G() < 12 ? 0 : 1; 2269 return vSettings.meridiem[n]; 2270 }, 2271 /** 2272 * Swatch Internet time: `000..999` 2273 * @return {string} 2274 */ 2275 B: function () { 2276 var H = vDate.getUTCHours() * HOUR, i = vDate.getUTCMinutes() * 60, s = vDate.getUTCSeconds(); 2277 return _lpad(Math.floor((H + i + s + HOUR) / 86.4) % 1000, 3); 2278 }, 2279 /** 2280 * 12-Hours: `1..12` 2281 * @return {number} 2282 */ 2283 g: function () { 2284 return fmt.G() % 12 || 12; 2285 }, 2286 /** 2287 * 24-Hours: `0..23` 2288 * @return {number} 2289 */ 2290 G: function () { 2291 return vDate.getHours(); 2292 }, 2293 /** 2294 * 12-Hours with leading 0: `01..12` 2295 * @return {string} 2296 */ 2297 h: function () { 2298 return _lpad(fmt.g(), 2); 2299 }, 2300 /** 2301 * 24-Hours w/leading 0: `00..23` 2302 * @return {string} 2303 */ 2304 H: function () { 2305 return _lpad(fmt.G(), 2); 2306 }, 2307 /** 2308 * Minutes w/leading 0: `00..59` 2309 * @return {string} 2310 */ 2311 i: function () { 2312 return _lpad(vDate.getMinutes(), 2); 2313 }, 2314 /** 2315 * Seconds w/leading 0: `00..59` 2316 * @return {string} 2317 */ 2318 s: function () { 2319 return _lpad(vDate.getSeconds(), 2); 2320 }, 2321 /** 2322 * Microseconds: `000000-999000` 2323 * @return {string} 2324 */ 2325 u: function () { 2326 return _lpad(vDate.getMilliseconds() * 1000, 6); 2327 }, 2328
2329 ////////////// 2330 // TIMEZONE // 2331 ////////////// 2332 /** 2333 * Timezone identifier: `e.g. Atlantic/Azores, ...` 2334 * @return {string} 2335 */ 2336 e: function () { 2337 var str = /\((.*)\)/.exec(String(vDate))[1]; 2338 return str || 'Coordinated Universal Time'; 2339 }, 2340 /** 2341 * DST observed? `0 or 1` 2342 * @return {number} 2343 */ 2344 I: function () { 2345 var a = new Date(fmt.Y(), 0), c = Date.UTC(fmt.Y(), 0), 2346 b = new Date(fmt.Y(), 6), d = Date.UTC(fmt.Y(), 6); 2347 return ((a - c) !== (b - d)) ? 1 : 0; 2348 }, 2349 /** 2350 * Difference to GMT in hour format: `e.g. +0200` 2351 * @return {string} 2352 */ 2353 O: function () { 2354 var tzo = vDate.getTimezoneOffset(), a = Math.abs(tzo); 2355 return (tzo > 0 ? '-' : '+') + _lpad(Math.floor(a / 60) * 100 + a % 60, 4); 2356 }, 2357 /** 2358 * Difference to GMT with colon: `e.g. +02:00` 2359 * @return {string} 2360 */ 2361 P: function () { 2362 var O = fmt.O(); 2363 return (O.substr(0, 3) + ':' + O.substr(3, 2)); 2364 }, 2365 /** 2366 * Timezone abbreviation: `e.g. EST, MDT, ...` 2367 * @return {string} 2368 */ 2369 T: function () { 2370 var str = (String(vDate).match(self.tzParts) || [""]).pop().replace(self.tzClip, ""); 2371 return str || 'UTC'; 2372 }, 2373 /** 2374 * Timezone offset in seconds: `-43200...50400` 2375 * @return {number} 2376 */ 2377 Z: function () { 2378 return -vDate.getTimezoneOffset() * 60; 2379 }, 2380
2381 //////////////////// 2382 // FULL DATE TIME // 2383 //////////////////// 2384 /** 2385 * ISO-8601 date 2386 * @return {string} 2387 */ 2388 c: function () { 2389 return 'Y-m-d\\TH:i:sP'.replace(backslash, doFormat); 2390 }, 2391 /** 2392 * RFC 2822 date 2393 * @return {string} 2394 */ 2395 r: function () { 2396 return 'D, d M Y H:i:s O'.replace(backslash, doFormat); 2397 }, 2398 /** 2399 * Seconds since UNIX epoch 2400 * @return {number} 2401 */ 2402 U: function () { 2403 return vDate.getTime() / 1000 || 0; 2404 } 2405 }; 2406 return doFormat(vChar, vChar); 2407 }, 2408 formatDate: function (vDate, vFormat) { 2409 var self = this, i, n, len, str, vChar, vDateStr = '', BACKSLASH = '\\'; 2410 if (typeof vDate === 'string') { 2411 vDate = self.parseDate(vDate, vFormat); 2412 if (!vDate) { 2413 return null; 2414 } 2415 } 2416 if (vDate instanceof Date) { 2417 len = vFormat.length; 2418 for (i = 0; i < len; i++) { 2419 vChar = vFormat.charAt(i); 2420 if (vChar === 'S' || vChar === BACKSLASH) { 2421 continue; 2422 } 2423 if (i > 0 && vFormat.charAt(i - 1) === BACKSLASH) { 2424 vDateStr += vChar; 2425 continue; 2426 } 2427 str = self.parseFormat(vChar, vDate); 2428 if (i !== (len - 1) && self.intParts.test(vChar) && vFormat.charAt(i + 1) === 'S') { 2429 n = parseInt(str) || 0; 2430 str += self.dateSettings.ordinal(n); 2431 } 2432 vDateStr += str; 2433 } 2434 return vDateStr; 2435 } 2436 return ''; 2437 } 2438 }; 2439})(); 2440/*! 2441 * Laravel Javascript Validation 2442 * 2443 * https://github.com/proengsoft/laravel-jsvalidation 2444 * 2445 * Copyright (c) 2017 Proengsoft 2446 * Released under the MIT license 2447 */ 2448 2449var laravelValidation; 2450laravelValidation = { 2451 2452 implicitRules: ['Required','Confirmed'], 2453 2454 /** 2455 * Initialize laravel validations. 2456 */ 2457 init: function () { 2458 2459 // Disable class rules and attribute rules 2460 $.validator.classRuleSettings = {}; 2461 $.validator.attributeRules = function () { 2462 this.rules = {} 2463 }; 2464 2465 $.validator.dataRules = this.arrayRules; 2466 $.validator.prototype.arrayRulesCache = {}; 2467 // Register validations methods 2468 this.setupValidations(); 2469 }, 2470 2471 arrayRules: function(element) { 2472 2473 var rules = {}, 2474 validator = $.data( element.form, "validator"), 2475 cache = validator.arrayRulesCache; 2476 2477 // Is not an Array 2478 if (element.name.indexOf('[') === -1 ) { 2479 return rules; 2480 } 2481 2482 if (! (element.name in cache) ) { 2483 cache[element.name]={}; 2484 } 2485 2486 $.each(validator.settings.rules, function(name, tmpRules){ 2487 if (name in cache[element.name]) { 2488 $.extend(rules, cache[element.name][name]); 2489 } else { 2490 cache[element.name][name]={}; 2491 var nameRegExp = laravelValidation.helpers.regexFromWildcard(name); 2492 if (element.name.match(nameRegExp)) { 2493 var newRules = $.validator.normalizeRule( tmpRules ) || {}; 2494 cache[element.name][name]=newRules; 2495 $.extend(rules, newRules); 2496 } 2497 } 2498 }); 2499 2500 return rules; 2501 }, 2502 2503 setupValidations: function () { 2504 2505 /** 2506 * Create JQueryValidation check to validate Laravel rules. 2507 */ 2508 2509 $.validator.addMethod("laravelValidation", function (value, element, params) {
2510 var validator = this; 2511 var validated = true; 2512 var previous = this.previousValue( element ); 2513 2514 // put Implicit rules in front 2515 var rules=[]; 2516 $.each(params, function (i, param) { 2517 if (param[3] || laravelValidation.implicitRules.indexOf(param[0])!== -1) { 2518 rules.unshift(param); 2519 } else { 2520 rules.push(param); 2521 } 2522 }); 2523 2524 $.each(rules, function (i, param) { 2525 var implicit = param[3] || laravelValidation.implicitRules.indexOf(param[0])!== -1; 2526 var rule = param[0]; 2527 var message = param[2]; 2528 2529 if ( !implicit && validator.optional( element ) ) { 2530 validated="dependency-mismatch"; 2531 return false; 2532 } 2533 2534 if (laravelValidation.methods[rule]!==undefined) { 2535 validated = laravelValidation.methods[rule].call(validator, value, element, param[1], function(valid) { 2536 validator.settings.messages[ element.name ].laravelValidationRemote = previous.originalMessage; 2537 if ( valid ) { 2538 var submitted = validator.formSubmitted; 2539 validator.prepareElement( element ); 2540 validator.formSubmitted = submitted; 2541 validator.successList.push( element ); 2542 delete validator.invalid[ element.name ]; 2543 validator.showErrors(); 2544 } else { 2545 var errors = {}; 2546 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message; 2547 validator.invalid[ element.name ] = true; 2548 validator.showErrors( errors ); 2549 } 2550 validator.showErrors(validator.errorMap); 2551 previous.valid = valid; 2552 }); 2553 } else { 2554 validated=false; 2555 } 2556 2557 if (validated !== true) { 2558 if (!validator.settings.messages[ element.name ] ) { 2559 validator.settings.messages[ element.name ] = {}; 2560 } 2561 validator.settings.messages[element.name].laravelValidation= message; 2562 return false; 2563 } 2564 2565 }); 2566 return validated; 2567 2568 }, ''); 2569 2570 2571 /** 2572 * Create JQueryValidation check to validate Remote Laravel rules. 2573 */ 2574 $.validator.addMethod("laravelValidationRemote", function (value, element, params) { 2575 2576 var implicit = false, 2577 check = params[0][1], 2578 attribute = element.name, 2579 token = check[1], 2580 validateAll = check[2]; 2581 2582 $.each(params, function (i, parameters) { 2583 implicit = implicit || parameters[3]; 2584 }); 2585 2586 2587 if ( !implicit && this.optional( element ) ) { 2588 return "dependency-mismatch"; 2589 } 2590 2591 var previous = this.previousValue( element ), 2592 validator, data; 2593 2594 if (!this.settings.messages[ element.name ] ) { 2595 this.settings.messages[ element.name ] = {}; 2596 } 2597 previous.originalMessage = this.settings.messages[ element.name ].laravelValidationRemote; 2598 this.settings.messages[ element.name ].laravelValidationRemote = previous.message; 2599 2600 var param = typeof param === "string" && { url: param } || param; 2601 2602 if (laravelValidation.helpers.arrayEquals(previous.old, value) || previous.old === value) { 2603 return previous.valid; 2604 } 2605 2606 previous.old = value; 2607 validator = this; 2608 this.startRequest( element ); 2609 2610 data = $(validator.currentForm).serializeArray(); 2611 2612 data.push({ 2613 'name': '_jsvalidation', 2614 'value': attribute 2615 }); 2616 2617 data.push({ 2618 'name': '_jsvalidation_validate_all', 2619 'value': validateAll 2620 }); 2621 2622 var formMethod = $(validator.currentForm).attr('method'); 2623 if($(validator.currentForm).find('input[name="_method"]').length) { 2624 formMethod = $(validator.currentForm).find('input[name="_method"]').val(); 2625 } 2626 2627 $.ajax( $.extend( true, { 2628 mode: "abort", 2629 port: "validate" + element.name, 2630 dataType: "json", 2631 data: data, 2632 context: validator.currentForm, 2633 url: $(validator.currentForm).attr('action'), 2634 type: formMethod, 2635 2636 beforeSend: function (xhr) { 2637 if ($(validator.currentForm).attr('method').toLowerCase() !== 'get' && token) { 2638 return xhr.setRequestHeader('X-XSRF-TOKEN', token); 2639 } 2640 } 2641 }, param ) 2642 ).always(function( response, textStatus ) { 2643 var errors, message, submitted, valid; 2644 2645 if (textStatus === 'error') { 2646 valid = false; 2647 response = laravelValidation.helpers.parseErrorResponse(response); 2648 } else if (textStatus === 'success') { 2649 valid = response === true || response === "true"; 2650 } else { 2651 return; 2652 } 2653 2654 validator.settings.messages[ element.name ].laravelValidationRemote = previous.originalMessage; 2655 2656 if ( valid ) { 2657 submitted = validator.formSubmitted; 2658 validator.prepareElement( element ); 2659 validator.formSubmitted = submitted; 2660 validator.successList.push( element );
2661 delete validator.invalid[ element.name ]; 2662 validator.showErrors(); 2663 } else { 2664 errors = {}; 2665 message = response || validator.defaultMessage( element, "remote" ); 2666 errors[ element.name ] = previous.message = $.isFunction( message ) ? message( value ) : message[0]; 2667 validator.invalid[ element.name ] = true; 2668 validator.showErrors( errors ); 2669 } 2670 validator.showErrors(validator.errorMap); 2671 previous.valid = valid; 2672 validator.stopRequest( element, valid ); 2673 } 2674 ); 2675 return "pending"; 2676 }, ''); 2677 } 2678}; 2679 2680$(function() { 2681 laravelValidation.init(); 2682}); 2683 2684/*! 2685 * Laravel Javascript Validation 2686 * 2687 * https://github.com/proengsoft/laravel-jsvalidation 2688 * 2689 * Helper functions used by validators 2690 * 2691 * Copyright (c) 2017 Proengsoft 2692 * Released under the MIT license 2693 */ 2694 2695$.extend(true, laravelValidation, { 2696 2697 helpers: { 2698 2699 /** 2700 * Numeric rules 2701 */ 2702 numericRules: ['Integer', 'Numeric'], 2703 2704 /** 2705 * Gets the file information from file input. 2706 * 2707 * @param fieldObj 2708 * @param index 2709 * @returns {{file: *, extension: string, size: number}} 2710 */ 2711 fileinfo: function (fieldObj, index) { 2712 var FileName = fieldObj.value; 2713 index = typeof index !== 'undefined' ? index : 0; 2714 if ( fieldObj.files !== null ) { 2715 if (typeof fieldObj.files[index] !== 'undefined') { 2716 return { 2717 file: FileName, 2718 extension: FileName.substr(FileName.lastIndexOf('.') + 1), 2719 size: fieldObj.files[index].size / 1024, 2720 type: fieldObj.files[index].type 2721 }; 2722 } 2723 } 2724 return false; 2725 }, 2726 2727 2728 /** 2729 * Gets the selectors for th specified field names. 2730 * 2731 * @param names 2732 * @returns {string} 2733 */ 2734 selector: function (names) { 2735 var selector = []; 2736 if (!$.isArray(names)) { 2737 names = [names]; 2738 } 2739 for (var i = 0; i < names.length; i++) { 2740 selector.push("[name='" + names[i] + "']"); 2741 } 2742 return selector.join(); 2743 }, 2744 2745 2746 /** 2747 * Check if element has numeric rules. 2748 * 2749 * @param element 2750 * @returns {boolean} 2751 */ 2752 hasNumericRules: function (element) { 2753 return this.hasRules(element, this.numericRules); 2754 }, 2755 2756 /** 2757 * Check if element has passed rules. 2758 * 2759 * @param element 2760 * @param rules 2761 * @returns {boolean} 2762 */ 2763 hasRules: function (element, rules) { 2764 2765 var found = false; 2766 if (typeof rules === 'string') { 2767 rules = [rules]; 2768 } 2769 2770 var validator = $.data(element.form, "validator"); 2771 var listRules = []; 2772 var cache = validator.arrayRulesCache; 2773 if (element.name in cache) { 2774 $.each(cache[element.name], function (index, arrayRule) { 2775 listRules.push(arrayRule); 2776 }); 2777 } 2778 if (element.name in validator.settings.rules) { 2779 listRules.push(validator.settings.rules[element.name]); 2780 } 2781 $.each(listRules, function(index,objRules){ 2782 if ('laravelValidation' in objRules) { 2783 var _rules=objRules.laravelValidation; 2784 for (var i = 0; i < _rules.length; i++) { 2785 if ($.inArray(_rules[i][0],rules) !== -1) { 2786 found = true; 2787 return false; 2788 } 2789 } 2790 } 2791 }); 2792 2793 return found; 2794 }, 2795 2796 /** 2797 * Return the string length using PHP function. 2798 * http://php.net/manual/en/function.strlen.php 2799 * http://phpjs.org/functions/strlen/ 2800 * 2801 * @param string 2802 */ 2803 strlen: function (string) { 2804 return strlen(string); 2805 }, 2806 2807 /** 2808 * Get the size of the object depending of his type. 2809 * 2810 * @param obj 2811 * @param element 2812 * @param value 2813 * @returns int 2814 */ 2815 getSize: function getSize(obj, element, value) { 2816 2817 if (this.hasNumericRules(element) && this.is_numeric(value)) { 2818 return parseFloat(value); 2819 } else if ($.isArray(value)) { 2820 return parseFloat(value.length); 2821 } else if (element.type === 'file') { 2822 return parseFloat(Math.floor(this.fileinfo(element).size)); 2823 } 2824 2825 return parseFloat(this.strlen(value)); 2826 }, 2827 2828 2829 /** 2830 * Return specified rule from element. 2831 * 2832 * @param rule 2833 * @param element 2834 * @returns object 2835 */ 2836 getLaravelValidation: function(rule, element) { 2837 2838 var found = undefined; 2839 $.each($.validator.staticRules(element), function(key, rules) { 2840 if (key==="laravelValidation") { 2841 $.each(rules, function (i, value) { 2842 if (value[0]===rule) { 2843 found=value; 2844 } 2845 }); 2846 } 2847 }); 2848 2849 return found; 2850 }, 2851 2852 /** 2853 * Return he timestamp of value passed using format or default format in element. 2854 * 2855 * @param value 2856 * @param format 2857 * @returns {boolean|int} 2858 */ 2859 parseTime: function (value, format) { 2860 2861 var timeValue = false; 2862 var fmt = new DateFormatter(); 2863 2864 if ($.type(format) === 'object') { 2865 var dateRule=this.getLaravelValidation('DateFormat', format); 2866 if (dateRule !== undefined) { 2867 format = dateRule[1][0]; 2868 } else { 2869 format = null; 2870 } 2871 } 2872 2873 if (format == null) { 2874 timeValue = this.strtotime(value); 2875 } else { 2876 timeValue = fmt.parseDate(value, format); 2877 if (timeValue) { 2878 timeValue = Math.round((timeValue.getTime() / 1000)); 2879 } 2880 } 2881 2882 return timeValue; 2883 }, 2884 2885 /** 2886 * This method allows you to intelligently guess the date by closely matching the specific format. 2887 * 2888 * @param value 2889 * @param format 2890 * @returns {Date} 2891 */ 2892 guessDate: function (value, format) { 2893 var fmt = new DateFormatter(); 2894 return fmt.guessDate(value, format) 2895 }, 2896 2897 /** 2898 * Returns Unix timestamp based on PHP function strototime. 2899 * http://php.net/manual/es/function.strtotime.php 2900 * http://phpjs.org/functions/strtotime/ 2901 * 2902 * @param text 2903 * @param now 2904 * @returns {*} 2905 */ 2906 strtotime: function (text, now) { 2907 return strtotime(text, now) 2908 }, 2909 2910 /** 2911 * Returns if value is numeric. 2912 * http://php.net/manual/es/var.is_numeric.php 2913 * http://phpjs.org/functions/is_numeric/ 2914 * 2915 * @param mixed_var 2916 * @returns {*} 2917 */ 2918 is_numeric: function (mixed_var) { 2919 return is_numeric(mixed_var) 2920 }, 2921 2922 /** 2923 * Returns Array diff based on PHP function array_diff. 2924 * http://php.net/manual/es/function.array_diff.php 2925 * http://phpjs.org/functions/array_diff/ 2926 * 2927 * @param arr1 2928 * @param arr2 2929 * @returns {*} 2930 */ 2931 arrayDiff: function (arr1, arr2) { 2932 return array_diff(arr1, arr2); 2933 }, 2934 2935 /** 2936 * Check whether two arrays are equal to one another. 2937 * 2938 * @param arr1 2939 * @param arr2 2940 * @returns {*} 2941 */ 2942 arrayEquals: function (arr1, arr2) { 2943 if (! $.isArray(arr1) || ! $.isArray(arr2)) { 2944 return false; 2945 } 2946 2947 if (arr1.length !== arr2.length) { 2948 return false; 2949 } 2950 2951 return $.isEmptyObject(this.arrayDiff(arr1, arr2)); 2952 }, 2953 2954 /** 2955 * Makes element dependant from other. 2956 * 2957 * @param validator 2958 * @param element 2959 * @param name 2960 * @returns {*} 2961 */
2962 dependentElement: function(validator, element, name) { 2963 2964 var el=validator.findByName(name); 2965 2966 if ( el[0]!==undefined && validator.settings.onfocusout ) { 2967 var event = 'blur'; 2968 if (el[0].tagName === 'SELECT' || 2969 el[0].tagName === 'OPTION' || 2970 el[0].type === 'checkbox' || 2971 el[0].type === 'radio' 2972 ) { 2973 event = 'click'; 2974 } 2975 2976 var ruleName = '.validate-laravelValidation'; 2977 el.off( ruleName ) 2978 .off(event + ruleName + '-' + element.name) 2979 .on( event + ruleName + '-' + element.name, function() { 2980 $( element ).valid(); 2981 }); 2982 } 2983 2984 return el[0]; 2985 }, 2986 2987 /** 2988 * Parses error Ajax response and gets the message. 2989 * 2990 * @param response 2991 * @returns {string[]} 2992 */ 2993 parseErrorResponse: function (response) { 2994 var newResponse = ['Whoops, looks like something went wrong.']; 2995 if ('responseText' in response) { 2996 var errorMsg = response.responseText.match(/<h1\s*>(.*)<\/h1\s*>/i); 2997 if ($.isArray(errorMsg)) { 2998 newResponse = [errorMsg[1]]; 2999 } 3000 } 3001 return newResponse; 3002 }, 3003 3004 /** 3005 * Escape string to use as Regular Expression. 3006 * 3007 * @param str 3008 * @returns string 3009 */ 3010 escapeRegExp: function (str) { 3011 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 3012 }, 3013 3014 /** 3015 * Generate RegExp from wildcard attributes. 3016 * 3017 * @param name 3018 * @returns {RegExp} 3019 */ 3020 regexFromWildcard: function(name) { 3021 var nameParts = name.split("[*]"); 3022 if (nameParts.length === 1) { 3023 nameParts.push(''); 3024 } 3025 var regexpParts = nameParts.map(function(currentValue, index) { 3026 if (index % 2 === 0) { 3027 currentValue = currentValue + '['; 3028 } else { 3029 currentValue = ']' +currentValue; 3030 } 3031 3032 return laravelValidation.helpers.escapeRegExp(currentValue); 3033 }); 3034 3035 return new RegExp('^'+regexpParts.join('.*')+'$'); 3036 } 3037 } 3038}); 3039 3040/*! 3041 * Laravel Javascript Validation 3042 * 3043 * https://github.com/proengsoft/laravel-jsvalidation 3044 * 3045 * Timezone Helper functions used by validators 3046 * 3047 * Copyright (c) 2017 Proengsoft 3048 * Released under the MIT license 3049 */ 3050 3051$.extend(true, laravelValidation, { 3052 3053 helpers: { 3054 3055 /** 3056 * Check if the specified timezone is valid. 3057 * 3058 * @param value 3059 * @returns {boolean} 3060 */ 3061 isTimezone: function (value) { 3062 3063 var timezones={ 3064 "africa": [ 3065 "abidjan", 3066 "accra", 3067 "addis_ababa", 3068 "algiers", 3069 "asmara", 3070 "bamako", 3071 "bangui", 3072 "banjul", 3073 "bissau", 3074 "blantyre", 3075 "brazzaville", 3076 "bujumbura", 3077 "cairo", 3078 "casablanca", 3079 "ceuta", 3080 "conakry", 3081 "dakar", 3082 "dar_es_salaam", 3083 "djibouti", 3084 "douala", 3085 "el_aaiun", 3086 "freetown", 3087 "gaborone", 3088 "harare", 3089 "johannesburg", 3090 "juba", 3091 "kampala", 3092 "khartoum", 3093 "kigali", 3094 "kinshasa", 3095 "lagos", 3096 "libreville", 3097 "lome", 3098 "luanda", 3099 "lubumbashi", 3100 "lusaka", 3101 "malabo", 3102 "maputo", 3103 "maseru", 3104 "mbabane", 3105 "mogadishu", 3106 "monrovia", 3107 "nairobi", 3108 "ndjamena", 3109 "niamey", 3110 "nouakchott", 3111 "ouagadougou", 3112 "porto-novo", 3113 "sao_tome", 3114 "tripoli", 3115 "tunis", 3116 "windhoek" 3117 ], 3118 "america": [ 3119 "adak", 3120 "anchorage", 3121 "anguilla", 3122 "antigua", 3123 "araguaina", 3124 "argentina\/buenos_aires", 3125 "argentina\/catamarca", 3126 "argentina\/cordoba", 3127 "argentina\/jujuy", 3128 "argentina\/la_rioja", 3129 "argentina\/mendoza", 3130 "argentina\/rio_gallegos", 3131 "argentina\/salta", 3132 "argentina\/san_juan", 3133 "argentina\/san_luis", 3134 "argentina\/tucuman", 3135 "argentina\/ushuaia", 3136 "aruba", 3137 "asuncion", 3138 "atikokan", 3139 "bahia", 3140 "bahia_banderas", 3141 "barbados", 3142 "belem", 3143 "belize", 3144 "blanc-sablon", 3145 "boa_vista", 3146 "bogota", 3147 "boise", 3148 "cambridge_bay", 3149 "campo_grande", 3150 "cancun", 3151 "caracas", 3152 "cayenne", 3153 "cayman", 3154 "chicago", 3155 "chihuahua", 3156 "costa_rica", 3157 "creston", 3158 "cuiaba", 3159 "curacao", 3160 "danmarkshavn", 3161 "dawson", 3162 "dawson_creek", 3163 "denver", 3164 "detroit", 3165 "dominica", 3166 "edmonton", 3167 "eirunepe", 3168 "el_salvador", 3169 "fortaleza", 3170 "glace_bay", 3171 "godthab",
3172 "goose_bay", 3173 "grand_turk", 3174 "grenada", 3175 "guadeloupe", 3176 "guatemala", 3177 "guayaquil", 3178 "guyana", 3179 "halifax", 3180 "havana", 3181 "hermosillo", 3182 "indiana\/indianapolis", 3183 "indiana\/knox", 3184 "indiana\/marengo", 3185 "indiana\/petersburg", 3186 "indiana\/tell_city", 3187 "indiana\/vevay", 3188 "indiana\/vincennes", 3189 "indiana\/winamac", 3190 "inuvik", 3191 "iqaluit", 3192 "jamaica", 3193 "juneau", 3194 "kentucky\/louisville", 3195 "kentucky\/monticello", 3196 "kralendijk", 3197 "la_paz", 3198 "lima", 3199 "los_angeles", 3200 "lower_princes", 3201 "maceio", 3202 "managua", 3203 "manaus", 3204 "marigot", 3205 "martinique", 3206 "matamoros", 3207 "mazatlan", 3208 "menominee", 3209 "merida", 3210 "metlakatla", 3211 "mexico_city", 3212 "miquelon", 3213 "moncton", 3214 "monterrey", 3215 "montevideo", 3216 "montreal", 3217 "montserrat", 3218 "nassau", 3219 "new_york", 3220 "nipigon", 3221 "nome", 3222 "noronha", 3223 "north_dakota\/beulah", 3224 "north_dakota\/center", 3225 "north_dakota\/new_salem", 3226 "ojinaga", 3227 "panama", 3228 "pangnirtung", 3229 "paramaribo", 3230 "phoenix", 3231 "port-au-prince", 3232 "port_of_spain", 3233 "porto_velho", 3234 "puerto_rico", 3235 "rainy_river", 3236 "rankin_inlet", 3237 "recife", 3238 "regina", 3239 "resolute", 3240 "rio_branco", 3241 "santa_isabel", 3242 "santarem", 3243 "santiago", 3244 "santo_domingo", 3245 "sao_paulo", 3246 "scoresbysund", 3247 "shiprock", 3248 "sitka", 3249 "st_barthelemy", 3250 "st_johns", 3251 "st_kitts", 3252 "st_lucia", 3253 "st_thomas", 3254 "st_vincent", 3255 "swift_current", 3256 "tegucigalpa", 3257 "thule", 3258 "thunder_bay", 3259 "tijuana", 3260 "toronto", 3261 "tortola", 3262 "vancouver", 3263 "whitehorse", 3264 "winnipeg", 3265 "yakutat", 3266 "yellowknife" 3267 ], 3268 "antarctica": [ 3269 "casey", 3270 "davis", 3271 "dumontdurville", 3272 "macquarie", 3273 "mawson", 3274 "mcmurdo", 3275 "palmer", 3276 "rothera", 3277 "south_pole", 3278 "syowa", 3279 "vostok" 3280 ], 3281 "arctic": [ 3282 "longyearbyen" 3283 ], 3284 "asia": [ 3285 "aden", 3286 "almaty", 3287 "amman", 3288 "anadyr", 3289 "aqtau", 3290 "aqtobe", 3291 "ashgabat", 3292 "baghdad", 3293 "bahrain", 3294 "baku", 3295 "bangkok", 3296 "beirut", 3297 "bishkek", 3298 "brunei", 3299 "choibalsan", 3300 "chongqing", 3301 "colombo", 3302 "damascus", 3303 "dhaka", 3304 "dili", 3305 "dubai", 3306 "dushanbe", 3307 "gaza", 3308 "harbin", 3309 "hebron", 3310 "ho_chi_minh", 3311 "hong_kong", 3312 "hovd", 3313 "irkutsk", 3314 "jakarta", 3315 "jayapura", 3316 "jerusalem", 3317 "kabul", 3318 "kamchatka", 3319 "karachi", 3320 "kashgar",
3321 "kathmandu", 3322 "khandyga", 3323 "kolkata", 3324 "krasnoyarsk", 3325 "kuala_lumpur", 3326 "kuching", 3327 "kuwait", 3328 "macau", 3329 "magadan", 3330 "makassar", 3331 "manila", 3332 "muscat", 3333 "nicosia", 3334 "novokuznetsk", 3335 "novosibirsk", 3336 "omsk", 3337 "oral", 3338 "phnom_penh", 3339 "pontianak", 3340 "pyongyang", 3341 "qatar", 3342 "qyzylorda", 3343 "rangoon", 3344 "riyadh", 3345 "sakhalin", 3346 "samarkand", 3347 "seoul", 3348 "shanghai", 3349 "singapore", 3350 "taipei", 3351 "tashkent", 3352 "tbilisi", 3353 "tehran", 3354 "thimphu", 3355 "tokyo", 3356 "ulaanbaatar", 3357 "urumqi", 3358 "ust-nera", 3359 "vientiane", 3360 "vladivostok", 3361 "yakutsk", 3362 "yekaterinburg", 3363 "yerevan" 3364 ], 3365 "atlantic": [ 3366 "azores", 3367 "bermuda", 3368 "canary", 3369 "cape_verde", 3370 "faroe", 3371 "madeira", 3372 "reykjavik", 3373 "south_georgia", 3374 "st_helena", 3375 "stanley" 3376 ], 3377 "australia": [ 3378 "adelaide", 3379 "brisbane", 3380 "broken_hill", 3381 "currie", 3382 "darwin", 3383 "eucla", 3384 "hobart", 3385 "lindeman", 3386 "lord_howe", 3387 "melbourne", 3388 "perth", 3389 "sydney" 3390 ], 3391 "europe": [ 3392 "amsterdam", 3393 "andorra", 3394 "athens", 3395 "belgrade", 3396 "berlin", 3397 "bratislava", 3398 "brussels", 3399 "bucharest", 3400 "budapest", 3401 "busingen", 3402 "chisinau", 3403 "copenhagen", 3404 "dublin", 3405 "gibraltar", 3406 "guernsey", 3407 "helsinki", 3408 "isle_of_man", 3409 "istanbul", 3410 "jersey", 3411 "kaliningrad", 3412 "kiev", 3413 "lisbon", 3414 "ljubljana", 3415 "london", 3416 "luxembourg", 3417 "madrid", 3418 "malta", 3419 "mariehamn", 3420 "minsk", 3421 "monaco", 3422 "moscow", 3423 "oslo", 3424 "paris", 3425 "podgorica", 3426 "prague", 3427 "riga", 3428 "rome", 3429 "samara", 3430 "san_marino", 3431 "sarajevo", 3432 "simferopol", 3433 "skopje", 3434 "sofia", 3435 "stockholm", 3436 "tallinn", 3437 "tirane", 3438 "uzhgorod", 3439 "vaduz", 3440 "vatican", 3441 "vienna", 3442 "vilnius", 3443 "volgograd", 3444 "warsaw", 3445 "zagreb", 3446 "zaporozhye", 3447 "zurich" 3448 ], 3449 "indian": [ 3450 "antananarivo", 3451 "chagos", 3452 "christmas", 3453 "cocos", 3454 "comoro", 3455 "kerguelen", 3456 "mahe", 3457 "maldives", 3458 "mauritius", 3459 "mayotte",
3460 "reunion" 3461 ], 3462 "pacific": [ 3463 "apia", 3464 "auckland", 3465 "chatham", 3466 "chuuk", 3467 "easter", 3468 "efate", 3469 "enderbury", 3470 "fakaofo", 3471 "fiji", 3472 "funafuti", 3473 "galapagos", 3474 "gambier", 3475 "guadalcanal", 3476 "guam", 3477 "honolulu", 3478 "johnston", 3479 "kiritimati", 3480 "kosrae", 3481 "kwajalein", 3482 "majuro", 3483 "marquesas", 3484 "midway", 3485 "nauru", 3486 "niue", 3487 "norfolk", 3488 "noumea", 3489 "pago_pago", 3490 "palau", 3491 "pitcairn", 3492 "pohnpei", 3493 "port_moresby", 3494 "rarotonga", 3495 "saipan", 3496 "tahiti", 3497 "tarawa", 3498 "tongatapu", 3499 "wake", 3500 "wallis" 3501 ], 3502 "utc": [ 3503 "" 3504 ] 3505 }; 3506 3507 var tzparts= value.split('/',2); 3508 var continent=tzparts[0].toLowerCase(); 3509 var city=''; 3510 if (tzparts[1]) { 3511 city=tzparts[1].toLowerCase(); 3512 } 3513 3514 return (continent in timezones && ( timezones[continent].length===0 || timezones[continent].indexOf(city)!==-1)) 3515 } 3516 } 3517}); 3518 3519/*! 3520 * Laravel Javascript Validation 3521 * 3522 * https://github.com/proengsoft/laravel-jsvalidation 3523 * 3524 * Methods that implement Laravel Validations 3525 * 3526 * Copyright (c) 2017 Proengsoft 3527 * Released under the MIT license 3528 */ 3529 3530$.extend(true, laravelValidation, { 3531 3532 methods:{ 3533 3534 helpers: laravelValidation.helpers, 3535 3536 jsRemoteTimer:0, 3537 3538 /** 3539 * "Validate" optional attributes. 3540 * Always returns true, just lets us put sometimes in rules. 3541 * 3542 * @return {boolean} 3543 */ 3544 Sometimes: function() { 3545 return true; 3546 }, 3547 3548 /** 3549 * Bail This is the default behaivour os JSValidation. 3550 * Always returns true, just lets us put sometimes in rules. 3551 * 3552 * @return {boolean} 3553 */ 3554 Bail: function() { 3555 return true; 3556 }, 3557 3558 /** 3559 * "Indicate" validation should pass if value is null. 3560 * Always returns true, just lets us put "nullable" in rules. 3561 * 3562 * @return {boolean} 3563 */ 3564 Nullable: function() { 3565 return true; 3566 }, 3567 3568 /** 3569 * Validate the given attribute is filled if it is present. 3570 */ 3571 Filled: function(value, element) { 3572 return $.validator.methods.required.call(this, value, element, true); 3573 }, 3574 3575 3576 /** 3577 * Validate that a required attribute exists. 3578 */ 3579 Required: function(value, element) { 3580 return $.validator.methods.required.call(this, value, element); 3581 }, 3582 3583 /** 3584 * Validate that an attribute exists when any other attribute exists. 3585 * 3586 * @return {boolean} 3587 */ 3588 RequiredWith: function(value, element, params) { 3589 var validator=this, 3590 required=false; 3591 var currentObject=this; 3592 3593 $.each(params,function(i,param) { 3594 var target=laravelValidation.helpers.dependentElement( 3595 currentObject, element, param 3596 ); 3597 required=required || ( 3598 target!==undefined && 3599 $.validator.methods.required.call( 3600 validator, 3601 currentObject.elementValue(target), 3602 target,true 3603 )); 3604 }); 3605 3606 if (required) { 3607 return $.validator.methods.required.call(this, value, element, true); 3608 } 3609 return true; 3610 }, 3611 3612 /** 3613 * Validate that an attribute exists when all other attribute exists. 3614 * 3615 * @return {boolean} 3616 */ 3617 RequiredWithAll: function(value, element, params) {
3618 var validator=this, 3619 required=true; 3620 var currentObject=this; 3621 3622 $.each(params,function(i,param) { 3623 var target=laravelValidation.helpers.dependentElement( 3624 currentObject, element, param 3625 ); 3626 required = required && ( 3627 target!==undefined && 3628 $.validator.methods.required.call( 3629 validator, 3630 currentObject.elementValue(target), 3631 target,true 3632 )); 3633 }); 3634 3635 if (required) { 3636 return $.validator.methods.required.call(this, value, element, true); 3637 } 3638 return true; 3639 }, 3640 3641 /** 3642 * Validate that an attribute exists when any other attribute does not exists. 3643 * 3644 * @return {boolean} 3645 */ 3646 RequiredWithout: function(value, element, params) { 3647 var validator=this, 3648 required=false; 3649 var currentObject=this; 3650 3651 $.each(params,function(i,param) { 3652 var target=laravelValidation.helpers.dependentElement( 3653 currentObject, element, param 3654 ); 3655 required = required || 3656 target===undefined|| 3657 !$.validator.methods.required.call( 3658 validator, 3659 currentObject.elementValue(target), 3660 target,true 3661 ); 3662 }); 3663 3664 if (required) { 3665 return $.validator.methods.required.call(this, value, element, true); 3666 } 3667 return true; 3668 }, 3669 3670 /** 3671 * Validate that an attribute exists when all other attribute does not exists. 3672 * 3673 * @return {boolean} 3674 */ 3675 RequiredWithoutAll: function(value, element, params) { 3676 var validator=this, 3677 required=true, 3678 currentObject=this; 3679 3680 $.each(params,function(i, param) { 3681 var target=laravelValidation.helpers.dependentElement( 3682 currentObject, element, param 3683 ); 3684 required = required && ( 3685 target===undefined || 3686 !$.validator.methods.required.call( 3687 validator, 3688 currentObject.elementValue(target), 3689 target,true 3690 )); 3691 }); 3692 3693 if (required) { 3694 return $.validator.methods.required.call(this, value, element, true); 3695 } 3696 return true; 3697 }, 3698 3699 /** 3700 * Validate that an attribute exists when another attribute has a given value. 3701 * 3702 * @return {boolean} 3703 */ 3704 RequiredIf: function(value, element, params) { 3705 3706 var target=laravelValidation.helpers.dependentElement( 3707 this, element, params[0] 3708 ); 3709 3710 if (target!==undefined) { 3711 var val=String(this.elementValue(target)); 3712 if (typeof val !== 'undefined') { 3713 var data = params.slice(1); 3714 if ($.inArray(val, data) !== -1) { 3715 return $.validator.methods.required.call( 3716 this, value, element, true 3717 ); 3718 } 3719 } 3720 } 3721 3722 return true; 3723 }, 3724 3725 /** 3726 * Validate that an attribute exists when another 3727 * attribute does not have a given value. 3728 * 3729 * @return {boolean} 3730 */ 3731 RequiredUnless: function(value, element, params) { 3732 3733 var target=laravelValidation.helpers.dependentElement( 3734 this, element, params[0] 3735 ); 3736 3737 if (target!==undefined) { 3738 var val=String(this.elementValue(target)); 3739 if (typeof val !== 'undefined') { 3740 var data = params.slice(1); 3741 if ($.inArray(val, data) !== -1) { 3742 return true; 3743 } 3744 } 3745 } 3746 3747 return $.validator.methods.required.call( 3748 this, value, element, true 3749 ); 3750 3751 }, 3752 3753 /** 3754 * Validate that an attribute has a matching confirmation. 3755 * 3756 * @return {boolean} 3757 */ 3758 Confirmed: function(value, element, params) { 3759 return laravelValidation.methods.Same.call(this,value, element, params); 3760 }, 3761 3762 /** 3763 * Validate that two attributes match. 3764 * 3765 * @return {boolean} 3766 */ 3767 Same: function(value, element, params) { 3768 3769 var target=laravelValidation.helpers.dependentElement( 3770 this, element, params[0] 3771 ); 3772 3773 if (target!==undefined) { 3774 return String(value) === String(this.elementValue(target)); 3775 } 3776 return false; 3777 }, 3778 3779 /** 3780 * Validate that the values of an attribute is in another attribute. 3781 * 3782 * @param value 3783 * @param element 3784 * @param params 3785 * @returns {boolean} 3786 * @constructor 3787 */ 3788 InArray: function (value, element, params) { 3789 if (typeof params[0] === 'undefined') { 3790 return false; 3791 } 3792 var elements = this.elements(); 3793 var found = false; 3794 var nameRegExp = laravelValidation.helpers.regexFromWildcard(params[0]); 3795 3796 for ( var i = 0; i < elements.length ; i++ ) { 3797 var targetName = elements[i].name; 3798 if (targetName.match(nameRegExp)) { 3799 var equals = laravelValidation.methods.Same.call(this,value, element, [targetName]); 3800 found = found || equals; 3801 } 3802 } 3803 3804 return found; 3805 }, 3806 3807 /** 3808 * Validate an attribute is unique among other values. 3809 * 3810 * @param value 3811 * @param element 3812 * @param params 3813 * @returns {boolean} 3814 */ 3815 Distinct: function (value, element, params) { 3816 if (typeof params[0] === 'undefined') { 3817 return false; 3818 } 3819 3820 var elements = this.elements(); 3821 var found = false; 3822 var nameRegExp = laravelValidation.helpers.regexFromWildcard(params[0]); 3823 3824 for ( var i = 0; i < elements.length ; i++ ) { 3825 var targetName = elements[i].name; 3826 if (targetName !== element.name && targetName.match(nameRegExp)) { 3827 var equals = laravelValidation.methods.Same.call(this,value, element, [targetName]); 3828 found = found || equals; 3829 } 3830 } 3831 3832 return !found; 3833 }, 3834 3835 3836 /** 3837 * Validate that an attribute is different from another attribute. 3838 * 3839 * @return {boolean} 3840 */ 3841 Different: function(value, element, params) { 3842 return ! laravelValidation.methods.Same.call(this,value, element, params); 3843 }, 3844 3845 /** 3846 * Validate that an attribute was "accepted". 3847 * This validation rule implies the attribute is "required". 3848 * 3849 * @return {boolean} 3850 */ 3851 Accepted: function(value) { 3852 var regex = new RegExp("^(?:(yes|on|1|true))$",'i'); 3853 return regex.test(value); 3854 }, 3855 3856 /** 3857 * Validate that an attribute is an array. 3858 * 3859 * @param value 3860 * @param element 3861 */ 3862 Array: function(value, element) { 3863 if (element.name.indexOf('[') !== -1 && element.name.indexOf(']') !== -1) { 3864 return true; 3865 } 3866 3867 return $.isArray(value); 3868 }, 3869 3870 /** 3871 * Validate that an attribute is a boolean. 3872 * 3873 * @return {boolean} 3874 */ 3875 Boolean: function(value) { 3876 var regex= new RegExp("^(?:(true|false|1|0))$",'i'); 3877 return regex.test(value); 3878 }, 3879 3880 /** 3881 * Validate that an attribute is an integer. 3882 * 3883 * @return {boolean} 3884 */ 3885 Integer: function(value) { 3886 var regex= new RegExp("^(?:-?\\d+)$",'i'); 3887 return regex.test(value); 3888 }, 3889 3890 /** 3891 * Validate that an attribute is numeric. 3892 */ 3893 Numeric: function(value, element) { 3894 return $.validator.methods.number.call(this, value, element, true); 3895 }, 3896 3897 /** 3898 * Validate that an attribute is a string. 3899 * 3900 * @return {boolean} 3901 */ 3902 String: function(value) { 3903 return typeof value === 'string'; 3904 }, 3905 3906 /** 3907 * The field under validation must be numeric and must have an exact length of value. 3908 */ 3909 Digits: function(value, element, params) { 3910 return ( 3911 $.validator.methods.number.call(this, value, element, true) && 3912 value.length === parseInt(params, 10) 3913 ); 3914 }, 3915 3916 /** 3917 * The field under validation must have a length between the given min and max. 3918 */ 3919 DigitsBetween: function(value, element, params) { 3920 return ($.validator.methods.number.call(this, value, element, true) 3921 && value.length>=parseFloat(params[0]) && value.length<=parseFloat(params[1])); 3922 }, 3923 3924 /** 3925 * Validate the size of an attribute. 3926 * 3927 * @return {boolean} 3928 */ 3929 Size: function(value, element, params) { 3930 return laravelValidation.helpers.getSize(this, element,value) === parseFloat(params[0]); 3931 }, 3932 3933 /** 3934 * Validate the size of an attribute is between a set of values. 3935 * 3936 * @return {boolean} 3937 */ 3938 Between: function(value, element, params) { 3939 return ( laravelValidation.helpers.getSize(this, element,value) >= parseFloat(params[0]) && 3940 laravelValidation.helpers.getSize(this,element,value) <= parseFloat(params[1])); 3941 }, 3942 3943 /** 3944 * Validate the size of an attribute is greater than a minimum value. 3945 * 3946 * @return {boolean} 3947 */ 3948 Min: function(value, element, params) { 3949 return laravelValidation.helpers.getSize(this, element,value) >= parseFloat(params[0]); 3950 }, 3951 3952 /** 3953 * Validate the size of an attribute is less than a maximum value. 3954 * 3955 * @return {boolean} 3956 */ 3957 Max: function(value, element, params) { 3958 return laravelValidation.helpers.getSize(this, element,value) <= parseFloat(params[0]); 3959 }, 3960 3961 /** 3962 * Validate an attribute is contained within a list of values. 3963 * 3964 * @return {boolean} 3965 */ 3966 In: function(value, element, params) { 3967 if ($.isArray(value) && laravelValidation.helpers.hasRules(element, "Array")) { 3968 var diff = laravelValidation.helpers.arrayDiff(value, params); 3969 return Object.keys(diff).length === 0; 3970 } 3971 return params.indexOf(value.toString()) !== -1; 3972 }, 3973 3974 /** 3975 * Validate an attribute is not contained within a list of values. 3976 * 3977 * @return {boolean} 3978 */ 3979 NotIn: function(value, element, params) { 3980 return params.indexOf(value.toString()) === -1; 3981 }, 3982 3983 /** 3984 * Validate that an attribute is a valid IP. 3985 * 3986 * @return {boolean} 3987 */ 3988 Ip: function(value) { 3989 return /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value) || 3990 /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value); 3991 }, 3992 3993 /** 3994 * Validate that an attribute is a valid e-mail address. 3995 */ 3996 Email: function(value, element) { 3997 return $.validator.methods.email.call(this, value, element, true); 3998 }, 3999 4000 /** 4001 * Validate that an attribute is a valid URL. 4002 */ 4003 Url: function(value, element) { 4004 return $.validator.methods.url.call(this, value, element, true); 4005 }, 4006 4007 /** 4008 * The field under validation must be a successfully uploaded file. 4009 * 4010 * @return {boolean} 4011 */ 4012 File: function(value, element) { 4013 if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { 4014 return true; 4015 } 4016 if ('files' in element ) { 4017 return (element.files.length > 0); 4018 } 4019 return false; 4020 }, 4021 4022 /** 4023 * Validate the MIME type of a file upload attribute is in a set of MIME types. 4024 * 4025 * @return {boolean} 4026 */ 4027 Mimes: function(value, element, params) { 4028 if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { 4029 return true; 4030 } 4031 var lowerParams = $.map(params, function(item) { 4032 return item.toLowerCase(); 4033 }); 4034 4035 var fileinfo = laravelValidation.helpers.fileinfo(element); 4036 return (fileinfo !== false && lowerParams.indexOf(fileinfo.extension.toLowerCase())!==-1); 4037 }, 4038 4039 /** 4040 * The file under validation must match one of the given MIME types. 4041 * 4042 * @return {boolean} 4043 */ 4044 Mimetypes: function(value, element, params) { 4045 if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { 4046 return true; 4047 } 4048 var lowerParams = $.map(params, function(item) { 4049 return item.toLowerCase(); 4050 }); 4051 4052 var fileinfo = laravelValidation.helpers.fileinfo(element); 4053 4054 if (fileinfo === false) { 4055 return false; 4056 } 4057 return (lowerParams.indexOf(fileinfo.type.toLowerCase())!==-1); 4058 }, 4059 4060 /** 4061 * Validate the MIME type of a file upload attribute is in a set of MIME types. 4062 */ 4063 Image: function(value, element) { 4064 return laravelValidation.methods.Mimes.call(this, value, element, [
4065 'jpg', 'png', 'gif', 'bmp', 'svg', 'jpeg' 4066 ]); 4067 }, 4068 4069 /** 4070 * Validate dimensions of Image. 4071 * 4072 * @return {boolean|string} 4073 */ 4074 Dimensions: function(value, element, params, callback) { 4075 if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { 4076 return true; 4077 } 4078 if (element.files === null || typeof element.files[0] === 'undefined') { 4079 return false; 4080 } 4081 4082 var fr = new FileReader; 4083 fr.onload = function () { 4084 var img = new Image(); 4085 img.onload = function () { 4086 var height = parseFloat(img.naturalHeight); 4087 var width = parseFloat(img.naturalWidth); 4088 var ratio = width / height; 4089 var notValid = ((params['width']) && parseFloat(params['width'] !== width)) || 4090 ((params['min_width']) && parseFloat(params['min_width']) > width) || 4091 ((params['max_width']) && parseFloat(params['max_width']) < width) || 4092 ((params['height']) && parseFloat(params['height']) !== height) || 4093 ((params['min_height']) && parseFloat(params['min_height']) > height) || 4094 ((params['max_height']) && parseFloat(params['max_height']) < height) || 4095 ((params['ratio']) && ratio !== parseFloat(eval(params['ratio'])) 4096 ); 4097 callback(! notValid); 4098 }; 4099 img.onerror = function() { 4100 callback(false); 4101 }; 4102 img.src = fr.result; 4103 }; 4104 fr.readAsDataURL(element.files[0]); 4105 4106 return 'pending'; 4107 }, 4108 4109 /** 4110 * Validate that an attribute contains only alphabetic characters. 4111 * 4112 * @return {boolean} 4113 */ 4114 Alpha: function(value) { 4115 if (typeof value !== 'string') { 4116 return false; 4117 } 4118 4119 var regex = new RegExp("^(?:^[a-z\u00E0-\u00FC]+$)$",'i'); 4120 return regex.test(value); 4121 4122 }, 4123 4124 /** 4125 * Validate that an attribute contains only alpha-numeric characters. 4126 * 4127 * @return {boolean} 4128 */ 4129 AlphaNum: function(value) { 4130 if (typeof value !== 'string') { 4131 return false; 4132 } 4133 var regex = new RegExp("^(?:^[a-z0-9\u00E0-\u00FC]+$)$",'i'); 4134 return regex.test(value); 4135 }, 4136 4137 /** 4138 * Validate that an attribute contains only alphabetic characters. 4139 * 4140 * @return {boolean} 4141 */ 4142 AlphaDash: function(value) { 4143 if (typeof value !== 'string') { 4144 return false; 4145 } 4146 var regex = new RegExp("^(?:^[a-z0-9\u00E0-\u00FC_-]+$)$",'i'); 4147 return regex.test(value); 4148 }, 4149 4150 /** 4151 * Validate that an attribute passes a regular expression check. 4152 * 4153 * @return {boolean} 4154 */ 4155 Regex: function(value, element, params) { 4156 var invalidModifiers=['x','s','u','X','U','A']; 4157 // Converting php regular expression 4158 var phpReg= new RegExp('^(?:\/)(.*\\\/?[^\/]*|[^\/]*)(?:\/)([gmixXsuUAJ]*)?$'); 4159 var matches=params[0].match(phpReg); 4160 if (matches === null) { 4161 return false; 4162 } 4163 // checking modifiers 4164 var php_modifiers=[]; 4165 if (matches[2]!==undefined) { 4166 php_modifiers=matches[2].split(''); 4167 for (var i=0; i<php_modifiers.length<i ;i++) { 4168 if (invalidModifiers.indexOf(php_modifiers[i])!==-1) { 4169 return true; 4170 } 4171 } 4172 } 4173 var regex = new RegExp("^(?:"+matches[1]+")$",php_modifiers.join()); 4174 return regex.test(value); 4175 }, 4176 4177 /** 4178 * Validate that an attribute is a valid date. 4179 * 4180 * @return {boolean} 4181 */ 4182 Date: function(value) { 4183 return (laravelValidation.helpers.strtotime(value)!==false); 4184 }, 4185 4186 /** 4187 * Validate that an attribute matches a date format. 4188 * 4189 * @return {boolean} 4190 */ 4191 DateFormat: function(value, element, params) { 4192 return laravelValidation.helpers.parseTime(value,params[0])!==false; 4193 }, 4194 4195 /** 4196 * Validate the date is before a given date. 4197 * 4198 * @return {boolean} 4199 */ 4200 Before: function(value, element, params) { 4201 4202 var timeCompare=parseFloat(params); 4203 if (isNaN(timeCompare)) { 4204 var target=laravelValidation.helpers.dependentElement(this, element, params); 4205 if (target===undefined) { 4206 return false; 4207 } 4208 timeCompare= laravelValidation.helpers.parseTime(this.elementValue(target), target); 4209 } 4210 4211 var timeValue=laravelValidation.helpers.parseTime(value, element); 4212 return (timeValue !==false && timeValue < timeCompare); 4213 4214 }, 4215 4216 /** 4217 * Validate the date is after a given date. 4218 * 4219 * @return {boolean} 4220 */ 4221 After: function(value, element, params) { 4222 var timeCompare=parseFloat(params); 4223 if (isNaN(timeCompare)) { 4224 var target=laravelValidation.helpers.dependentElement(this, element, params); 4225 if (target===undefined) { 4226 return false; 4227 } 4228 timeCompare= laravelValidation.helpers.parseTime(this.elementValue(target), target); 4229 } 4230 4231 var timeValue=laravelValidation.helpers.parseTime(value, element); 4232 return (timeValue !==false && timeValue > timeCompare); 4233 4234 }, 4235 4236 4237 /** 4238 * Validate that an attribute is a valid date. 4239 */ 4240 Timezone: function(value) { 4241 return laravelValidation.helpers.isTimezone(value); 4242 }, 4243 4244 4245 /** 4246 * Validate the attribute is a valid JSON string. 4247 * 4248 * @param value 4249 * @return bool 4250 */ 4251 Json: function(value) { 4252 var result = true; 4253 try { 4254 JSON.parse(value); 4255 } catch (e) { 4256 result = false; 4257 } 4258 return result; 4259 } 4260 } 4261}); 4262 4263//# sourceMappingURL=jsvalidation.js.map
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.