1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { 40/******/ configurable: false, 41/******/ enumerable: true, 42/******/ get: getter 43/******/ }); 44/******/ } 45/******/ }; 46/******/ 47/******/ // getDefaultExport function for compatibility with non-harmony modules 48/******/ __webpack_require__.n = function(module) { 49/******/ var getter = module && module.__esModule ? 50/******/ function getDefault() { return module['default']; } : 51/******/ function getModuleExports() { return module; }; 52/******/ __webpack_require__.d(getter, 'a', getter); 53/******/ return getter; 54/******/ }; 55/******/ 56/******/ // Object.prototype.hasOwnProperty.call 57/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 58/******/ 59/******/ // __webpack_public_path__ 60/******/ __webpack_require__.p = ""; 61/******/ 62/******/ // Load entry module and return exports 63/******/ return __webpack_require__(__webpack_require__.s = 3); 64/******/ }) 65/************************************************************************/ 66/******/ ([ 67/* 0 */ 68/***/ (function(module, exports, __webpack_require__) { 69 70var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function mailpoet() { 71 // A placeholder for MailPoet object 72 var MailPoet = {}; 73 74 // Expose MailPoet globally 75 window.MailPoet = MailPoet; 76 77 return MailPoet; 78}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 79 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 80 81 82/***/ }), 83/* 1 */ 84/***/ (function(module, exports) { 85 86module.exports = jQuery; 87 88/***/ }), 89/* 2 */ 90/***/ (function(module, exports) { 91 92var g; 93 94// This works in non-strict mode 95g = (function() { 96 return this; 97})(); 98 99try { 100 // This works if eval is allowed (see CSP) 101 g = g || Function("return this")() || (1,eval)("this"); 102} catch(e) { 103 // This works if the window reference is available 104 if(typeof window === "object") 105 g = window; 106} 107 108// g can still be undefined, but nothing to do about it... 109// We return undefined, instead of nothing here, so it's 110// easier to handle this case. if(!global) { ...} 111 112module.exports = g; 113 114 115/***/ }), 116/* 3 */ 117/***/ (function(module, exports, __webpack_require__) { 118 119__webpack_require__(0); 120__webpack_require__(4); 121__webpack_require__(5); 122__webpack_require__(8); 123__webpack_require__(9); 124module.exports = __webpack_require__(10); 125 126 127/***/ }), 128/* 4 */ 129/***/ (function(module, exports, __webpack_require__) { 130 131var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 132 __webpack_require__(0) 133 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function i18n( 134 mp 135 ) { 136 'use strict'; 137 138 var MailPoet = mp; 139 140 var translations = {}; 141 142 MailPoet.I18n = { 143 add: function add(key, value) { 144 translations[key] = value; 145 }, 146 t: function t(key) { 147 return translations[key] || 'TRANSLATION "%$1s" NOT FOUND'.replace('%$1s', key); 148 }, 149 all: function all() { 150 return translations; 151 } 152 }; 153 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 154 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 155 156 157/***/ }), 158/* 5 */ 159/***/ (function(module, exports, __webpack_require__) { 160 161var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function requestFailed(errorMessage, xhr) { 162 if (xhr.responseJSON) { 163 return xhr.responseJSON; 164 } 165 return { 166 errors: [ 167 { 168 message: errorMessage.replace('%d', xhr.status) 169 } 170 ] 171 }; 172} 173 174!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0), __webpack_require__(1), __webpack_require__(6)], __WEBPACK_AMD_DEFINE_RESULT__ = (function ajax(mp, jQuery, _) { 175 var MailPoet = mp; 176 177 MailPoet.Ajax = { 178 version: 0.5, 179 options: {}, 180 defaults: { 181 url: null, 182 api_version: null, 183 endpoint: null, 184 action: null, 185 token: null, 186 data: {} 187 },
188 post: function post(options) { 189 return this.request('post', options); 190 }, 191 init: function init(options) { 192 // merge options 193 this.options = jQuery.extend({}, this.defaults, options); 194 195 // set default url 196 if (this.options.url === null) { 197 this.options.url = window.ajaxurl; 198 } 199 200 // set default token 201 if (this.options.token === null) { 202 this.options.token = window.mailpoet_token; 203 } 204 }, 205 getParams: function getParams() { 206 return { 207 action: 'mailpoet', 208 api_version: this.options.api_version, 209 token: this.options.token, 210 endpoint: this.options.endpoint, 211 method: this.options.action, 212 data: this.options.data || {} 213 }; 214 }, 215 request: function request(method, options) { 216 var params; 217 var deferred; 218 // set options 219 this.init(options); 220 221 // set request params 222 params = this.getParams(); 223 224 // remove null values from the data object 225 if (_.isObject(params.data)) { 226 params.data = _.pick(params.data, function isNotNull(value) { 227 return (value !== null); 228 }); 229 } 230 231 // ajax request 232 deferred = jQuery.post( 233 this.options.url, 234 params, 235 null, 236 'json' 237 ).then(function resultHandler(data) { 238 return data; 239 }, _.partial(requestFailed, MailPoet.I18n.t('ajaxFailedErrorMessage'))); 240 241 // clear options 242 this.options = {}; 243 244 return deferred; 245 } 246 }; 247}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 248 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 249 250 251/***/ }), 252/* 6 */ 253/***/ (function(module, exports, __webpack_require__) { 254 255/* WEBPACK VAR INJECTION */(function(global) {module.exports = global["_"] = __webpack_require__(7); 256/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2))) 257 258/***/ }), 259/* 7 */ 260/***/ (function(module, exports, __webpack_require__) { 261 262var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;// Underscore.js 1.8.3 263// http://underscorejs.org 264// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 265// Underscore may be freely distributed under the MIT license. 266 267(function() { 268 269 // Baseline setup 270 // -------------- 271 272 // Establish the root object, `window` in the browser, or `exports` on the server. 273 var root = this; 274 275 // Save the previous value of the `_` variable. 276 var previousUnderscore = root._; 277 278 // Save bytes in the minified (but not gzipped) version: 279 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 280 281 // Create quick reference variables for speed access to core prototypes. 282 var 283 push = ArrayProto.push, 284 slice = ArrayProto.slice, 285 toString = ObjProto.toString, 286 hasOwnProperty = ObjProto.hasOwnProperty; 287 288 // All **ECMAScript 5** native function implementations that we hope to use 289 // are declared here. 290 var 291 nativeIsArray = Array.isArray, 292 nativeKeys = Object.keys, 293 nativeBind = FuncProto.bind, 294 nativeCreate = Object.create; 295 296 // Naked function reference for surrogate-prototype-swapping. 297 var Ctor = function(){}; 298 299 // Create a safe reference to the Underscore object for use below. 300 var _ = function(obj) { 301 if (obj instanceof _) return obj; 302 if (!(this instanceof _)) return new _(obj); 303 this._wrapped = obj; 304 }; 305 306 // Export the Underscore object for **Node.js**, with 307 // backwards-compatibility for the old `require()` API. If we're in 308 // the browser, add `_` as a global object. 309 if (true
vendor: 51,135 bytes, lines 309-1804
309) { 310 if (typeof module !== 'undefined' && module.exports) { 311 exports = module.exports = _; 312 } 313 exports._ = _; 314 } else { 315 root._ = _; 316 } 317 318 // Current version. 319 _.VERSION = '1.8.3'; 320 321 // Internal function that returns an efficient (for current engines) version 322 // of the passed-in callback, to be repeatedly applied in other Underscore 323 // functions. 324 var optimizeCb = function(func, context, argCount) { 325 if (context === void 0) return func; 326 switch (argCount == null ? 3 : argCount) { 327 case 1: return function(value) { 328 return func.call(context, value); 329 }; 330 case 2: return function(value, other) { 331 return func.call(context, value, other); 332 }; 333 case 3: return function(value, index, collection) { 334 return func.call(context, value, index, collection); 335 }; 336 case 4: return function(accumulator, value, index, collection) { 337 return func.call(context, accumulator, value, index, collection); 338 }; 339 } 340 return function() { 341 return func.apply(context, arguments); 342 }; 343 }; 344 345 // A mostly-internal function to generate callbacks that can be applied 346 // to each element in a collection, returning the desired result â either 347 // identity, an arbitrary callback, a property matcher, or a property accessor. 348 var cb = function(value, context, argCount) { 349 if (value == null) return _.identity; 350 if (_.isFunction(value)) return optimizeCb(value, context, argCount); 351 if (_.isObject(value)) return _.matcher(value); 352 return _.property(value); 353 }; 354 _.iteratee = function(value, context) { 355 return cb(value, context, Infinity); 356 }; 357 358 // An internal function for creating assigner functions. 359 var createAssigner = function(keysFunc, undefinedOnly) { 360 return function(obj) { 361 var length = arguments.length; 362 if (length < 2 || obj == null) return obj; 363 for (var index = 1; index < length; index++) { 364 var source = arguments[index], 365 keys = keysFunc(source), 366 l = keys.length; 367 for (var i = 0; i < l; i++) { 368 var key = keys[i]; 369 if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; 370 } 371 } 372 return obj; 373 }; 374 }; 375 376 // An internal function for creating a new object that inherits from another. 377 var baseCreate = function(prototype) { 378 if (!_.isObject(prototype)) return {}; 379 if (nativeCreate) return nativeCreate(prototype); 380 Ctor.prototype = prototype; 381 var result = new Ctor; 382 Ctor.prototype = null; 383 return result; 384 }; 385 386 var property = function(key) { 387 return function(obj) { 388 return obj == null ? void 0 : obj[key]; 389 }; 390 }; 391 392 // Helper for collection methods to determine whether a collection 393 // should be iterated as an array or as an object 394 // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength 395 // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 396 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; 397 var getLength = property('length'); 398 var isArrayLike = function(collection) { 399 var length = getLength(collection); 400 return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; 401 }; 402 403 // Collection Functions 404 // -------------------- 405 406 // The cornerstone, an `each` implementation, aka `forEach`. 407 // Handles raw objects in addition to array-likes. Treats all 408 // sparse array-likes as if they were dense. 409 _.each = _.forEach = function(obj, iteratee, context) { 410 iteratee = optimizeCb(iteratee, context); 411 var i, length; 412 if (isArrayLike(obj)) { 413 for (i = 0, length = obj.length; i < length; i++) { 414 iteratee(obj[i], i, obj); 415 } 416 } else { 417 var keys = _.keys(obj); 418 for (i = 0, length = keys.length; i < length; i++) { 419 iteratee(obj[keys[i]], keys[i], obj); 420 } 421 } 422 return obj; 423 }; 424 425 // Return the results of applying the iteratee to each element. 426 _.map = _.collect = function(obj, iteratee, context) { 427 iteratee = cb(iteratee, context); 428 var keys = !isArrayLike(obj) && _.keys(obj), 429 length = (keys || obj).length, 430 results = Array(length); 431 for (var index = 0; index < length; index++) { 432 var currentKey = keys ? keys[index] : index; 433 results[index] = iteratee(obj[currentKey], currentKey, obj); 434 } 435 return results; 436 }; 437 438 // Create a reducing function iterating left or right. 439 function createReduce(dir) { 440 // Optimized iterator function as using arguments.length 441 // in the main function will deoptimize the, see #1991. 442 function iterator(obj, iteratee, memo, keys, index, length) { 443 for (; index >= 0 && index < length; index += dir) { 444 var currentKey = keys ? keys[index] : index; 445 memo = iteratee(memo, obj[currentKey], currentKey, obj); 446 } 447 return memo; 448 } 449 450 return function(obj, iteratee, memo, context) { 451 iteratee = optimizeCb(iteratee, context, 4); 452 var keys = !isArrayLike(obj) && _.keys(obj), 453 length = (keys || obj).length, 454 index = dir > 0 ? 0 : length - 1; 455 // Determine the initial value if none is provided. 456 if (arguments.length < 3) { 457 memo = obj[keys ? keys[index] : index]; 458 index += dir; 459 } 460 return iterator(obj, iteratee, memo, keys, index, length); 461 }; 462 } 463 464 // **Reduce** builds up a single result from a list of values, aka `inject`, 465 // or `foldl`. 466 _.reduce = _.foldl = _.inject = createReduce(1); 467 468 // The right-associative version of reduce, also known as `foldr`. 469 _.reduceRight = _.foldr = createReduce(-1); 470 471 // Return the first value which passes a truth test. Aliased as `detect`. 472 _.find = _.detect = function(obj, predicate, context) { 473 var key; 474 if (isArrayLike(obj)) { 475 key = _.findIndex(obj, predicate, context); 476 } else { 477 key = _.findKey(obj, predicate, context); 478 } 479 if (key !== void 0 && key !== -1) return obj[key]; 480 }; 481 482 // Return all the elements that pass a truth test. 483 // Aliased as `select`. 484 _.filter = _.select = function(obj, predicate, context) { 485 var results = []; 486 predicate = cb(predicate, context); 487 _.each(obj, function(value, index, list) { 488 if (predicate(value, index, list)) results.push(value); 489 }); 490 return results; 491 }; 492 493 // Return all the elements for which a truth test fails. 494 _.reject = function(obj, predicate, context) { 495 return _.filter(obj, _.negate(cb(predicate)), context); 496 }; 497 498 // Determine whether all of the elements match a truth test. 499 // Aliased as `all`. 500 _.every = _.all = function(obj, predicate, context) { 501 predicate = cb(predicate, context); 502 var keys = !isArrayLike(obj) && _.keys(obj), 503 length = (keys || obj).length; 504 for (var index = 0; index < length; index++) { 505 var currentKey = keys ? keys[index] : index; 506 if (!predicate(obj[currentKey], currentKey, obj)) return false; 507 } 508 return true; 509 }; 510 511 // Determine if at least one element in the object matches a truth test. 512 // Aliased as `any`. 513 _.some = _.any = function(obj, predicate, context) { 514 predicate = cb(predicate, context); 515 var keys = !isArrayLike(obj) && _.keys(obj), 516 length = (keys || obj).length; 517 for (var index = 0; index < length; index++) { 518 var currentKey = keys ? keys[index] : index; 519 if (predicate(obj[currentKey], currentKey, obj)) return true; 520 } 521 return false; 522 }; 523 524 // Determine if the array or object contains a given item (using `===`). 525 // Aliased as `includes` and `include`. 526 _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { 527 if (!isArrayLike(obj)) obj = _.values(obj); 528 if (typeof fromIndex != 'number' || guard) fromIndex = 0; 529 return _.indexOf(obj, item, fromIndex) >= 0; 530 }; 531 532 // Invoke a method (with arguments) on every item in a collection. 533 _.invoke = function(obj, method) { 534 var args = slice.call(arguments, 2); 535 var isFunc = _.isFunction(method); 536 return _.map(obj, function(value) { 537 var func = isFunc ? method : value[method]; 538 return func == null ? func : func.apply(value, args); 539 }); 540 }; 541 542 // Convenience version of a common use case of `map`: fetching a property. 543 _.pluck = function(obj, key) { 544 return _.map(obj, _.property(key)); 545 }; 546 547 // Convenience version of a common use case of `filter`: selecting only objects 548 // containing specific `key:value` pairs. 549 _.where = function(obj, attrs) { 550 return _.filter(obj, _.matcher(attrs)); 551 }; 552 553 // Convenience version of a common use case of `find`: getting the first object 554 // containing specific `key:value` pairs. 555 _.findWhere = function(obj, attrs) { 556 return _.find(obj, _.matcher(attrs)); 557 }; 558 559 // Return the maximum element (or element-based computation). 560 _.max = function(obj, iteratee, context) { 561 var result = -Infinity, lastComputed = -Infinity, 562 value, computed; 563 if (iteratee == null && obj != null) { 564 obj = isArrayLike(obj) ? obj : _.values(obj); 565 for (var i = 0, length = obj.length; i < length; i++) { 566 value = obj[i]; 567 if (value > result) { 568 result = value; 569 } 570 } 571 } else { 572 iteratee = cb(iteratee, context); 573 _.each(obj, function(value, index, list) { 574 computed = iteratee(value, index, list); 575 if (computed > lastComputed || computed === -Infinity && result === -Infinity) { 576 result = value; 577 lastComputed = computed; 578 } 579 }); 580 } 581 return result; 582 }; 583 584 // Return the minimum element (or element-based computation). 585 _.min = function(obj, iteratee, context) { 586 var result = Infinity, lastComputed = Infinity, 587 value, computed; 588 if (iteratee == null && obj != null) { 589 obj = isArrayLike(obj) ? obj : _.values(obj); 590 for (var i = 0, length = obj.length; i < length; i++) { 591 value = obj[i]; 592 if (value < result) { 593 result = value; 594 } 595 } 596 } else { 597 iteratee = cb(iteratee, context); 598 _.each(obj, function(value, index, list) { 599 computed = iteratee(value, index, list); 600 if (computed < lastComputed || computed === Infinity && result === Infinity) { 601 result = value; 602 lastComputed = computed; 603 } 604 }); 605 } 606 return result; 607 }; 608 609 // Shuffle a collection, using the modern version of the 610 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/FisherâYates_shuffle). 611 _.shuffle = function(obj) { 612 var set = isArrayLike(obj) ? obj : _.values(obj); 613 var length = set.length; 614 var shuffled = Array(length); 615 for (var index = 0, rand; index < length; index++) { 616 rand = _.random(0, index); 617 if (rand !== index) shuffled[index] = shuffled[rand]; 618 shuffled[rand] = set[index]; 619 } 620 return shuffled; 621 }; 622 623 // Sample **n** random values from a collection. 624 // If **n** is not specified, returns a single random element. 625 // The internal `guard` argument allows it to work with `map`. 626 _.sample = function(obj, n, guard) { 627 if (n == null || guard) { 628 if (!isArrayLike(obj)) obj = _.values(obj); 629 return obj[_.random(obj.length - 1)]; 630 } 631 return _.shuffle(obj).slice(0, Math.max(0, n)); 632 }; 633 634 // Sort the object's values by a criterion produced by an iteratee. 635 _.sortBy = function(obj, iteratee, context) { 636 iteratee = cb(iteratee, context); 637 return _.pluck(_.map(obj, function(value, index, list) { 638 return { 639 value: value, 640 index: index, 641 criteria: iteratee(value, index, list) 642 }; 643 }).sort(function(left, right) { 644 var a = left.criteria; 645 var b = right.criteria; 646 if (a !== b) { 647 if (a > b || a === void 0) return 1; 648 if (a < b || b === void 0) return -1; 649 } 650 return left.index - right.index; 651 }), 'value'); 652 }; 653 654 // An internal function used for aggregate "group by" operations. 655 var group = function(behavior) { 656 return function(obj, iteratee, context) { 657 var result = {}; 658 iteratee = cb(iteratee, context); 659 _.each(obj, function(value, index) { 660 var key = iteratee(value, index, obj); 661 behavior(result, value, key); 662 }); 663 return result; 664 }; 665 }; 666 667 // Groups the object's values by a criterion. Pass either a string attribute 668 // to group by, or a function that returns the criterion. 669 _.groupBy = group(function(result, value, key) { 670 if (_.has(result, key)) result[key].push(value); else result[key] = [value]; 671 }); 672 673 // Indexes the object's values by a criterion, similar to `groupBy`, but for 674 // when you know that your index values will be unique. 675 _.indexBy = group(function(result, value, key) { 676 result[key] = value; 677 }); 678 679 // Counts instances of an object that group by a certain criterion. Pass 680 // either a string attribute to count by, or a function that returns the 681 // criterion. 682 _.countBy = group(function(result, value, key) { 683 if (_.has(result, key)) result[key]++; else result[key] = 1; 684 }); 685 686 // Safely create a real, live array from anything iterable. 687 _.toArray = function(obj) { 688 if (!obj) return []; 689 if (_.isArray(obj)) return slice.call(obj); 690 if (isArrayLike(obj)) return _.map(obj, _.identity); 691 return _.values(obj); 692 }; 693 694 // Return the number of elements in an object. 695 _.size = function(obj) { 696 if (obj == null) return 0; 697 return isArrayLike(obj) ? obj.length : _.keys(obj).length; 698 }; 699 700 // Split a collection into two arrays: one whose elements all satisfy the given 701 // predicate, and one whose elements all do not satisfy the predicate. 702 _.partition = function(obj, predicate, context) { 703 predicate = cb(predicate, context); 704 var pass = [], fail = []; 705 _.each(obj, function(value, key, obj) { 706 (predicate(value, key, obj) ? pass : fail).push(value); 707 }); 708 return [pass, fail]; 709 }; 710 711 // Array Functions 712 // --------------- 713 714 // Get the first element of an array. Passing **n** will return the first N 715 // values in the array. Aliased as `head` and `take`. The **guard** check 716 // allows it to work with `_.map`. 717 _.first = _.head = _.take = function(array, n, guard) { 718 if (array == null) return void 0; 719 if (n == null || guard) return array[0]; 720 return _.initial(array, array.length - n); 721 }; 722 723 // Returns everything but the last entry of the array. Especially useful on 724 // the arguments object. Passing **n** will return all the values in 725 // the array, excluding the last N. 726 _.initial = function(array, n, guard) { 727 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); 728 }; 729 730 // Get the last element of an array. Passing **n** will return the last N 731 // values in the array. 732 _.last = function(array, n, guard) { 733 if (array == null) return void 0; 734 if (n == null || guard) return array[array.length - 1]; 735 return _.rest(array, Math.max(0, array.length - n)); 736 }; 737 738 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. 739 // Especially useful on the arguments object. Passing an **n** will return 740 // the rest N values in the array. 741 _.rest = _.tail = _.drop = function(array, n, guard) { 742 return slice.call(array, n == null || guard ? 1 : n); 743 }; 744 745 // Trim out all falsy values from an array. 746 _.compact = function(array) { 747 return _.filter(array, _.identity); 748 }; 749 750 // Internal implementation of a recursive `flatten` function. 751 var flatten = function(input, shallow, strict, startIndex) { 752 var output = [], idx = 0; 753 for (var i = startIndex || 0, length = getLength(input); i < length; i++) { 754 var value = input[i]; 755 if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { 756 //flatten current level of array or arguments object 757 if (!shallow) value = flatten(value, shallow, strict); 758 var j = 0, len = value.length; 759 output.length += len; 760 while (j < len) { 761 output[idx++] = value[j++]; 762 } 763 } else if (!strict) { 764 output[idx++] = value; 765 } 766 } 767 return output; 768 }; 769 770 // Flatten out an array, either recursively (by default), or just one level. 771 _.flatten = function(array, shallow) { 772 return flatten(array, shallow, false); 773 }; 774 775 // Return a version of the array that does not contain the specified value(s). 776 _.without = function(array) { 777 return _.difference(array, slice.call(arguments, 1)); 778 }; 779 780 // Produce a duplicate-free version of the array. If the array has already 781 // been sorted, you have the option of using a faster algorithm. 782 // Aliased as `unique`. 783 _.uniq = _.unique = function(array, isSorted, iteratee, context) { 784 if (!_.isBoolean(isSorted)) { 785 context = iteratee; 786 iteratee = isSorted; 787 isSorted = false; 788 } 789 if (iteratee != null) iteratee = cb(iteratee, context); 790 var result = []; 791 var seen = []; 792 for (var i = 0, length = getLength(array); i < length; i++) { 793 var value = array[i], 794 computed = iteratee ? iteratee(value, i, array) : value; 795 if (isSorted) { 796 if (!i || seen !== computed) result.push(value); 797 seen = computed; 798 } else if (iteratee) { 799 if (!_.contains(seen, computed)) { 800 seen.push(computed); 801 result.push(value); 802 } 803 } else if (!_.contains(result, value)) { 804 result.push(value); 805 } 806 } 807 return result; 808 }; 809 810 // Produce an array that contains the union: each distinct element from all of 811 // the passed-in arrays. 812 _.union = function() { 813 return _.uniq(flatten(arguments, true, true)); 814 }; 815 816 // Produce an array that contains every item shared between all the 817 // passed-in arrays. 818 _.intersection = function(array) { 819 var result = []; 820 var argsLength = arguments.length; 821 for (var i = 0, length = getLength(array); i < length; i++) { 822 var item = array[i]; 823 if (_.contains(result, item)) continue; 824 for (var j = 1; j < argsLength; j++) { 825 if (!_.contains(arguments[j], item)) break; 826 } 827 if (j === argsLength) result.push(item); 828 } 829 return result; 830 }; 831 832 // Take the difference between one array and a number of other arrays. 833 // Only the elements present in just the first array will remain. 834 _.difference = function(array) { 835 var rest = flatten(arguments, true, true, 1); 836 return _.filter(array, function(value){ 837 return !_.contains(rest, value); 838 }); 839 }; 840 841 // Zip together multiple lists into a single array -- elements that share 842 // an index go together. 843 _.zip = function() { 844 return _.unzip(arguments); 845 }; 846 847 // Complement of _.zip. Unzip accepts an array of arrays and groups 848 // each array's elements on shared indices 849 _.unzip = function(array) { 850 var length = array && _.max(array, getLength).length || 0; 851 var result = Array(length); 852 853 for (var index = 0; index < length; index++) { 854 result[index] = _.pluck(array, index); 855 } 856 return result; 857 }; 858 859 // Converts lists into objects. Pass either a single array of `[key, value]` 860 // pairs, or two parallel arrays of the same length -- one of keys, and one of 861 // the corresponding values. 862 _.object = function(list, values) { 863 var result = {}; 864 for (var i = 0, length = getLength(list); i < length; i++) { 865 if (values) { 866 result[list[i]] = values[i]; 867 } else { 868 result[list[i][0]] = list[i][1]; 869 } 870 } 871 return result; 872 }; 873 874 // Generator function to create the findIndex and findLastIndex functions 875 function createPredicateIndexFinder(dir) { 876 return function(array, predicate, context) { 877 predicate = cb(predicate, context); 878 var length = getLength(array); 879 var index = dir > 0 ? 0 : length - 1; 880 for (; index >= 0 && index < length; index += dir) { 881 if (predicate(array[index], index, array)) return index; 882 } 883 return -1; 884 }; 885 } 886 887 // Returns the first index on an array-like that passes a predicate test 888 _.findIndex = createPredicateIndexFinder(1); 889 _.findLastIndex = createPredicateIndexFinder(-1); 890 891 // Use a comparator function to figure out the smallest index at which 892 // an object should be inserted so as to maintain order. Uses binary search. 893 _.sortedIndex = function(array, obj, iteratee, context) { 894 iteratee = cb(iteratee, context, 1); 895 var value = iteratee(obj); 896 var low = 0, high = getLength(array); 897 while (low < high) { 898 var mid = Math.floor((low + high) / 2); 899 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; 900 } 901 return low; 902 }; 903 904 // Generator function to create the indexOf and lastIndexOf functions 905 function createIndexFinder(dir, predicateFind, sortedIndex) { 906 return function(array, item, idx) { 907 var i = 0, length = getLength(array); 908 if (typeof idx == 'number') { 909 if (dir > 0) { 910 i = idx >= 0 ? idx : Math.max(idx + length, i); 911 } else { 912 length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; 913 } 914 } else if (sortedIndex && idx && length) { 915 idx = sortedIndex(array, item); 916 return array[idx] === item ? idx : -1; 917 } 918 if (item !== item) { 919 idx = predicateFind(slice.call(array, i, length), _.isNaN); 920 return idx >= 0 ? idx + i : -1; 921 } 922 for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { 923 if (array[idx] === item) return idx; 924 } 925 return -1; 926 }; 927 } 928 929 // Return the position of the first occurrence of an item in an array, 930 // or -1 if the item is not included in the array. 931 // If the array is large and already in sort order, pass `true` 932 // for **isSorted** to use binary search. 933 _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); 934 _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); 935 936 // Generate an integer Array containing an arithmetic progression. A port of 937 // the native Python `range()` function. See 938 // [the Python documentation](http://docs.python.org/library/functions.html#range). 939 _.range = function(start, stop, step) { 940 if (stop == null) { 941 stop = start || 0; 942 start = 0; 943 } 944 step = step || 1; 945 946 var length = Math.max(Math.ceil((stop - start) / step), 0); 947 var range = Array(length); 948 949 for (var idx = 0; idx < length; idx++, start += step) { 950 range[idx] = start; 951 } 952 953 return range; 954 }; 955 956 // Function (ahem) Functions 957 // ------------------ 958 959 // Determines whether to execute a function as a constructor 960 // or a normal function with the provided arguments 961 var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { 962 if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); 963 var self = baseCreate(sourceFunc.prototype); 964 var result = sourceFunc.apply(self, args); 965 if (_.isObject(result)) return result; 966 return self; 967 }; 968 969 // Create a function bound to a given object (assigning `this`, and arguments, 970 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if 971 // available. 972 _.bind = function(func, context) { 973 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 974 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); 975 var args = slice.call(arguments, 2); 976 var bound = function() { 977 return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); 978 }; 979 return bound; 980 }; 981 982 // Partially apply a function by creating a version that has had some of its 983 // arguments pre-filled, without changing its dynamic `this` context. _ acts 984 // as a placeholder, allowing any combination of arguments to be pre-filled. 985 _.partial = function(func) { 986 var boundArgs = slice.call(arguments, 1); 987 var bound = function() { 988 var position = 0, length = boundArgs.length; 989 var args = Array(length); 990 for (var i = 0; i < length; i++) { 991 args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; 992 } 993 while (position < arguments.length) args.push(arguments[position++]); 994 return executeBound(func, bound, this, this, args); 995 }; 996 return bound; 997 }; 998 999 // Bind a number of an object's methods to that object. Remaining arguments 1000 // are the method names to be bound. Useful for ensuring that all callbacks 1001 // defined on an object belong to it. 1002 _.bindAll = function(obj) { 1003 var i, length = arguments.length, key; 1004 if (length <= 1) throw new Error('bindAll must be passed function names'); 1005 for (i = 1; i < length; i++) { 1006 key = arguments[i]; 1007 obj[key] = _.bind(obj[key], obj); 1008 } 1009 return obj; 1010 }; 1011 1012 // Memoize an expensive function by storing its results. 1013 _.memoize = function(func, hasher) { 1014 var memoize = function(key) { 1015 var cache = memoize.cache; 1016 var address = '' + (hasher ? hasher.apply(this, arguments) : key); 1017 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); 1018 return cache[address]; 1019 }; 1020 memoize.cache = {}; 1021 return memoize; 1022 }; 1023 1024 // Delays a function for the given number of milliseconds, and then calls 1025 // it with the arguments supplied. 1026 _.delay = function(func, wait) { 1027 var args = slice.call(arguments, 2); 1028 return setTimeout(function(){ 1029 return func.apply(null, args); 1030 }, wait); 1031 }; 1032 1033 // Defers a function, scheduling it to run after the current call stack has 1034 // cleared. 1035 _.defer = _.partial(_.delay, _, 1); 1036 1037 // Returns a function, that, when invoked, will only be triggered at most once 1038 // during a given window of time. Normally, the throttled function will run 1039 // as much as it can, without ever going more than once per `wait` duration; 1040 // but if you'd like to disable the execution on the leading edge, pass 1041 // `{leading: false}`. To disable execution on the trailing edge, ditto. 1042 _.throttle = function(func, wait, options) { 1043 var context, args, result; 1044 var timeout = null; 1045 var previous = 0; 1046 if (!options) options = {}; 1047 var later = function() { 1048 previous = options.leading === false ? 0 : _.now(); 1049 timeout = null; 1050 result = func.apply(context, args); 1051 if (!timeout) context = args = null; 1052 }; 1053 return function() { 1054 var now = _.now(); 1055 if (!previous && options.leading === false) previous = now; 1056 var remaining = wait - (now - previous); 1057 context = this; 1058 args = arguments; 1059 if (remaining <= 0 || remaining > wait) { 1060 if (timeout) { 1061 clearTimeout(timeout); 1062 timeout = null; 1063 } 1064 previous = now; 1065 result = func.apply(context, args); 1066 if (!timeout) context = args = null; 1067 } else if (!timeout && options.trailing !== false) { 1068 timeout = setTimeout(later, remaining); 1069 } 1070 return result; 1071 }; 1072 }; 1073 1074 // Returns a function, that, as long as it continues to be invoked, will not 1075 // be triggered. The function will be called after it stops being called for 1076 // N milliseconds. If `immediate` is passed, trigger the function on the 1077 // leading edge, instead of the trailing. 1078 _.debounce = function(func, wait, immediate) { 1079 var timeout, args, context, timestamp, result; 1080 1081 var later = function() { 1082 var last = _.now() - timestamp; 1083 1084 if (last < wait && last >= 0) { 1085 timeout = setTimeout(later, wait - last); 1086 } else { 1087 timeout = null; 1088 if (!immediate) { 1089 result = func.apply(context, args); 1090 if (!timeout) context = args = null; 1091 } 1092 } 1093 }; 1094 1095 return function() { 1096 context = this; 1097 args = arguments; 1098 timestamp = _.now(); 1099 var callNow = immediate && !timeout; 1100 if (!timeout) timeout = setTimeout(later, wait); 1101 if (callNow) { 1102 result = func.apply(context, args); 1103 context = args = null; 1104 } 1105 1106 return result; 1107 }; 1108 }; 1109 1110 // Returns the first function passed as an argument to the second, 1111 // allowing you to adjust arguments, run code before and after, and 1112 // conditionally execute the original function. 1113 _.wrap = function(func, wrapper) { 1114 return _.partial(wrapper, func); 1115 }; 1116 1117 // Returns a negated version of the passed-in predicate. 1118 _.negate = function(predicate) { 1119 return function() { 1120 return !predicate.apply(this, arguments); 1121 }; 1122 }; 1123 1124 // Returns a function that is the composition of a list of functions, each 1125 // consuming the return value of the function that follows. 1126 _.compose = function() { 1127 var args = arguments; 1128 var start = args.length - 1; 1129 return function() { 1130 var i = start; 1131 var result = args[start].apply(this, arguments); 1132 while (i--) result = args[i].call(this, result); 1133 return result; 1134 }; 1135 }; 1136 1137 // Returns a function that will only be executed on and after the Nth call. 1138 _.after = function(times, func) { 1139 return function() { 1140 if (--times < 1) { 1141 return func.apply(this, arguments); 1142 } 1143 }; 1144 }; 1145 1146 // Returns a function that will only be executed up to (but not including) the Nth call. 1147 _.before = function(times, func) { 1148 var memo; 1149 return function() { 1150 if (--times > 0) { 1151 memo = func.apply(this, arguments); 1152 } 1153 if (times <= 1) func = null; 1154 return memo; 1155 }; 1156 }; 1157 1158 // Returns a function that will be executed at most one time, no matter how 1159 // often you call it. Useful for lazy initialization. 1160 _.once = _.partial(_.before, 2); 1161 1162 // Object Functions 1163 // ---------------- 1164 1165 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. 1166 var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); 1167 var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 1168 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; 1169 1170 function collectNonEnumProps(obj, keys) { 1171 var nonEnumIdx = nonEnumerableProps.length; 1172 var constructor = obj.constructor; 1173 var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; 1174 1175 // Constructor is a special case. 1176 var prop = 'constructor'; 1177 if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); 1178 1179 while (nonEnumIdx--) { 1180 prop = nonEnumerableProps[nonEnumIdx]; 1181 if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { 1182 keys.push(prop); 1183 } 1184 } 1185 } 1186 1187 // Retrieve the names of an object's own properties. 1188 // Delegates to **ECMAScript 5**'s native `Object.keys` 1189 _.keys = function(obj) { 1190 if (!_.isObject(obj)) return []; 1191 if (nativeKeys) return nativeKeys(obj); 1192 var keys = []; 1193 for (var key in obj) if (_.has(obj, key)) keys.push(key); 1194 // Ahem, IE < 9. 1195 if (hasEnumBug) collectNonEnumProps(obj, keys); 1196 return keys; 1197 }; 1198 1199 // Retrieve all the property names of an object. 1200 _.allKeys = function(obj) { 1201 if (!_.isObject(obj)) return []; 1202 var keys = []; 1203 for (var key in obj) keys.push(key); 1204 // Ahem, IE < 9. 1205 if (hasEnumBug) collectNonEnumProps(obj, keys); 1206 return keys; 1207 }; 1208 1209 // Retrieve the values of an object's properties. 1210 _.values = function(obj) { 1211 var keys = _.keys(obj); 1212 var length = keys.length; 1213 var values = Array(length); 1214 for (var i = 0; i < length; i++) { 1215 values[i] = obj[keys[i]]; 1216 } 1217 return values; 1218 }; 1219 1220 // Returns the results of applying the iteratee to each element of the object 1221 // In contrast to _.map it returns an object 1222 _.mapObject = function(obj, iteratee, context) { 1223 iteratee = cb(iteratee, context); 1224 var keys = _.keys(obj), 1225 length = keys.length, 1226 results = {}, 1227 currentKey; 1228 for (var index = 0; index < length; index++) { 1229 currentKey = keys[index]; 1230 results[currentKey] = iteratee(obj[currentKey], currentKey, obj); 1231 } 1232 return results; 1233 }; 1234 1235 // Convert an object into a list of `[key, value]` pairs. 1236 _.pairs = function(obj) { 1237 var keys = _.keys(obj); 1238 var length = keys.length; 1239 var pairs = Array(length); 1240 for (var i = 0; i < length; i++) { 1241 pairs[i] = [keys[i], obj[keys[i]]]; 1242 } 1243 return pairs; 1244 }; 1245 1246 // Invert the keys and values of an object. The values must be serializable. 1247 _.invert = function(obj) { 1248 var result = {}; 1249 var keys = _.keys(obj); 1250 for (var i = 0, length = keys.length; i < length; i++) { 1251 result[obj[keys[i]]] = keys[i]; 1252 } 1253 return result; 1254 }; 1255 1256 // Return a sorted list of the function names available on the object. 1257 // Aliased as `methods` 1258 _.functions = _.methods = function(obj) { 1259 var names = []; 1260 for (var key in obj) { 1261 if (_.isFunction(obj[key])) names.push(key); 1262 } 1263 return names.sort(); 1264 }; 1265 1266 // Extend a given object with all the properties in passed-in object(s). 1267 _.extend = createAssigner(_.allKeys); 1268 1269 // Assigns a given object with all the own properties in the passed-in object(s) 1270 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 1271 _.extendOwn = _.assign = createAssigner(_.keys); 1272 1273 // Returns the first key on an object that passes a predicate test 1274 _.findKey = function(obj, predicate, context) { 1275 predicate = cb(predicate, context); 1276 var keys = _.keys(obj), key; 1277 for (var i = 0, length = keys.length; i < length; i++) { 1278 key = keys[i]; 1279 if (predicate(obj[key], key, obj)) return key; 1280 } 1281 }; 1282 1283 // Return a copy of the object only containing the whitelisted properties. 1284 _.pick = function(object, oiteratee, context) { 1285 var result = {}, obj = object, iteratee, keys; 1286 if (obj == null) return result; 1287 if (_.isFunction(oiteratee)) { 1288 keys = _.allKeys(obj); 1289 iteratee = optimizeCb(oiteratee, context); 1290 } else { 1291 keys = flatten(arguments, false, false, 1); 1292 iteratee = function(value, key, obj) { return key in obj; }; 1293 obj = Object(obj); 1294 } 1295 for (var i = 0, length = keys.length; i < length; i++) { 1296 var key = keys[i]; 1297 var value = obj[key]; 1298 if (iteratee(value, key, obj)) result[key] = value; 1299 } 1300 return result; 1301 }; 1302 1303 // Return a copy of the object without the blacklisted properties. 1304 _.omit = function(obj, iteratee, context) { 1305 if (_.isFunction(iteratee)) { 1306 iteratee = _.negate(iteratee); 1307 } else { 1308 var keys = _.map(flatten(arguments, false, false, 1), String); 1309 iteratee = function(value, key) { 1310 return !_.contains(keys, key); 1311 }; 1312 } 1313 return _.pick(obj, iteratee, context); 1314 }; 1315 1316 // Fill in a given object with default properties. 1317 _.defaults = createAssigner(_.allKeys, true); 1318 1319 // Creates an object that inherits from the given prototype object. 1320 // If additional properties are provided then they will be added to the 1321 // created object. 1322 _.create = function(prototype, props) { 1323 var result = baseCreate(prototype); 1324 if (props) _.extendOwn(result, props); 1325 return result; 1326 }; 1327 1328 // Create a (shallow-cloned) duplicate of an object. 1329 _.clone = function(obj) { 1330 if (!_.isObject(obj)) return obj; 1331 return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 1332 }; 1333 1334 // Invokes interceptor with the obj, and then returns obj. 1335 // The primary purpose of this method is to "tap into" a method chain, in 1336 // order to perform operations on intermediate results within the chain. 1337 _.tap = function(obj, interceptor) { 1338 interceptor(obj); 1339 return obj; 1340 }; 1341 1342 // Returns whether an object has a given set of `key:value` pairs. 1343 _.isMatch = function(object, attrs) { 1344 var keys = _.keys(attrs), length = keys.length; 1345 if (object == null) return !length; 1346 var obj = Object(object); 1347 for (var i = 0; i < length; i++) { 1348 var key = keys[i]; 1349 if (attrs[key] !== obj[key] || !(key in obj)) return false; 1350 } 1351 return true; 1352 }; 1353 1354 1355 // Internal recursive comparison function for `isEqual`. 1356 var eq = function(a, b, aStack, bStack) { 1357 // Identical objects are equal. `0 === -0`, but they aren't identical. 1358 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). 1359 if (a === b) return a !== 0 || 1 / a === 1 / b; 1360 // A strict comparison is necessary because `null == undefined`. 1361 if (a == null || b == null) return a === b; 1362 // Unwrap any wrapped objects. 1363 if (a instanceof _) a = a._wrapped; 1364 if (b instanceof _) b = b._wrapped; 1365 // Compare `[[Class]]` names. 1366 var className = toString.call(a); 1367 if (className !== toString.call(b)) return false; 1368 switch (className) { 1369 // Strings, numbers, regular expressions, dates, and booleans are compared by value. 1370 case '[object RegExp]': 1371 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') 1372 case '[object String]': 1373 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is 1374 // equivalent to `new String("5")`. 1375 return '' + a === '' + b; 1376 case '[object Number]': 1377 // `NaN`s are equivalent, but non-reflexive. 1378 // Object(NaN) is equivalent to NaN 1379 if (+a !== +a) return +b !== +b; 1380 // An `egal` comparison is performed for other numeric values. 1381 return +a === 0 ? 1 / +a === 1 / b : +a === +b; 1382 case '[object Date]': 1383 case '[object Boolean]': 1384 // Coerce dates and booleans to numeric primitive values. Dates are compared by their 1385 // millisecond representations. Note that invalid dates with millisecond representations 1386 // of `NaN` are not equivalent. 1387 return +a === +b; 1388 } 1389 1390 var areArrays = className === '[object Array]'; 1391 if (!areArrays) { 1392 if (typeof a != 'object' || typeof b != 'object') return false; 1393 1394 // Objects with different constructors are not equivalent, but `Object`s or `Array`s 1395 // from different frames are. 1396 var aCtor = a.constructor, bCtor = b.constructor; 1397 if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && 1398 _.isFunction(bCtor) && bCtor instanceof bCtor) 1399 && ('constructor' in a && 'constructor' in b)) { 1400 return false; 1401 } 1402 } 1403 // Assume equality for cyclic structures. The algorithm for detecting cyclic 1404 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 1405 1406 // Initializing stack of traversed objects. 1407 // It's done here since we only need them for objects and arrays comparison. 1408 aStack = aStack || []; 1409 bStack = bStack || []; 1410 var length = aStack.length; 1411 while (length--) { 1412 // Linear search. Performance is inversely proportional to the number of 1413 // unique nested structures. 1414 if (aStack[length] === a) return bStack[length] === b; 1415 } 1416 1417 // Add the first object to the stack of traversed objects. 1418 aStack.push(a); 1419 bStack.push(b); 1420 1421 // Recursively compare objects and arrays. 1422 if (areArrays) { 1423 // Compare array lengths to determine if a deep comparison is necessary. 1424 length = a.length; 1425 if (length !== b.length) return false; 1426 // Deep compare the contents, ignoring non-numeric properties. 1427 while (length--) { 1428 if (!eq(a[length], b[length], aStack, bStack)) return false; 1429 } 1430 } else { 1431 // Deep compare objects. 1432 var keys = _.keys(a), key; 1433 length = keys.length; 1434 // Ensure that both objects contain the same number of properties before comparing deep equality. 1435 if (_.keys(b).length !== length) return false; 1436 while (length--) { 1437 // Deep compare each member 1438 key = keys[length]; 1439 if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; 1440 } 1441 } 1442 // Remove the first object from the stack of traversed objects. 1443 aStack.pop(); 1444 bStack.pop(); 1445 return true; 1446 }; 1447 1448 // Perform a deep comparison to check if two objects are equal. 1449 _.isEqual = function(a, b) { 1450 return eq(a, b); 1451 }; 1452 1453 // Is a given array, string, or object empty? 1454 // An "empty" object has no enumerable own-properties. 1455 _.isEmpty = function(obj) { 1456 if (obj == null) return true; 1457 if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; 1458 return _.keys(obj).length === 0; 1459 }; 1460 1461 // Is a given value a DOM element? 1462 _.isElement = function(obj) { 1463 return !!(obj && obj.nodeType === 1); 1464 }; 1465 1466 // Is a given value an array? 1467 // Delegates to ECMA5's native Array.isArray 1468 _.isArray = nativeIsArray || function(obj) { 1469 return toString.call(obj) === '[object Array]'; 1470 }; 1471 1472 // Is a given variable an object? 1473 _.isObject = function(obj) { 1474 var type = typeof obj; 1475 return type === 'function' || type === 'object' && !!obj; 1476 }; 1477 1478 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. 1479 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { 1480 _['is' + name] = function(obj) { 1481 return toString.call(obj) === '[object ' + name + ']'; 1482 }; 1483 }); 1484 1485 // Define a fallback version of the method in browsers (ahem, IE < 9), where 1486 // there isn't any inspectable "Arguments" type. 1487 if (!_.isArguments(arguments)) { 1488 _.isArguments = function(obj) { 1489 return _.has(obj, 'callee'); 1490 }; 1491 } 1492 1493 // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, 1494 // IE 11 (#1621), and in Safari 8 (#1929). 1495 if (typeof /./ != 'function' && typeof Int8Array != 'object') { 1496 _.isFunction = function(obj) { 1497 return typeof obj == 'function' || false; 1498 }; 1499 } 1500 1501 // Is a given object a finite number? 1502 _.isFinite = function(obj) { 1503 return isFinite(obj) && !isNaN(parseFloat(obj)); 1504 }; 1505 1506 // Is the given value `NaN`? (NaN is the only number which does not equal itself). 1507 _.isNaN = function(obj) { 1508 return _.isNumber(obj) && obj !== +obj; 1509 }; 1510 1511 // Is a given value a boolean? 1512 _.isBoolean = function(obj) { 1513 return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; 1514 }; 1515 1516 // Is a given value equal to null? 1517 _.isNull = function(obj) { 1518 return obj === null; 1519 }; 1520 1521 // Is a given variable undefined? 1522 _.isUndefined = function(obj) { 1523 return obj === void 0; 1524 }; 1525 1526 // Shortcut function for checking if an object has a given property directly 1527 // on itself (in other words, not on a prototype). 1528 _.has = function(obj, key) { 1529 return obj != null && hasOwnProperty.call(obj, key); 1530 }; 1531 1532 // Utility Functions 1533 // ----------------- 1534 1535 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 1536 // previous owner. Returns a reference to the Underscore object. 1537 _.noConflict = function() { 1538 root._ = previousUnderscore; 1539 return this; 1540 }; 1541 1542 // Keep the identity function around for default iteratees. 1543 _.identity = function(value) { 1544 return value; 1545 }; 1546 1547 // Predicate-generating functions. Often useful outside of Underscore. 1548 _.constant = function(value) { 1549 return function() { 1550 return value; 1551 }; 1552 }; 1553 1554 _.noop = function(){}; 1555 1556 _.property = property; 1557 1558 // Generates a function for a given object that returns a given property. 1559 _.propertyOf = function(obj) { 1560 return obj == null ? function(){} : function(key) { 1561 return obj[key]; 1562 }; 1563 }; 1564 1565 // Returns a predicate for checking whether an object has a given set of 1566 // `key:value` pairs. 1567 _.matcher = _.matches = function(attrs) { 1568 attrs = _.extendOwn({}, attrs); 1569 return function(obj) { 1570 return _.isMatch(obj, attrs); 1571 }; 1572 }; 1573 1574 // Run a function **n** times. 1575 _.times = function(n, iteratee, context) { 1576 var accum = Array(Math.max(0, n)); 1577 iteratee = optimizeCb(iteratee, context, 1); 1578 for (var i = 0; i < n; i++) accum[i] = iteratee(i); 1579 return accum; 1580 }; 1581 1582 // Return a random integer between min and max (inclusive). 1583 _.random = function(min, max) { 1584 if (max == null) { 1585 max = min; 1586 min = 0; 1587 } 1588 return min + Math.floor(Math.random() * (max - min + 1)); 1589 }; 1590 1591 // A (possibly faster) way to get the current timestamp as an integer. 1592 _.now = Date.now || function() { 1593 return new Date().getTime(); 1594 }; 1595 1596 // List of HTML entities for escaping. 1597 var escapeMap = { 1598 '&': '&', 1599 '<': '<', 1600 '>': '>', 1601 '"': '"', 1602 "'": ''', 1603 '`': '`' 1604 }; 1605 var unescapeMap = _.invert(escapeMap); 1606 1607 // Functions for escaping and unescaping strings to/from HTML interpolation. 1608 var createEscaper = function(map) { 1609 var escaper = function(match) { 1610 return map[match]; 1611 }; 1612 // Regexes for identifying a key that needs to be escaped 1613 var source = '(?:' + _.keys(map).join('|') + ')'; 1614 var testRegexp = RegExp(source); 1615 var replaceRegexp = RegExp(source, 'g'); 1616 return function(string) { 1617 string = string == null ? '' : '' + string; 1618 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1619 }; 1620 }; 1621 _.escape = createEscaper(escapeMap); 1622 _.unescape = createEscaper(unescapeMap); 1623 1624 // If the value of the named `property` is a function then invoke it with the 1625 // `object` as context; otherwise, return it. 1626 _.result = function(object, property, fallback) { 1627 var value = object == null ? void 0 : object[property]; 1628 if (value === void 0) { 1629 value = fallback; 1630 } 1631 return _.isFunction(value) ? value.call(object) : value; 1632 }; 1633 1634 // Generate a unique integer id (unique within the entire client session). 1635 // Useful for temporary DOM ids. 1636 var idCounter = 0; 1637 _.uniqueId = function(prefix) { 1638 var id = ++idCounter + ''; 1639 return prefix ? prefix + id : id; 1640 }; 1641 1642 // By default, Underscore uses ERB-style template delimiters, change the 1643 // following template settings to use alternative delimiters. 1644 _.templateSettings = { 1645 evaluate : /<%([\s\S]+?)%>/g, 1646 interpolate : /<%=([\s\S]+?)%>/g, 1647 escape : /<%-([\s\S]+?)%>/g 1648 }; 1649 1650 // When customizing `templateSettings`, if you don't want to define an 1651 // interpolation, evaluation or escaping regex, we need one that is 1652 // guaranteed not to match. 1653 var noMatch = /(.)^/; 1654 1655 // Certain characters need to be escaped so that they can be put into a 1656 // string literal. 1657 var escapes = { 1658 "'": "'", 1659 '\\': '\\', 1660 '\r': 'r', 1661 '\n': 'n', 1662 '\u2028': 'u2028', 1663 '\u2029': 'u2029' 1664 }; 1665 1666 var escaper = /\\|'|\r|\n|\u2028|\u2029/g; 1667 1668 var escapeChar = function(match) { 1669 return '\\' + escapes[match]; 1670 }; 1671 1672 // JavaScript micro-templating, similar to John Resig's implementation. 1673 // Underscore templating handles arbitrary delimiters, preserves whitespace, 1674 // and correctly escapes quotes within interpolated code. 1675 // NB: `oldSettings` only exists for backwards compatibility. 1676 _.template = function(text, settings, oldSettings) { 1677 if (!settings && oldSettings) settings = oldSettings; 1678 settings = _.defaults({}, settings, _.templateSettings); 1679 1680 // Combine delimiters into one regular expression via alternation. 1681 var matcher = RegExp([ 1682 (settings.escape || noMatch).source, 1683 (settings.interpolate || noMatch).source, 1684 (settings.evaluate || noMatch).source 1685 ].join('|') + '|$', 'g'); 1686 1687 // Compile the template source, escaping string literals appropriately. 1688 var index = 0; 1689 var source = "__p+='"; 1690 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 1691 source += text.slice(index, offset).replace(escaper, escapeChar); 1692 index = offset + match.length; 1693 1694 if (escape) { 1695 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 1696 } else if (interpolate) { 1697 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 1698 } else if (evaluate) { 1699 source += "';\n" + evaluate + "\n__p+='"; 1700 } 1701 1702 // Adobe VMs need the match returned to produce the correct offest. 1703 return match; 1704 }); 1705 source += "';\n"; 1706 1707 // If a variable is not specified, place data values in local scope. 1708 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 1709 1710 source = "var __t,__p='',__j=Array.prototype.join," + 1711 "print=function(){__p+=__j.call(arguments,'');};\n" + 1712 source + 'return __p;\n'; 1713 1714 try { 1715 var render = new Function(settings.variable || 'obj', '_', source); 1716 } catch (e) { 1717 e.source = source; 1718 throw e; 1719 } 1720 1721 var template = function(data) { 1722 return render.call(this, data, _); 1723 }; 1724 1725 // Provide the compiled source as a convenience for precompilation. 1726 var argument = settings.variable || 'obj'; 1727 template.source = 'function(' + argument + '){\n' + source + '}'; 1728 1729 return template; 1730 }; 1731 1732 // Add a "chain" function. Start chaining a wrapped Underscore object. 1733 _.chain = function(obj) { 1734 var instance = _(obj); 1735 instance._chain = true; 1736 return instance; 1737 }; 1738 1739 // OOP 1740 // --------------- 1741 // If Underscore is called as a function, it returns a wrapped object that 1742 // can be used OO-style. This wrapper holds altered versions of all the 1743 // underscore functions. Wrapped objects may be chained. 1744 1745 // Helper function to continue chaining intermediate results. 1746 var result = function(instance, obj) { 1747 return instance._chain ? _(obj).chain() : obj; 1748 }; 1749 1750 // Add your own custom functions to the Underscore object. 1751 _.mixin = function(obj) { 1752 _.each(_.functions(obj), function(name) { 1753 var func = _[name] = obj[name]; 1754 _.prototype[name] = function() { 1755 var args = [this._wrapped]; 1756 push.apply(args, arguments); 1757 return result(this, func.apply(_, args)); 1758 }; 1759 }); 1760 }; 1761 1762 // Add all of the Underscore functions to the wrapper object. 1763 _.mixin(_); 1764 1765 // Add all mutator Array functions to the wrapper. 1766 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 1767 var method = ArrayProto[name]; 1768 _.prototype[name] = function() { 1769 var obj = this._wrapped; 1770 method.apply(obj, arguments); 1771 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; 1772 return result(this, obj); 1773 }; 1774 }); 1775 1776 // Add all accessor Array functions to the wrapper. 1777 _.each(['concat', 'join', 'slice'], function(name) { 1778 var method = ArrayProto[name]; 1779 _.prototype[name] = function() { 1780 return result(this, method.apply(this._wrapped, arguments)); 1781 }; 1782 }); 1783 1784 // Extracts the result from a wrapped and chained object. 1785 _.prototype.value = function() { 1786 return this._wrapped; 1787 }; 1788 1789 // Provide unwrapping proxy for some methods used in engine operations 1790 // such as arithmetic and JSON stringification. 1791 _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; 1792 1793 _.prototype.toString = function() { 1794 return '' + this._wrapped; 1795 }; 1796 1797 // AMD registration happens at the end for compatibility with AMD loaders 1798 // that may not enforce next-turn semantics on modules. Even though general 1799 // practice for AMD registration is to be anonymous, underscore registers 1800 // as a named module because, like jQuery, it is a base library that is 1801 // popular enough to be bundled in a third party lib, but not be part of 1802 // an AMD load request. Those cases could generate an error when an 1803 // anonymous define() is called outside of a loader request. 1804 if (t
1804rue) { 1805 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 1806 return _; 1807 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 1808 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 1809 } 1810}.call(this)); 1811 1812 1813/***/ }), 1814/* 8 */ 1815/***/ (function(module, exports, __webpack_require__) { 1816 1817var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(0)], __WEBPACK_AMD_DEFINE_RESULT__ = (function iframeModule(mp) { 1818 'use strict'; 1819 1820 var MailPoet = mp; 1821 MailPoet.Iframe = { 1822 marginY: 20, 1823 autoSize: function autoSize(iframe) { 1824 if (!iframe) return; 1825 1826 this.setSize( 1827 iframe, 1828 iframe.contentWindow.document.body.scrollHeight 1829 ); 1830 }, 1831 setSize: function setSize(sizeIframe, i) { 1832 var iframe = sizeIframe; 1833 if (!iframe) return; 1834 1835 iframe.style.height = ( 1836 parseInt(i, 10) + this.marginY 1837 ) + 'px'; 1838 } 1839 }; 1840 1841 return MailPoet; 1842}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 1843 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 1844 1845 1846/***/ }), 1847/* 9 */ 1848/***/ (function(module, exports, __webpack_require__) { 1849 1850var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 1851 __webpack_require__(1) 1852 ], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( // eslint-disable-line func-names 1853 jQuery 1854 ) { 1855 var $ = jQuery; 1856 // Combination of jQuery.deparam and jQuery.serializeObject by Ben Alman. 1857 /*! 1858 * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010 1859 * http://benalman.com/projects/jquery-bbq-plugin/ 1860 * 1861 * Copyright (c) 2010 "Cowboy" Ben Alman 1862 * Dual licensed under the MIT and GPL licenses. 1863 * http://benalman.com/about/license/ 1864 */ 1865 /*! 1866 * jQuery serializeObject - v0.2 - 1/20/2010 1867 * http://benalman.com/projects/jquery-misc-plugins/ 1868 * 1869 * Copyright (c) 2010 "Cowboy" Ben Alman 1870 * Dual licensed under the MIT and GPL licenses. 1871 * http://benalman.com/about/license/ 1872 */ 1873 $.fn.mailpoetSerializeObject = function (coerce) { // eslint-disable-line func-names 1874 var obj = {}; 1875 var coerceTypes = { true: !0, false: !1, null: null }; 1876 1877 // Iterate over all name=value pairs. 1878 $.each(this.serializeArray(), function (j, v) { // eslint-disable-line func-names 1879 var key = v.name; 1880 var val = v.value; 1881 var cur = obj; 1882 var i = 0; 1883 1884 // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it 1885 // into its component parts. 1886 var keys = key.split('][');
1887 var keysLast = keys.length - 1; 1888 1889 // If the first keys part contains [ and the last ends with ], then [] 1890 // are correctly balanced. 1891 if (/\[/.test(keys[0]) && /\]$/.test(keys[keysLast])) { 1892 // Remove the trailing ] from the last keys part. 1893 keys[keysLast] = keys[keysLast].replace(/\]$/, ''); 1894 1895 // Split first keys part into two parts on the [ and add them back onto 1896 // the beginning of the keys array. 1897 keys = keys.shift().split('[').concat(keys); 1898 1899 keysLast = keys.length - 1; 1900 } else { 1901 // Basic 'foo' style key. 1902 keysLast = 0; 1903 } 1904 1905 // Coerce values. 1906 if (coerce) { 1907 if (val && !isNaN(val)) { // number 1908 val = +val; 1909 } else if (val === 'undefined') { // undefined 1910 val = undefined; 1911 } else if (coerceTypes[val] !== undefined) { // true, false, null 1912 val = coerceTypes[val]; 1913 } 1914 } 1915 1916 if (keysLast) { 1917 // Complex key, build deep object structure based on a few rules: 1918 // * The 'cur' pointer starts at the object top-level. 1919 // * [] = array push (n is set to array length), [n] = array if n is 1920 // numeric, otherwise object. 1921 // * If at the last keys part, set the value. 1922 // * For each keys part, if the current level is undefined create an 1923 // object or array based on the type of the next keys part. 1924 // * Move the 'cur' pointer to the next level. 1925 // * Rinse & repeat. 1926 for (; i <= keysLast; i += 1) { 1927 key = keys[i] === '' ? cur.length : keys[i]; 1928 cur[key] = i < keysLast 1929 ? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : []) 1930 : val; 1931 cur = cur[key]; 1932 } 1933 } else if ($.isArray(obj[key])) { 1934 // val is already an array, so push on the next value. 1935 obj[key].push(val); 1936 } else if (obj[key] !== undefined) { 1937 // val isn't an array, but since a second value has been specified, 1938 // convert val into an array. 1939 obj[key] = [obj[key], val]; 1940 } else { 1941 // val is a scalar. 1942 obj[key] = val; 1943 } 1944 }); 1945 1946 return obj; 1947 }; 1948 1949 return $; 1950 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 1951 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 1952 1953 1954/***/ }), 1955/* 10 */ 1956/***/ (function(module, exports, __webpack_require__) { 1957 1958var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ 1959 __webpack_require__(0), 1960 __webpack_require__(1), 1961 __webpack_require__(11) 1962], __WEBPACK_AMD_DEFINE_RESULT__ = (function ( // eslint-disable-line func-names 1963 MailPoet, 1964 jQuery 1965) { 1966 jQuery(function ($) { // eslint-disable-line func-names 1967 window.reCaptchaCallback = function reCaptchaCallback() { 1968 $('.mailpoet_recaptcha').each(function () { // eslint-disable-line func-names 1969 var sitekey = $(this).attr('data-sitekey'); 1970 var container = $(this).find('> .mailpoet_recaptcha_container').get(0); 1971 var field = $(this).find('> .mailpoet_recaptcha_field'); 1972 var widgetId; 1973 if (sitekey) { 1974 widgetId = window.grecaptcha.render(container, { sitekey: sitekey, size: 'compact' }); 1975 field.val(widgetId); 1976 } 1977 }); 1978 }; 1979 1980 function isSameDomain(url) { 1981 var link = document.createElement('a'); 1982 link.href = url; 1983 return (window.location.hostname === link.hostname); 1984 } 1985 1986 $(function () { // eslint-disable-line func-names 1987 // setup form validation 1988 $('form.mailpoet_form').each(function () { // eslint-disable-line func-names 1989 var form = $(this); 1990 1991 form.parsley().on('form:validated', function () { // eslint-disable-line func-names 1992 // clear messages 1993 form.find('.mailpoet_message > p').hide(); 1994 1995 // resize iframe 1996 if (window.frameElement !== null) { 1997 MailPoet.Iframe.autoSize(window.frameElement); 1998 } 1999 }); 2000 2001 form.parsley().on('form:submit', function (parsley) { // eslint-disable-line func-names 2002 var formData = form.mailpoetSerializeObject() || {}; 2003 // check if we're on the same domain 2004 if (isSameDomain(window.MailPoetForm.ajax_url) === false) { 2005 // non ajax post request 2006 return true; 2007 } 2008 2009 if (window.grecaptcha && formData.recaptcha) { 2010 formData.data.recaptcha = window.grecaptcha.getResponse(formData.recaptcha); 2011 } 2012 2013 // ajax request 2014 MailPoet.Ajax.post({ 2015 url: window.MailPoetForm.ajax_url, 2016 token: formData.token, 2017 api_version: formData.api_version, 2018 endpoint: 'subscribers', 2019 action: 'subscribe', 2020 data: formData.data 2021 }).fail(function (response) { // eslint-disable-line func-names 2022 form.find('.mailpoet_validate_error').html( 2023 response.errors.map(function (error) { // eslint-disable-line func-names 2024 return error.message; 2025 }).join('<br />') 2026 ).show(); 2027 }).done(function (response) { // eslint-disable-line func-names 2028 if (window.grecaptcha && formData.recaptcha) { 2029 window.grecaptcha.reset(formData.recaptcha); 2030 } 2031 return response; 2032 }).done(function (response) { // eslint-disable-line func-names 2033 // successfully subscribed 2034 if ( 2035 response.meta !== undefined 2036 && response.meta.redirect_url !== undefined 2037 ) { 2038 // go to page 2039 window.location.href = response.meta.redirect_url; 2040 } else { 2041 // display success message 2042 form.find('.mailpoet_validate_success').show(); 2043 } 2044 2045 // reset form 2046 form.trigger('reset'); 2047 // reset validation 2048 parsley.reset(); 2049 // reset captcha 2050 if (window.grecaptcha && formData.recaptcha) { 2051 window.grecaptcha.reset(formData.recaptcha); 2052 } 2053 2054 // resize iframe 2055 if ( 2056 window.frameElement !== null 2057 && MailPoet !== undefined 2058 && MailPoet.Iframe 2059 ) { 2060 MailPoet.Iframe.autoSize(window.frameElement); 2061 } 2062 }); 2063 2064 return false;
vendor: 93,668 bytes, lines 2065-4575
2065 }); 2066 }); 2067 }); 2068 }); 2069}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 2070 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 2071 2072 2073/***/ }), 2074/* 11 */ 2075/***/ (function(module, exports, __webpack_require__) { 2076 2077/* WEBPACK VAR INJECTION */(function(global) {/*! 2078* Parsley.js 2079* Version 2.8.1 - built Sat, Feb 3rd 2018, 2:27 pm 2080* http://parsleyjs.org 2081* Guillaume Potier - <[email protected]> 2082* Marc-Andre Lafortune - <[email protected]> 2083* MIT Licensed 2084*/ 2085 2086// The source code below is generated by babel as 2087// Parsley is written in ECMAScript 6 2088// 2089var _slice = Array.prototype.slice; 2090 2091var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); 2092 2093var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 2094 2095function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } 2096 2097(function (global, factory) { 2098 true ? module.exports = factory(__webpack_require__(1)) : typeof define === 'function' && define.amd ? define(['jquery'], factory) : global.parsley = factory(global.jQuery); 2099})(this, function ($) { 2100 'use strict'; 2101 2102 var globalID = 1; 2103 var pastWarnings = {}; 2104 2105 var Utils = { 2106 // Parsley DOM-API 2107 // returns object from dom attributes and values 2108 attr: function attr(element, namespace, obj) { 2109 var i; 2110 var attribute; 2111 var attributes; 2112 var regex = new RegExp('^' + namespace, 'i'); 2113 2114 if ('undefined' === typeof obj) obj = {};else { 2115 // Clear all own properties. This won't affect prototype's values 2116 for (i in obj) { 2117 if (obj.hasOwnProperty(i)) delete obj[i]; 2118 } 2119 } 2120 2121 if (!element) return obj; 2122 2123 attributes = element.attributes; 2124 for (i = attributes.length; i--;) { 2125 attribute = attributes[i]; 2126 2127 if (attribute && attribute.specified && regex.test(attribute.name)) { 2128 obj[this.camelize(attribute.name.slice(namespace.length))] = this.deserializeValue(attribute.value); 2129 } 2130 } 2131 2132 return obj; 2133 }, 2134 2135 checkAttr: function checkAttr(element, namespace, _checkAttr) { 2136 return element.hasAttribute(namespace + _checkAttr); 2137 }, 2138 2139 setAttr: function setAttr(element, namespace, attr, value) { 2140 element.setAttribute(this.dasherize(namespace + attr), String(value)); 2141 }, 2142 2143 getType: function getType(element) { 2144 return element.getAttribute('type') || 'text'; 2145 }, 2146 2147 generateID: function generateID() { 2148 return '' + globalID++; 2149 }, 2150 2151 /** Third party functions **/ 2152 deserializeValue: function deserializeValue(value) { 2153 var num; 2154 2155 try { 2156 return value ? value == "true" || (value == "false" ? false : value == "null" ? null : !isNaN(num = Number(value)) ? num : /^[\[\{]/.test(value) ? JSON.parse(value) : value) : value; 2157 } catch (e) { 2158 return value; 2159 } 2160 }, 2161 2162 // Zepto camelize function 2163 camelize: function camelize(str) { 2164 return str.replace(/-+(.)?/g, function (match, chr) { 2165 return chr ? chr.toUpperCase() : ''; 2166 }); 2167 }, 2168 2169 // Zepto dasherize function 2170 dasherize: function dasherize(str) { 2171 return str.replace(/::/g, '/').replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').replace(/([a-z\d])([A-Z])/g, '$1_$2').replace(/_/g, '-').toLowerCase(); 2172 }, 2173 2174 warn: function warn() { 2175 var _window$console; 2176 2177 if (window.console && 'function' === typeof window.console.warn) (_window$console = window.console).warn.apply(_window$console, arguments); 2178 }, 2179 2180 warnOnce: function warnOnce(msg) { 2181 if (!pastWarnings[msg]) { 2182 pastWarnings[msg] = true; 2183 this.warn.apply(this, arguments); 2184 } 2185 }, 2186 2187 _resetWarnings: function _resetWarnings() { 2188 pastWarnings = {}; 2189 }, 2190 2191 trimString: function trimString(string) { 2192 return string.replace(/^\s+|\s+$/g, ''); 2193 }, 2194 2195 parse: { 2196 date: function date(string) { 2197 var parsed = string.match(/^(\d{4,})-(\d\d)-(\d\d)$/); 2198 if (!parsed) return null; 2199 2200 var _parsed$map = parsed.map(function (x) { 2201 return parseInt(x, 10); 2202 }); 2203 2204 var _parsed$map2 = _slicedToArray(_parsed$map, 4); 2205 2206 var _ = _parsed$map2[0]; 2207 var year = _parsed$map2[1]; 2208 var month = _parsed$map2[2]; 2209 var day = _parsed$map2[3]; 2210 2211 var date = new Date(year, month - 1, day); 2212 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) return null; 2213 return date; 2214 }, 2215 string: function string(_string) { 2216 return _string; 2217 }, 2218 integer: function integer(string) { 2219 if (isNaN(string)) return null; 2220 return parseInt(string, 10); 2221 }, 2222 number: function number(string) { 2223 if (isNaN(string)) throw null; 2224 return parseFloat(string); 2225 }, 2226 'boolean': function _boolean(string) { 2227 return !/^\s*false\s*$/i.test(string); 2228 }, 2229 object: function object(string) { 2230 return Utils.deserializeValue(string); 2231 }, 2232 regexp: function regexp(_regexp) { 2233 var flags = ''; 2234 2235 // Test if RegExp is literal, if not, nothing to be done, otherwise, we need to isolate flags and pattern 2236 if (/^\/.*\/(?:[gimy]*)$/.test(_regexp)) { 2237 // Replace the regexp literal string with the first match group: ([gimy]*) 2238 // If no flag is present, this will be a blank string 2239 flags = _regexp.replace(/.*\/([gimy]*)$/, '$1'); 2240 // Again, replace the regexp literal string with the first match group: 2241 // everything excluding the opening and closing slashes and the flags 2242 _regexp = _regexp.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1'); 2243 } else { 2244 // Anchor regexp: 2245 _regexp = '^' + _regexp + '$'; 2246 } 2247 return new RegExp(_regexp, flags); 2248 } 2249 }, 2250 2251 parseRequirement: function parseRequirement(requirementType, string) { 2252 var converter = this.parse[requirementType || 'string']; 2253 if (!converter) throw 'Unknown requirement specification: "' + requirementType + '"'; 2254 var converted = converter(string); 2255 if (converted === null) throw 'Requirement is not a ' + requirementType + ': "' + string + '"'; 2256 return converted; 2257 }, 2258 2259 namespaceEvents: function namespaceEvents(events, namespace) { 2260 events = this.trimString(events || '').split(/\s+/); 2261 if (!events[0]) return ''; 2262 return $.map(events, function (evt) { 2263 return evt + '.' + namespace; 2264 }).join(' '); 2265 }, 2266 2267 difference: function difference(array, remove) { 2268 // This is O(N^2), should be optimized 2269 var result = []; 2270 $.each(array, function (_, elem) { 2271 if (remove.indexOf(elem) == -1) result.push(elem); 2272 }); 2273 return result; 2274 }, 2275 2276 // Alter-ego to native Promise.all, but for jQuery 2277 all: function all(promises) { 2278 // jQuery treats $.when() and $.when(singlePromise) differently; let's avoid that and add spurious elements 2279 return $.when.apply($, _toConsumableArray(promises).concat([42, 42])); 2280 }, 2281 2282 // Object.create polyfill, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill 2283 objectCreate: Object.create || (function () { 2284 var Object = function Object() {}; 2285 return function (prototype) { 2286 if (arguments.length > 1) { 2287 throw Error('Second argument not supported'); 2288 } 2289 if (typeof prototype != 'object') { 2290 throw TypeError('Argument must be an object'); 2291 } 2292 Object.prototype = prototype; 2293 var result = new Object(); 2294 Object.prototype = null; 2295 return result; 2296 }; 2297 })(), 2298 2299 _SubmitSelector: 'input[type="submit"], button:submit' 2300 }; 2301 2302 // All these options could be overriden and specified directly in DOM using 2303 // `data-parsley-` default DOM-API 2304 // eg: `inputs` can be set in DOM using `data-parsley-inputs="input, textarea"` 2305 // eg: `data-parsley-stop-on-first-failing-constraint="false"` 2306 2307 var Defaults = { 2308 // ### General 2309 2310 // Default data-namespace for DOM API 2311 namespace: 'data-parsley-', 2312 2313 // Supported inputs by default 2314 inputs: 'input, textarea, select', 2315 2316 // Excluded inputs by default 2317 excluded: 'input[type=button], input[type=submit], input[type=reset], input[type=hidden]', 2318 2319 // Stop validating field on highest priority failing constraint 2320 priorityEnabled: true, 2321 2322 // ### Field only 2323 2324 // identifier used to group together inputs (e.g. radio buttons...) 2325 multiple: null, 2326 2327 // identifier (or array of identifiers) used to validate only a select group of inputs 2328 group: null, 2329 2330 // ### UI 2331 // Enable\Disable error messages 2332 uiEnabled: true, 2333 2334 // Key events threshold before validation 2335 validationThreshold: 3, 2336 2337 // Focused field on form validation error. 'first'|'last'|'none' 2338 focus: 'first', 2339 2340 // event(s) that will trigger validation before first failure. eg: `input`... 2341 trigger: false, 2342 2343 // event(s) that will trigger validation after first failure. 2344 triggerAfterFailure: 'input', 2345 2346 // Class that would be added on every failing validation Parsley field 2347 errorClass: 'parsley-error', 2348 2349 // Same for success validation 2350 successClass: 'parsley-success', 2351 2352 // Return the `$element` that will receive these above success or error classes 2353 // Could also be (and given directly from DOM) a valid selector like `'#div'` 2354 classHandler: function classHandler(Field) {}, 2355 2356 // Return the `$element` where errors will be appended 2357 // Could also be (and given directly from DOM) a valid selector like `'#div'` 2358 errorsContainer: function errorsContainer(Field) {}, 2359 2360 // ul elem that would receive errors' list 2361 errorsWrapper: '<ul class="parsley-errors-list"></ul>', 2362 2363 // li elem that would receive error message 2364 errorTemplate: '<li></li>' 2365 }; 2366 2367 var Base = function Base() { 2368 this.__id__ = Utils.generateID(); 2369 }; 2370 2371 Base.prototype = { 2372 asyncSupport: true, // Deprecated 2373 2374 _pipeAccordingToValidationResult: function _pipeAccordingToValidationResult() { 2375 var _this = this; 2376 2377 var pipe = function pipe() { 2378 var r = $.Deferred(); 2379 if (true !== _this.validationResult) r.reject(); 2380 return r.resolve().promise(); 2381 }; 2382 return [pipe, pipe]; 2383 }, 2384 2385 actualizeOptions: function actualizeOptions() { 2386 Utils.attr(this.element, this.options.namespace, this.domOptions); 2387 if (this.parent && this.parent.actualizeOptions) this.parent.actualizeOptions(); 2388 return this; 2389 }, 2390 2391 _resetOptions: function _resetOptions(initOptions) { 2392 this.domOptions = Utils.objectCreate(this.parent.options); 2393 this.options = Utils.objectCreate(this.domOptions); 2394 // Shallow copy of ownProperties of initOptions: 2395 for (var i in initOptions) { 2396 if (initOptions.hasOwnProperty(i)) this.options[i] = initOptions[i]; 2397 } 2398 this.actualizeOptions(); 2399 }, 2400 2401 _listeners: null, 2402 2403 // Register a callback for the given event name 2404 // Callback is called with context as the first argument and the `this` 2405 // The context is the current parsley instance, or window.Parsley if global 2406 // A return value of `false` will interrupt the calls 2407 on: function on(name, fn) { 2408 this._listeners = this._listeners || {}; 2409 var queue = this._listeners[name] = this._listeners[name] || []; 2410 queue.push(fn); 2411 2412 return this; 2413 }, 2414 2415 // Deprecated. Use `on` instead 2416 subscribe: function subscribe(name, fn) { 2417 $.listenTo(this, name.toLowerCase(), fn); 2418 }, 2419 2420 // Unregister a callback (or all if none is given) for the given event name 2421 off: function off(name, fn) { 2422 var queue = this._listeners && this._listeners[name]; 2423 if (queue) { 2424 if (!fn) { 2425 delete this._listeners[name]; 2426 } else { 2427 for (var i = queue.length; i--;) if (queue[i] === fn) queue.splice(i, 1); 2428 } 2429 } 2430 return this; 2431 }, 2432 2433 // Deprecated. Use `off` 2434 unsubscribe: function unsubscribe(name, fn) { 2435 $.unsubscribeTo(this, name.toLowerCase()); 2436 }, 2437 2438 // Trigger an event of the given name 2439 // A return value of `false` interrupts the callback chain 2440 // Returns false if execution was interrupted 2441 trigger: function trigger(name, target, extraArg) { 2442 target = target || this; 2443 var queue = this._listeners && this._listeners[name]; 2444 var result; 2445 var parentResult; 2446 if (queue) { 2447 for (var i = queue.length; i--;) { 2448 result = queue[i].call(target, target, extraArg); 2449 if (result === false) return result; 2450 } 2451 } 2452 if (this.parent) { 2453 return this.parent.trigger(name, target, extraArg); 2454 } 2455 return true; 2456 }, 2457 2458 asyncIsValid: function asyncIsValid(group, force) { 2459 Utils.warnOnce("asyncIsValid is deprecated; please use whenValid instead"); 2460 return this.whenValid({ group: group, force: force }); 2461 }, 2462 2463 _findRelated: function _findRelated() { 2464 return this.options.multiple ? $(this.parent.element.querySelectorAll('[' + this.options.namespace + 'multiple="' + this.options.multiple + '"]')) : this.$element; 2465 } 2466 }; 2467 2468 var convertArrayRequirement = function convertArrayRequirement(string, length) { 2469 var m = string.match(/^\s*\[(.*)\]\s*$/); 2470 if (!m) throw 'Requirement is not an array: "' + string + '"'; 2471 var values = m[1].split(',').map(Utils.trimString); 2472 if (values.length !== length) throw 'Requirement has ' + values.length + ' values when ' + length + ' are needed'; 2473 return values; 2474 }; 2475 2476 var convertExtraOptionRequirement = function convertExtraOptionRequirement(requirementSpec, string, extraOptionReader) { 2477 var main = null; 2478 var extra = {}; 2479 for (var key in requirementSpec) { 2480 if (key) { 2481 var value = extraOptionReader(key); 2482 if ('string' === typeof value) value = Utils.parseRequirement(requirementSpec[key], value); 2483 extra[key] = value; 2484 } else { 2485 main = Utils.parseRequirement(requirementSpec[key], string); 2486 } 2487 } 2488 return [main, extra]; 2489 }; 2490 2491 // A Validator needs to implement the methods `validate` and `parseRequirements` 2492 2493 var Validator = function Validator(spec) { 2494 $.extend(true, this, spec); 2495 }; 2496 2497 Validator.prototype = { 2498 // Returns `true` iff the given `value` is valid according the given requirements. 2499 validate: function validate(value, requirementFirstArg) { 2500 if (this.fn) { 2501 // Legacy style validator 2502 2503 if (arguments.length > 3) // If more args then value, requirement, instance... 2504 requirementFirstArg = [].slice.call(arguments, 1, -1); // Skip first arg (value) and last (instance), combining the rest 2505 return this.fn(value, requirementFirstArg); 2506 } 2507 2508 if (Array.isArray(value)) { 2509 if (!this.validateMultiple) throw 'Validator `' + this.name + '` does not handle multiple values'; 2510 return this.validateMultiple.apply(this, arguments); 2511 } else { 2512 var instance = arguments[arguments.length - 1]; 2513 if (this.validateDate && instance._isDateInput()) { 2514 arguments[0] = Utils.parse.date(arguments[0]); 2515 if (arguments[0] === null) return false; 2516 return this.validateDate.apply(this, arguments); 2517 } 2518 if (this.validateNumber) { 2519 if (isNaN(value)) return false; 2520 arguments[0] = parseFloat(arguments[0]); 2521 return this.validateNumber.apply(this, arguments); 2522 } 2523 if (this.validateString) { 2524 return this.validateString.apply(this, arguments); 2525 } 2526 throw 'Validator `' + this.name + '` only handles multiple values'; 2527 } 2528 }, 2529 2530 // Parses `requirements` into an array of arguments, 2531 // according to `this.requirementType` 2532 parseRequirements: function parseRequirements(requirements, extraOptionReader) { 2533 if ('string' !== typeof requirements) { 2534 // Assume requirement already parsed 2535 // but make sure we return an array 2536 return Array.isArray(requirements) ? requirements : [requirements]; 2537 } 2538 var type = this.requirementType; 2539 if (Array.isArray(type)) { 2540 var values = convertArrayRequirement(requirements, type.length); 2541 for (var i = 0; i < values.length; i++) values[i] = Utils.parseRequirement(type[i], values[i]); 2542 return values; 2543 } else if ($.isPlainObject(type)) { 2544 return convertExtraOptionRequirement(type, requirements, extraOptionReader); 2545 } else { 2546 return [Utils.parseRequirement(type, requirements)]; 2547 } 2548 }, 2549 // Defaults: 2550 requirementType: 'string', 2551 2552 priority: 2 2553 2554 }; 2555 2556 var ValidatorRegistry = function ValidatorRegistry(validators, catalog) { 2557 this.__class__ = 'ValidatorRegistry'; 2558 2559 // Default Parsley locale is en 2560 this.locale = 'en'; 2561 2562 this.init(validators || {}, catalog || {}); 2563 }; 2564 2565 var typeTesters = { 2566 email: /^((([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-zA-Z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/, 2567 2568 // Follow https://www.w3.org/TR/html5/infrastructure.html#floating-point-numbers 2569 number: /^-?(\d*\.)?\d+(e[-+]?\d+)?$/i, 2570 2571 integer: /^-?\d+$/, 2572 2573 digits: /^\d+$/, 2574 2575 alphanum: /^\w+$/i, 2576 2577 date: { 2578 test: function test(value) { 2579 return Utils.parse.date(value) !== null; 2580 } 2581 }, 2582 2583 url: new RegExp("^" + 2584 // protocol identifier 2585 "(?:(?:https?|ftp)://)?" + // ** mod: make scheme optional 2586 // user:pass authentication 2587 "(?:\\S+(?::\\S*)?@)?" + "(?:" + 2588 // IP address exclusion 2589 // private & local networks 2590 // "(?!(?:10|127)(?:\\.\\d{1,3}){3})" + // ** mod: allow local networks 2591 // "(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks 2592 // "(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})" + // ** mod: allow local networks 2593 // IP address dotted notation octets 2594 // excludes loopback network 0.0.0.0 2595 // excludes reserved space >= 224.0.0.0 2596 // excludes network & broacast addresses 2597 // (first & last IP address of each class) 2598 "(?:[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]))" + "|" + 2599 // host name 2600 '(?:(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)' + 2601 // domain name 2602 '(?:\\.(?:[a-zA-Z\\u00a1-\\uffff0-9]-*)*[a-zA-Z\\u00a1-\\uffff0-9]+)*' + 2603 // TLD identifier 2604 '(?:\\.(?:[a-zA-Z\\u00a1-\\uffff]{2,}))' + ")" + 2605 // port number 2606 "(?::\\d{2,5})?" + 2607 // resource path 2608 "(?:/\\S*)?" + "$") 2609 }; 2610 typeTesters.range = typeTesters.number; 2611 2612 // See http://stackoverflow.com/a/10454560/8279 2613 var decimalPlaces = function decimalPlaces(num) { 2614 var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); 2615 if (!match) { 2616 return 0; 2617 } 2618 return Math.max(0, 2619 // Number of digits right of decimal point. 2620 (match[1] ? match[1].length : 0) - ( 2621 // Adjust for scientific notation. 2622 match[2] ? +match[2] : 0)); 2623 }; 2624 2625 // parseArguments('number', ['1', '2']) => [1, 2] 2626 var ValidatorRegistry__parseArguments = function ValidatorRegistry__parseArguments(type, args) { 2627 return args.map(Utils.parse[type]); 2628 }; 2629 // operatorToValidator returns a validating function for an operator function, applied to the given type 2630 var ValidatorRegistry__operatorToValidator = function ValidatorRegistry__operatorToValidator(type, operator) { 2631 return function (value) { 2632 for (var _len = arguments.length, requirementsAndInput = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 2633 requirementsAndInput[_key - 1] = arguments[_key]; 2634 } 2635 2636 requirementsAndInput.pop(); // Get rid of `input` argument 2637 return operator.apply(undefined, [value].concat(_toConsumableArray(ValidatorRegistry__parseArguments(type, requirementsAndInput)))); 2638 }; 2639 }; 2640 2641 var ValidatorRegistry__comparisonOperator = function ValidatorRegistry__comparisonOperator(operator) { 2642 return { 2643 validateDate: ValidatorRegistry__operatorToValidator('date', operator), 2644 validateNumber: ValidatorRegistry__operatorToValidator('number', operator), 2645 requirementType: operator.length <= 2 ? 'string' : ['string', 'string'], // Support operators with a 1 or 2 requirement(s) 2646 priority: 30 2647 }; 2648 }; 2649 2650 ValidatorRegistry.prototype = { 2651 init: function init(validators, catalog) { 2652 this.catalog = catalog; 2653 // Copy prototype's validators: 2654 this.validators = _extends({}, this.validators); 2655 2656 for (var name in validators) this.addValidator(name, validators[name].fn, validators[name].priority); 2657 2658 window.Parsley.trigger('parsley:validator:init'); 2659 }, 2660 2661 // Set new messages locale if we have dictionary loaded in ParsleyConfig.i18n 2662 setLocale: function setLocale(locale) { 2663 if ('undefined' === typeof this.catalog[locale]) throw new Error(locale + ' is not available in the catalog'); 2664 2665 this.locale = locale; 2666 2667 return this; 2668 }, 2669 2670 // Add a new messages catalog for a given locale. Set locale for this catalog if set === `true` 2671 addCatalog: function addCatalog(locale, messages, set) { 2672 if ('object' === typeof messages) this.catalog[locale] = messages; 2673 2674 if (true === set) return this.setLocale(locale); 2675 2676 return this; 2677 }, 2678 2679 // Add a specific message for a given constraint in a given locale 2680 addMessage: function addMessage(locale, name, message) { 2681 if ('undefined' === typeof this.catalog[locale]) this.catalog[locale] = {}; 2682 2683 this.catalog[locale][name] = message; 2684 2685 return this; 2686 }, 2687 2688 // Add messages for a given locale 2689 addMessages: function addMessages(locale, nameMessageObject) { 2690 for (var name in nameMessageObject) this.addMessage(locale, name, nameMessageObject[name]); 2691 2692 return this; 2693 }, 2694 2695 // Add a new validator 2696 // 2697 // addValidator('custom', { 2698 // requirementType: ['integer', 'integer'], 2699 // validateString: function(value, from, to) {}, 2700 // priority: 22, 2701 // messages: { 2702 // en: "Hey, that's no good", 2703 // fr: "Aye aye, pas bon du tout", 2704 // } 2705 // }) 2706 // 2707 // Old API was addValidator(name, function, priority) 2708 // 2709 addValidator: function addValidator(name, arg1, arg2) { 2710 if (this.validators[name]) Utils.warn('Validator "' + name + '" is already defined.');else if (Defaults.hasOwnProperty(name)) { 2711 Utils.warn('"' + name + '" is a restricted keyword and is not a valid validator name.'); 2712 return; 2713 } 2714 return this._setValidator.apply(this, arguments); 2715 }, 2716 2717 hasValidator: function hasValidator(name) { 2718 return !!this.validators[name]; 2719 }, 2720 2721 updateValidator: function updateValidator(name, arg1, arg2) { 2722 if (!this.validators[name]) { 2723 Utils.warn('Validator "' + name + '" is not already defined.'); 2724 return this.addValidator.apply(this, arguments); 2725 } 2726 return this._setValidator.apply(this, arguments); 2727 }, 2728 2729 removeValidator: function removeValidator(name) { 2730 if (!this.validators[name]) Utils.warn('Validator "' + name + '" is not defined.'); 2731 2732 delete this.validators[name]; 2733 2734 return this; 2735 }, 2736 2737 _setValidator: function _setValidator(name, validator, priority) { 2738 if ('object' !== typeof validator) { 2739 // Old style validator, with `fn` and `priority` 2740 validator = { 2741 fn: validator, 2742 priority: priority 2743 }; 2744 } 2745 if (!validator.validate) { 2746 validator = new Validator(validator); 2747 } 2748 this.validators[name] = validator; 2749 2750 for (var locale in validator.messages || {}) this.addMessage(locale, name, validator.messages[locale]); 2751 2752 return this; 2753 }, 2754 2755 getErrorMessage: function getErrorMessage(constraint) { 2756 var message; 2757 2758 // Type constraints are a bit different, we have to match their requirements too to find right error message 2759 if ('type' === constraint.name) { 2760 var typeMessages = this.catalog[this.locale][constraint.name] || {}; 2761 message = typeMessages[constraint.requirements]; 2762 } else message = this.formatMessage(this.catalog[this.locale][constraint.name], constraint.requirements); 2763 2764 return message || this.catalog[this.locale].defaultMessage || this.catalog.en.defaultMessage; 2765 }, 2766 2767 // Kind of light `sprintf()` implementation 2768 formatMessage: function formatMessage(string, parameters) { 2769 if ('object' === typeof parameters) { 2770 for (var i in parameters) string = this.formatMessage(string, parameters[i]); 2771 2772 return string; 2773 } 2774 2775 return 'string' === typeof string ? string.replace(/%s/i, parameters) : ''; 2776 }, 2777 2778 // Here is the Parsley default validators list. 2779 // A validator is an object with the following key values: 2780 // - priority: an integer 2781 // - requirement: 'string' (default), 'integer', 'number', 'regexp' or an Array of these 2782 // - validateString, validateMultiple, validateNumber: functions returning `true`, `false` or a promise 2783 // Alternatively, a validator can be a function that returns such an object 2784 // 2785 validators: { 2786 notblank: { 2787 validateString: function validateString(value) { 2788 return (/\S/.test(value) 2789 ); 2790 }, 2791 priority: 2 2792 }, 2793 required: { 2794 validateMultiple: function validateMultiple(values) { 2795 return values.length > 0; 2796 }, 2797 validateString: function validateString(value) { 2798 return (/\S/.test(value) 2799 ); 2800 }, 2801 priority: 512 2802 }, 2803 type: { 2804 validateString: function validateString(value, type) { 2805 var _ref = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; 2806 2807 var _ref$step = _ref.step; 2808 var step = _ref$step === undefined ? 'any' : _ref$step; 2809 var _ref$base = _ref.base; 2810 var base = _ref$base === undefined ? 0 : _ref$base; 2811 2812 var tester = typeTesters[type]; 2813 if (!tester) { 2814 throw new Error('validator type `' + type + '` is not supported'); 2815 } 2816 if (!tester.test(value)) return false; 2817 if ('number' === type) { 2818 if (!/^any$/i.test(step || '')) { 2819 var nb = Number(value); 2820 var decimals = Math.max(decimalPlaces(step), decimalPlaces(base)); 2821 if (decimalPlaces(nb) > decimals) // Value can't have too many decimals 2822 return false; 2823 // Be careful of rounding errors by using integers. 2824 var toInt = function toInt(f) { 2825 return Math.round(f * Math.pow(10, decimals)); 2826 }; 2827 if ((toInt(nb) - toInt(base)) % toInt(step) != 0) return false; 2828 } 2829 } 2830 return true; 2831 }, 2832 requirementType: { 2833 '': 'string', 2834 step: 'string', 2835 base: 'number' 2836 }, 2837 priority: 256 2838 }, 2839 pattern: { 2840 validateString: function validateString(value, regexp) { 2841 return regexp.test(value); 2842 }, 2843 requirementType: 'regexp', 2844 priority: 64 2845 }, 2846 minlength: { 2847 validateString: function validateString(value, requirement) { 2848 return value.length >= requirement; 2849 }, 2850 requirementType: 'integer', 2851 priority: 30 2852 }, 2853 maxlength: { 2854 validateString: function validateString(value, requirement) { 2855 return value.length <= requirement; 2856 }, 2857 requirementType: 'integer', 2858 priority: 30 2859 }, 2860 length: { 2861 validateString: function validateString(value, min, max) { 2862 return value.length >= min && value.length <= max; 2863 }, 2864 requirementType: ['integer', 'integer'], 2865 priority: 30 2866 }, 2867 mincheck: { 2868 validateMultiple: function validateMultiple(values, requirement) { 2869 return values.length >= requirement; 2870 }, 2871 requirementType: 'integer', 2872 priority: 30 2873 }, 2874 maxcheck: { 2875 validateMultiple: function validateMultiple(values, requirement) { 2876 return values.length <= requirement; 2877 }, 2878 requirementType: 'integer', 2879 priority: 30 2880 }, 2881 check: { 2882 validateMultiple: function validateMultiple(values, min, max) { 2883 return values.length >= min && values.length <= max; 2884 }, 2885 requirementType: ['integer', 'integer'], 2886 priority: 30 2887 }, 2888 min: ValidatorRegistry__comparisonOperator(function (value, requirement) { 2889 return value >= requirement; 2890 }), 2891 max: ValidatorRegistry__comparisonOperator(function (value, requirement) { 2892 return value <= requirement; 2893 }), 2894 range: ValidatorRegistry__comparisonOperator(function (value, min, max) { 2895 return value >= min && value <= max; 2896 }), 2897 equalto: { 2898 validateString: function validateString(value, refOrValue) { 2899 var $reference = $(refOrValue); 2900 if ($reference.length) return value === $reference.val();else return value === refOrValue; 2901 }, 2902 priority: 256 2903 } 2904 } 2905 }; 2906 2907 var UI = {}; 2908 2909 var diffResults = function diffResults(newResult, oldResult, deep) { 2910 var added = []; 2911 var kept = []; 2912 2913 for (var i = 0; i < newResult.length; i++) { 2914 var found = false; 2915 2916 for (var j = 0; j < oldResult.length; j++) if (newResult[i].assert.name === oldResult[j].assert.name) { 2917 found = true; 2918 break; 2919 } 2920 2921 if (found) kept.push(newResult[i]);else added.push(newResult[i]); 2922 } 2923 2924 return { 2925 kept: kept, 2926 added: added, 2927 removed: !deep ? diffResults(oldResult, newResult, true).added : [] 2928 }; 2929 }; 2930 2931 UI.Form = { 2932 2933 _actualizeTriggers: function _actualizeTriggers() { 2934 var _this2 = this; 2935 2936 this.$element.on('submit.Parsley', function (evt) { 2937 _this2.onSubmitValidate(evt); 2938 }); 2939 this.$element.on('click.Parsley', Utils._SubmitSelector, function (evt) { 2940 _this2.onSubmitButton(evt); 2941 }); 2942 2943 // UI could be disabled 2944 if (false === this.options.uiEnabled) return; 2945 2946 this.element.setAttribute('novalidate', ''); 2947 }, 2948 2949 focus: function focus() { 2950 this._focusedField = null; 2951 2952 if (true === this.validationResult || 'none' === this.options.focus) return null; 2953 2954 for (var i = 0; i < this.fields.length; i++) { 2955 var field = this.fields[i]; 2956 if (true !== field.validationResult && field.validationResult.length > 0 && 'undefined' === typeof field.options.noFocus) { 2957 this._focusedField = field.$element; 2958 if ('first' === this.options.focus) break; 2959 } 2960 } 2961 2962 if (null === this._focusedField) return null; 2963 2964 return this._focusedField.focus(); 2965 }, 2966 2967 _destroyUI: function _destroyUI() { 2968 // Reset all event listeners 2969 this.$element.off('.Parsley'); 2970 } 2971 2972 }; 2973 2974 UI.Field = { 2975 2976 _reflowUI: function _reflowUI() { 2977 this._buildUI(); 2978 2979 // If this field doesn't have an active UI don't bother doing something 2980 if (!this._ui) return; 2981 2982 // Diff between two validation results 2983 var diff = diffResults(this.validationResult, this._ui.lastValidationResult); 2984 2985 // Then store current validation result for next reflow 2986 this._ui.lastValidationResult = this.validationResult; 2987 2988 // Handle valid / invalid / none field class 2989 this._manageStatusClass(); 2990 2991 // Add, remove, updated errors messages 2992 this._manageErrorsMessages(diff); 2993 2994 // Triggers impl 2995 this._actualizeTriggers(); 2996 2997 // If field is not valid for the first time, bind keyup trigger to ease UX and quickly inform user 2998 if ((diff.kept.length || diff.added.length) && !this._failedOnce) { 2999 this._failedOnce = true; 3000 this._actualizeTriggers(); 3001 } 3002 }, 3003 3004 // Returns an array of field's error message(s) 3005 getErrorsMessages: function getErrorsMessages() { 3006 // No error message, field is valid 3007 if (true === this.validationResult) return []; 3008 3009 var messages = []; 3010 3011 for (var i = 0; i < this.validationResult.length; i++) messages.push(this.validationResult[i].errorMessage || this._getErrorMessage(this.validationResult[i].assert)); 3012 3013 return messages; 3014 }, 3015 3016 // It's a goal of Parsley that this method is no longer required [#1073] 3017 addError: function addError(name) { 3018 var _ref2 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3019 3020 var message = _ref2.message; 3021 var assert = _ref2.assert; 3022 var _ref2$updateClass = _ref2.updateClass; 3023 var updateClass = _ref2$updateClass === undefined ? true : _ref2$updateClass; 3024 3025 this._buildUI(); 3026 this._addError(name, { message: message, assert: assert }); 3027 3028 if (updateClass) this._errorClass(); 3029 }, 3030 3031 // It's a goal of Parsley that this method is no longer required [#1073] 3032 updateError: function updateError(name) { 3033 var _ref3 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3034 3035 var message = _ref3.message; 3036 var assert = _ref3.assert; 3037 var _ref3$updateClass = _ref3.updateClass; 3038 var updateClass = _ref3$updateClass === undefined ? true : _ref3$updateClass; 3039 3040 this._buildUI(); 3041 this._updateError(name, { message: message, assert: assert }); 3042 3043 if (updateClass) this._errorClass(); 3044 }, 3045 3046 // It's a goal of Parsley that this method is no longer required [#1073] 3047 removeError: function removeError(name) { 3048 var _ref4 = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; 3049 3050 var _ref4$updateClass = _ref4.updateClass; 3051 var updateClass = _ref4$updateClass === undefined ? true : _ref4$updateClass; 3052 3053 this._buildUI(); 3054 this._removeError(name); 3055 3056 // edge case possible here: remove a standard Parsley error that is still failing in this.validationResult 3057 // but highly improbable cuz' manually removing a well Parsley handled error makes no sense. 3058 if (updateClass) this._manageStatusClass(); 3059 }, 3060 3061 _manageStatusClass: function _manageStatusClass() { 3062 if (this.hasConstraints() && this.needsValidation() && true === this.validationResult) this._successClass();else if (this.validationResult.length > 0) this._errorClass();else this._resetClass(); 3063 }, 3064 3065 _manageErrorsMessages: function _manageErrorsMessages(diff) { 3066 if ('undefined' !== typeof this.options.errorsMessagesDisabled) return; 3067 3068 // Case where we have errorMessage option that configure an unique field error message, regardless failing validators 3069 if ('undefined' !== typeof this.options.errorMessage) { 3070 if (diff.added.length || diff.kept.length) { 3071 this._insertErrorWrapper(); 3072 3073 if (0 === this._ui.$errorsWrapper.find('.parsley-custom-error-message').length) this._ui.$errorsWrapper.append($(this.options.errorTemplate).addClass('parsley-custom-error-message')); 3074 3075 return this._ui.$errorsWrapper.addClass('filled').find('.parsley-custom-error-message').html(this.options.errorMessage); 3076 } 3077 3078 return this._ui.$errorsWrapper.removeClass('filled').find('.parsley-custom-error-message').remove(); 3079 } 3080 3081 // Show, hide, update failing constraints messages 3082 for (var i = 0; i < diff.removed.length; i++) this._removeError(diff.removed[i].assert.name); 3083 3084 for (i = 0; i < diff.added.length; i++) this._addError(diff.added[i].assert.name, { message: diff.added[i].errorMessage, assert: diff.added[i].assert }); 3085 3086 for (i = 0; i < diff.kept.length; i++) this._updateError(diff.kept[i].assert.name, { message: diff.kept[i].errorMessage, assert: diff.kept[i].assert }); 3087 }, 3088 3089 _addError: function _addError(name, _ref5) { 3090 var message = _ref5.message; 3091 var assert = _ref5.assert; 3092 3093 this._insertErrorWrapper(); 3094 this._ui.$errorClassHandler.attr('aria-describedby', this._ui.errorsWrapperId); 3095 this._ui.$errorsWrapper.addClass('filled').append($(this.options.errorTemplate).addClass('parsley-' + name).html(message || this._getErrorMessage(assert))); 3096 }, 3097 3098 _updateError: function _updateError(name, _ref6) { 3099 var message = _ref6.message; 3100 var assert = _ref6.assert; 3101 3102 this._ui.$errorsWrapper.addClass('filled').find('.parsley-' + name).html(message || this._getErrorMessage(assert)); 3103 }, 3104 3105 _removeError: function _removeError(name) { 3106 this._ui.$errorClassHandler.removeAttr('aria-describedby'); 3107 this._ui.$errorsWrapper.removeClass('filled').find('.parsley-' + name).remove(); 3108 }, 3109 3110 _getErrorMessage: function _getErrorMessage(constraint) { 3111 var customConstraintErrorMessage = constraint.name + 'Message'; 3112 3113 if ('undefined' !== typeof this.options[customConstraintErrorMessage]) return window.Parsley.formatMessage(this.options[customConstraintErrorMessage], constraint.requirements); 3114 3115 return window.Parsley.getErrorMessage(constraint); 3116 }, 3117 3118 _buildUI: function _buildUI() { 3119 // UI could be already built or disabled 3120 if (this._ui || false === this.options.uiEnabled) return; 3121 3122 var _ui = {}; 3123 3124 // Give field its Parsley id in DOM 3125 this.element.setAttribute(this.options.namespace + 'id', this.__id__); 3126 3127 /** Generate important UI elements and store them in this **/ 3128 // $errorClassHandler is the $element that woul have parsley-error and parsley-success classes 3129 _ui.$errorClassHandler = this._manageClassHandler(); 3130 3131 // $errorsWrapper is a div that would contain the various field errors, it will be appended into $errorsContainer 3132 _ui.errorsWrapperId = 'parsley-id-' + (this.options.multiple ? 'multiple-' + this.options.multiple : this.__id__); 3133 _ui.$errorsWrapper = $(this.options.errorsWrapper).attr('id', _ui.errorsWrapperId); 3134 3135 // ValidationResult UI storage to detect what have changed bwt two validations, and update DOM accordingly 3136 _ui.lastValidationResult = []; 3137 _ui.validationInformationVisible = false; 3138 3139 // Store it in this for later 3140 this._ui = _ui; 3141 }, 3142 3143 // Determine which element will have `parsley-error` and `parsley-success` classes 3144 _manageClassHandler: function _manageClassHandler() { 3145 // Class handled could also be determined by function given in Parsley options 3146 if ('string' === typeof this.options.classHandler && $(this.options.classHandler).length) return $(this.options.classHandler); 3147 3148 // Class handled could also be determined by function given in Parsley options 3149 var $handlerFunction = this.options.classHandler; 3150 3151 // It might also be the function name of a global function 3152 if ('string' === typeof this.options.classHandler && 'function' === typeof window[this.options.classHandler]) $handlerFunction = window[this.options.classHandler]; 3153 3154 if ('function' === typeof $handlerFunction) { 3155 var $handler = $handlerFunction.call(this, this); 3156 3157 // If this function returned a valid existing DOM element, go for it 3158 if ('undefined' !== typeof $handler && $handler.length) return $handler; 3159 } else if ('object' === typeof $handlerFunction && $handlerFunction instanceof jQuery && $handlerFunction.length) { 3160 return $handlerFunction; 3161 } else if ($handlerFunction) { 3162 Utils.warn('The class handler `' + $handlerFunction + '` does not exist in DOM nor as a global JS function'); 3163 } 3164 3165 return this._inputHolder(); 3166 }, 3167 3168 _inputHolder: function _inputHolder() { 3169 // if simple element (input, texatrea, select...) it will perfectly host the classes and precede the error container 3170 if (!this.options.multiple || this.element.nodeName === 'SELECT') return this.$element; 3171 3172 // But if multiple element (radio, checkbox), that would be their parent 3173 return this.$element.parent(); 3174 }, 3175 3176 _insertErrorWrapper: function _insertErrorWrapper() { 3177 var $errorsContainer = this.options.errorsContainer; 3178 3179 // Nothing to do if already inserted 3180 if (0 !== this._ui.$errorsWrapper.parent().length) return this._ui.$errorsWrapper.parent(); 3181 3182 if ('string' === typeof $errorsContainer) { 3183 if ($($errorsContainer).length) return $($errorsContainer).append(this._ui.$errorsWrapper);else if ('function' === typeof window[$errorsContainer]) $errorsContainer = window[$errorsContainer];else Utils.warn('The errors container `' + $errorsContainer + '` does not exist in DOM nor as a global JS function'); 3184 } 3185 3186 if ('function' === typeof $errorsContainer) $errorsContainer = $errorsContainer.call(this, this); 3187 3188 if ('object' === typeof $errorsContainer && $errorsContainer.length) return $errorsContainer.append(this._ui.$errorsWrapper); 3189 3190 return this._inputHolder().after(this._ui.$errorsWrapper); 3191 }, 3192 3193 _actualizeTriggers: function _actualizeTriggers() { 3194 var _this3 = this; 3195 3196 var $toBind = this._findRelated(); 3197 var trigger; 3198 3199 // Remove Parsley events already bound on this field 3200 $toBind.off('.Parsley'); 3201 if (this._failedOnce) $toBind.on(Utils.namespaceEvents(this.options.triggerAfterFailure, 'Parsley'), function () { 3202 _this3._validateIfNeeded(); 3203 });else if (trigger = Utils.namespaceEvents(this.options.trigger, 'Parsley')) { 3204 $toBind.on(trigger, function (event) { 3205 _this3._validateIfNeeded(event); 3206 }); 3207 } 3208 }, 3209 3210 _validateIfNeeded: function _validateIfNeeded(event) { 3211 var _this4 = this; 3212 3213 // For keyup, keypress, keydown, input... events that could be a little bit obstrusive 3214 // do not validate if val length < min threshold on first validation. Once field have been validated once and info 3215 // about success or failure have been displayed, always validate with this trigger to reflect every yalidation change. 3216 if (event && /key|input/.test(event.type)) if (!(this._ui && this._ui.validationInformationVisible) && this.getValue().length <= this.options.validationThreshold) return; 3217 3218 if (this.options.debounce) { 3219 window.clearTimeout(this._debounced); 3220 this._debounced = window.setTimeout(function () { 3221 return _this4.validate(); 3222 }, this.options.debounce); 3223 } else this.validate(); 3224 }, 3225 3226 _resetUI: function _resetUI() { 3227 // Reset all event listeners 3228 this._failedOnce = false; 3229 this._actualizeTriggers(); 3230 3231 // Nothing to do if UI never initialized for this field 3232 if ('undefined' === typeof this._ui) return; 3233 3234 // Reset all errors' li 3235 this._ui.$errorsWrapper.removeClass('filled').children().remove(); 3236 3237 // Reset validation class 3238 this._resetClass(); 3239 3240 // Reset validation flags and last validation result 3241 this._ui.lastValidationResult = []; 3242 this._ui.validationInformationVisible = false; 3243 }, 3244 3245 _destroyUI: function _destroyUI() { 3246 this._resetUI(); 3247 3248 if ('undefined' !== typeof this._ui) this._ui.$errorsWrapper.remove(); 3249 3250 delete this._ui; 3251 }, 3252 3253 _successClass: function _successClass() { 3254 this._ui.validationInformationVisible = true; 3255 this._ui.$errorClassHandler.removeClass(this.options.errorClass).addClass(this.options.successClass); 3256 }, 3257 _errorClass: function _errorClass() { 3258 this._ui.validationInformationVisible = true; 3259 this._ui.$errorClassHandler.removeClass(this.options.successClass).addClass(this.options.errorClass); 3260 }, 3261 _resetClass: function _resetClass() { 3262 this._ui.$errorClassHandler.removeClass(this.options.successClass).removeClass(this.options.errorClass); 3263 } 3264 }; 3265 3266 var Form = function Form(element, domOptions, options) { 3267 this.__class__ = 'Form'; 3268 3269 this.element = element; 3270 this.$element = $(element); 3271 this.domOptions = domOptions; 3272 this.options = options; 3273 this.parent = window.Parsley; 3274 3275 this.fields = []; 3276 this.validationResult = null; 3277 }; 3278 3279 var Form__statusMapping = { pending: null, resolved: true, rejected: false }; 3280 3281 Form.prototype = { 3282 onSubmitValidate: function onSubmitValidate(event) { 3283 var _this5 = this; 3284 3285 // This is a Parsley generated submit event, do not validate, do not prevent, simply exit and keep normal behavior 3286 if (true === event.parsley) return; 3287 3288 // If we didn't come here through a submit button, use the first one in the form 3289 var submitSource = this._submitSource || this.$element.find(Utils._SubmitSelector)[0]; 3290 this._submitSource = null; 3291 this.$element.find('.parsley-synthetic-submit-button').prop('disabled', true); 3292 if (submitSource && null !== submitSource.getAttribute('formnovalidate')) return; 3293 3294 window.Parsley._remoteCache = {}; 3295 3296 var promise = this.whenValidate({ event: event }); 3297 3298 if ('resolved' === promise.state() && false !== this._trigger('submit')) { 3299 // All good, let event go through. We make this distinction because browsers 3300 // differ in their handling of `submit` being called from inside a submit event [#1047] 3301 } else { 3302 // Rejected or pending: cancel this submit 3303 event.stopImmediatePropagation(); 3304 event.preventDefault(); 3305 if ('pending' === promise.state()) promise.done(function () { 3306 _this5._submit(submitSource); 3307 }); 3308 } 3309 }, 3310 3311 onSubmitButton: function onSubmitButton(event) { 3312 this._submitSource = event.currentTarget; 3313 }, 3314 // internal 3315 // _submit submits the form, this time without going through the validations. 3316 // Care must be taken to "fake" the actual submit button being clicked. 3317 _submit: function _submit(submitSource) { 3318 if (false === this._trigger('submit')) return; 3319 // Add submit button's data 3320 if (submitSource) { 3321 var $synthetic = this.$element.find('.parsley-synthetic-submit-button').prop('disabled', false); 3322 if (0 === $synthetic.length) $synthetic = $('<input class="parsley-synthetic-submit-button" type="hidden">').appendTo(this.$element); 3323 $synthetic.attr({ 3324 name: submitSource.getAttribute('name'), 3325 value: submitSource.getAttribute('value') 3326 }); 3327 } 3328 3329 this.$element.trigger(_extends($.Event('submit'), { parsley: true })); 3330 }, 3331 3332 // Performs validation on fields while triggering events. 3333 // @returns `true` if all validations succeeds, `false` 3334 // if a failure is immediately detected, or `null` 3335 // if dependant on a promise. 3336 // Consider using `whenValidate` instead. 3337 validate: function validate(options) { 3338 if (arguments.length >= 1 && !$.isPlainObject(options)) { 3339 Utils.warnOnce('Calling validate on a parsley form without passing arguments as an object is deprecated.'); 3340 3341 var _arguments = _slice.call(arguments); 3342 3343 var group = _arguments[0]; 3344 var force = _arguments[1]; 3345 var event = _arguments[2]; 3346 3347 options = { group: group, force: force, event: event }; 3348 } 3349 return Form__statusMapping[this.whenValidate(options).state()]; 3350 }, 3351 3352 whenValidate: function whenValidate() { 3353 var _Utils$all$done$fail$always, 3354 _this6 = this; 3355 3356 var _ref7 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 3357 3358 var group = _ref7.group; 3359 var force = _ref7.force; 3360 var event = _ref7.event; 3361 3362 this.submitEvent = event; 3363 if (event) { 3364 this.submitEvent = _extends({}, event, { preventDefault: function preventDefault() { 3365 Utils.warnOnce("Using `this.submitEvent.preventDefault()` is deprecated; instead, call `this.validationResult = false`"); 3366 _this6.validationResult = false; 3367 } }); 3368 } 3369 this.validationResult = true; 3370 3371 // fire validate event to eventually modify things before every validation 3372 this._trigger('validate'); 3373 3374 // Refresh form DOM options and form's fields that could have changed 3375 this._refreshFields(); 3376 3377 var promises = this._withoutReactualizingFormOptions(function () { 3378 return $.map(_this6.fields, function (field) { 3379 return field.whenValidate({ force: force, group: group }); 3380 }); 3381 }); 3382 3383 return (_Utils$all$done$fail$always = Utils.all(promises).done(function () { 3384 _this6._trigger('success'); 3385 }).fail(function () { 3386 _this6.validationResult = false; 3387 _this6.focus(); 3388 _this6._trigger('error'); 3389 }).always(function () { 3390 _this6._trigger('validated'); 3391 })).pipe.apply(_Utils$all$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult())); 3392 }, 3393 3394 // Iterate over refreshed fields, and stop on first failure. 3395 // Returns `true` if all fields are valid, `false` if a failure is detected 3396 // or `null` if the result depends on an unresolved promise. 3397 // Prefer using `whenValid` instead. 3398 isValid: function isValid(options) { 3399 if (arguments.length >= 1 && !$.isPlainObject(options)) { 3400 Utils.warnOnce('Calling isValid on a parsley form without passing arguments as an object is deprecated.'); 3401 3402 var _arguments2 = _slice.call(arguments); 3403 3404 var group = _arguments2[0]; 3405 var force = _arguments2[1]; 3406 3407 options = { group: group, force: force }; 3408 } 3409 return Form__statusMapping[this.whenValid(options).state()]; 3410 }, 3411 3412 // Iterate over refreshed fields and validate them. 3413 // Returns a promise. 3414 // A validation that immediately fails will interrupt the validations. 3415 whenValid: function whenValid() { 3416 var _this7 = this; 3417 3418 var _ref8 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 3419 3420 var group = _ref8.group; 3421 var force = _ref8.force; 3422 3423 this._refreshFields(); 3424 3425 var promises = this._withoutReactualizingFormOptions(function () { 3426 return $.map(_this7.fields, function (field) { 3427 return field.whenValid({ group: group, force: force }); 3428 }); 3429 }); 3430 return Utils.all(promises); 3431 }, 3432 3433 refresh: function refresh() { 3434 this._refreshFields(); 3435 return this; 3436 }, 3437 3438 // Reset UI 3439 reset: function reset() { 3440 // Form case: emit a reset event for each field 3441 for (var i = 0; i < this.fields.length; i++) this.fields[i].reset(); 3442 3443 this._trigger('reset'); 3444 }, 3445 3446 // Destroy Parsley instance (+ UI) 3447 destroy: function destroy() { 3448 // Field case: emit destroy event to clean UI and then destroy stored instance 3449 this._destroyUI(); 3450 3451 // Form case: destroy all its fields and then destroy stored instance 3452 for (var i = 0; i < this.fields.length; i++) this.fields[i].destroy(); 3453 3454 this.$element.removeData('Parsley'); 3455 this._trigger('destroy'); 3456 }, 3457 3458 _refreshFields: function _refreshFields() { 3459 return this.actualizeOptions()._bindFields(); 3460 }, 3461 3462 _bindFields: function _bindFields() { 3463 var _this8 = this; 3464 3465 var oldFields = this.fields; 3466 3467 this.fields = []; 3468 this.fieldsMappedById = {}; 3469 3470 this._withoutReactualizingFormOptions(function () { 3471 _this8.$element.find(_this8.options.inputs).not(_this8.options.excluded).each(function (_, element) { 3472 var fieldInstance = new window.Parsley.Factory(element, {}, _this8); 3473 3474 // Only add valid and not excluded `Field` and `FieldMultiple` children 3475 if (('Field' === fieldInstance.__class__ || 'FieldMultiple' === fieldInstance.__class__) && true !== fieldInstance.options.excluded) { 3476 var uniqueId = fieldInstance.__class__ + '-' + fieldInstance.__id__; 3477 if ('undefined' === typeof _this8.fieldsMappedById[uniqueId]) { 3478 _this8.fieldsMappedById[uniqueId] = fieldInstance; 3479 _this8.fields.push(fieldInstance); 3480 } 3481 } 3482 }); 3483 3484 $.each(Utils.difference(oldFields, _this8.fields), function (_, field) { 3485 field.reset(); 3486 }); 3487 }); 3488 return this; 3489 }, 3490 3491 // Internal only. 3492 // Looping on a form's fields to do validation or similar 3493 // will trigger reactualizing options on all of them, which 3494 // in turn will reactualize the form's options. 3495 // To avoid calling actualizeOptions so many times on the form 3496 // for nothing, _withoutReactualizingFormOptions temporarily disables 3497 // the method actualizeOptions on this form while `fn` is called. 3498 _withoutReactualizingFormOptions: function _withoutReactualizingFormOptions(fn) { 3499 var oldActualizeOptions = this.actualizeOptions; 3500 this.actualizeOptions = function () { 3501 return this; 3502 }; 3503 var result = fn(); 3504 this.actualizeOptions = oldActualizeOptions; 3505 return result; 3506 }, 3507 3508 // Internal only. 3509 // Shortcut to trigger an event 3510 // Returns true iff event is not interrupted and default not prevented. 3511 _trigger: function _trigger(eventName) { 3512 return this.trigger('form:' + eventName); 3513 } 3514 3515 }; 3516 3517 var Constraint = function Constraint(parsleyField, name, requirements, priority, isDomConstraint) { 3518 var validatorSpec = window.Parsley._validatorRegistry.validators[name]; 3519 var validator = new Validator(validatorSpec); 3520 priority = priority || parsleyField.options[name + 'Priority'] || validator.priority; 3521 isDomConstraint = true === isDomConstraint; 3522 3523 _extends(this, { 3524 validator: validator, 3525 name: name, 3526 requirements: requirements, 3527 priority: priority, 3528 isDomConstraint: isDomConstraint 3529 }); 3530 this._parseRequirements(parsleyField.options); 3531 }; 3532 3533 var capitalize = function capitalize(str) { 3534 var cap = str[0].toUpperCase(); 3535 return cap + str.slice(1); 3536 }; 3537 3538 Constraint.prototype = { 3539 validate: function validate(value, instance) { 3540 var _validator; 3541 3542 return (_validator = this.validator).validate.apply(_validator, [value].concat(_toConsumableArray(this.requirementList), [instance])); 3543 }, 3544 3545 _parseRequirements: function _parseRequirements(options) { 3546 var _this9 = this; 3547 3548 this.requirementList = this.validator.parseRequirements(this.requirements, function (key) { 3549 return options[_this9.name + capitalize(key)]; 3550 }); 3551 } 3552 }; 3553 3554 var Field = function Field(field, domOptions, options, parsleyFormInstance) { 3555 this.__class__ = 'Field'; 3556 3557 this.element = field; 3558 this.$element = $(field); 3559 3560 // Set parent if we have one 3561 if ('undefined' !== typeof parsleyFormInstance) { 3562 this.parent = parsleyFormInstance; 3563 } 3564 3565 this.options = options; 3566 this.domOptions = domOptions; 3567 3568 // Initialize some properties 3569 this.constraints = []; 3570 this.constraintsByName = {}; 3571 this.validationResult = true; 3572 3573 // Bind constraints 3574 this._bindConstraints(); 3575 }; 3576 3577 var parsley_field__statusMapping = { pending: null, resolved: true, rejected: false }; 3578 3579 Field.prototype = { 3580 // # Public API 3581 // Validate field and trigger some events for mainly `UI` 3582 // @returns `true`, an array of the validators that failed, or 3583 // `null` if validation is not finished. Prefer using whenValidate 3584 validate: function validate(options) { 3585 if (arguments.length >= 1 && !$.isPlainObject(options)) { 3586 Utils.warnOnce('Calling validate on a parsley field without passing arguments as an object is deprecated.'); 3587 options = { options: options }; 3588 } 3589 var promise = this.whenValidate(options); 3590 if (!promise) // If excluded with `group` option 3591 return true; 3592 switch (promise.state()) { 3593 case 'pending': 3594 return null; 3595 case 'resolved': 3596 return true; 3597 case 'rejected': 3598 return this.validationResult; 3599 } 3600 }, 3601 3602 // Validate field and trigger some events for mainly `UI` 3603 // @returns a promise that succeeds only when all validations do 3604 // or `undefined` if field is not in the given `group`. 3605 whenValidate: function whenValidate() { 3606 var _whenValid$always$done$fail$always, 3607 _this10 = this; 3608 3609 var _ref9 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 3610 3611 var force = _ref9.force; 3612 var group = _ref9.group; 3613 3614 // do not validate a field if not the same as given validation group 3615 this.refresh(); 3616 if (group && !this._isInGroup(group)) return; 3617 3618 this.value = this.getValue(); 3619 3620 // Field Validate event. `this.value` could be altered for custom needs 3621 this._trigger('validate'); 3622 3623 return (_whenValid$always$done$fail$always = this.whenValid({ force: force, value: this.value, _refreshed: true }).always(function () { 3624 _this10._reflowUI(); 3625 }).done(function () { 3626 _this10._trigger('success'); 3627 }).fail(function () { 3628 _this10._trigger('error'); 3629 }).always(function () { 3630 _this10._trigger('validated'); 3631 })).pipe.apply(_whenValid$always$done$fail$always, _toConsumableArray(this._pipeAccordingToValidationResult())); 3632 }, 3633 3634 hasConstraints: function hasConstraints() { 3635 return 0 !== this.constraints.length; 3636 }, 3637 3638 // An empty optional field does not need validation 3639 needsValidation: function needsValidation(value) { 3640 if ('undefined' === typeof value) value = this.getValue(); 3641 3642 // If a field is empty and not required, it is valid 3643 // Except if `data-parsley-validate-if-empty` explicitely added, useful for some custom validators 3644 if (!value.length && !this._isRequired() && 'undefined' === typeof this.options.validateIfEmpty) return false; 3645 3646 return true; 3647 }, 3648 3649 _isInGroup: function _isInGroup(group) { 3650 if (Array.isArray(this.options.group)) return -1 !== $.inArray(group, this.options.group); 3651 return this.options.group === group; 3652 }, 3653 3654 // Just validate field. Do not trigger any event. 3655 // Returns `true` iff all constraints pass, `false` if there are failures, 3656 // or `null` if the result can not be determined yet (depends on a promise) 3657 // See also `whenValid`. 3658 isValid: function isValid(options) { 3659 if (arguments.length >= 1 && !$.isPlainObject(options)) { 3660 Utils.warnOnce('Calling isValid on a parsley field without passing arguments as an object is deprecated.'); 3661 3662 var _arguments3 = _slice.call(arguments); 3663 3664 var force = _arguments3[0]; 3665 var value = _arguments3[1]; 3666 3667 options = { force: force, value: value }; 3668 } 3669 var promise = this.whenValid(options); 3670 if (!promise) // Excluded via `group` 3671 return true; 3672 return parsley_field__statusMapping[promise.state()]; 3673 }, 3674 3675 // Just validate field. Do not trigger any event. 3676 // @returns a promise that succeeds only when all validations do 3677 // or `undefined` if the field is not in the given `group`. 3678 // The argument `force` will force validation of empty fields. 3679 // If a `value` is given, it will be validated instead of the value of the input. 3680 whenValid: function whenValid() { 3681 var _this11 = this; 3682 3683 var _ref10 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; 3684 3685 var _ref10$force = _ref10.force; 3686 var force = _ref10$force === undefined ? false : _ref10$force; 3687 var value = _ref10.value; 3688 var group = _ref10.group; 3689 var _refreshed = _ref10._refreshed; 3690 3691 // Recompute options and rebind constraints to have latest changes 3692 if (!_refreshed) this.refresh(); 3693 // do not validate a field if not the same as given validation group 3694 if (group && !this._isInGroup(group)) return; 3695 3696 this.validationResult = true; 3697 3698 // A field without constraint is valid 3699 if (!this.hasConstraints()) return $.when(); 3700 3701 // Value could be passed as argument, needed to add more power to 'field:validate' 3702 if ('undefined' === typeof value || null === value) value = this.getValue(); 3703 3704 if (!this.needsValidation(value) && true !== force) return $.when(); 3705 3706 var groupedConstraints = this._getGroupedConstraints(); 3707 var promises = []; 3708 $.each(groupedConstraints, function (_, constraints) { 3709 // Process one group of constraints at a time, we validate the constraints 3710 // and combine the promises together. 3711 var promise = Utils.all($.map(constraints, function (constraint) { 3712 return _this11._validateConstraint(value, constraint); 3713 })); 3714 promises.push(promise); 3715 if (promise.state() === 'rejected') return false; // Interrupt processing if a group has already failed 3716 }); 3717 return Utils.all(promises); 3718 }, 3719 3720 // @returns a promise 3721 _validateConstraint: function _validateConstraint(value, constraint) { 3722 var _this12 = this; 3723 3724 var result = constraint.validate(value, this); 3725 // Map false to a failed promise 3726 if (false === result) result = $.Deferred().reject(); 3727 // Make sure we return a promise and that we record failures 3728 return Utils.all([result]).fail(function (errorMessage) { 3729 if (!(_this12.validationResult instanceof Array)) _this12.validationResult = []; 3730 _this12.validationResult.push({ 3731 assert: constraint, 3732 errorMessage: 'string' === typeof errorMessage && errorMessage 3733 }); 3734 }); 3735 }, 3736 3737 // @returns Parsley field computed value that could be overrided or configured in DOM 3738 getValue: function getValue() { 3739 var value; 3740 3741 // Value could be overriden in DOM or with explicit options 3742 if ('function' === typeof this.options.value) value = this.options.value(this);else if ('undefined' !== typeof this.options.value) value = this.options.value;else value = this.$element.val(); 3743 3744 // Handle wrong DOM or configurations 3745 if ('undefined' === typeof value || null === value) return ''; 3746 3747 return this._handleWhitespace(value); 3748 }, 3749 3750 // Reset UI 3751 reset: function reset() { 3752 this._resetUI(); 3753 return this._trigger('reset'); 3754 }, 3755 3756 // Destroy Parsley instance (+ UI) 3757 destroy: function destroy() { 3758 // Field case: emit destroy event to clean UI and then destroy stored instance 3759 this._destroyUI(); 3760 this.$element.removeData('Parsley'); 3761 this.$element.removeData('FieldMultiple'); 3762 this._trigger('destroy'); 3763 }, 3764 3765 // Actualize options and rebind constraints 3766 refresh: function refresh() { 3767 this._refreshConstraints(); 3768 return this; 3769 }, 3770 3771 _refreshConstraints: function _refreshConstraints() { 3772 return this.actualizeOptions()._bindConstraints(); 3773 }, 3774 3775 refreshConstraints: function refreshConstraints() { 3776 Utils.warnOnce("Parsley's refreshConstraints is deprecated. Please use refresh"); 3777 return this.refresh(); 3778 }, 3779 3780 /** 3781 * Add a new constraint to a field 3782 * 3783 * @param {String} name 3784 * @param {Mixed} requirements optional 3785 * @param {Number} priority optional 3786 * @param {Boolean} isDomConstraint optional 3787 */ 3788 addConstraint: function addConstraint(name, requirements, priority, isDomConstraint) { 3789 3790 if (window.Parsley._validatorRegistry.validators[name]) { 3791 var constraint = new Constraint(this, name, requirements, priority, isDomConstraint); 3792 3793 // if constraint already exist, delete it and push new version 3794 if ('undefined' !== this.constraintsByName[constraint.name]) this.removeConstraint(constraint.name); 3795 3796 this.constraints.push(constraint); 3797 this.constraintsByName[constraint.name] = constraint; 3798 } 3799 3800 return this; 3801 }, 3802 3803 // Remove a constraint 3804 removeConstraint: function removeConstraint(name) { 3805 for (var i = 0; i < this.constraints.length; i++) if (name === this.constraints[i].name) { 3806 this.constraints.splice(i, 1); 3807 break; 3808 } 3809 delete this.constraintsByName[name]; 3810 return this; 3811 }, 3812 3813 // Update a constraint (Remove + re-add) 3814 updateConstraint: function updateConstraint(name, parameters, priority) { 3815 return this.removeConstraint(name).addConstraint(name, parameters, priority); 3816 }, 3817 3818 // # Internals 3819 3820 // Internal only. 3821 // Bind constraints from config + options + DOM 3822 _bindConstraints: function _bindConstraints() { 3823 var constraints = []; 3824 var constraintsByName = {}; 3825 3826 // clean all existing DOM constraints to only keep javascript user constraints 3827 for (var i = 0; i < this.constraints.length; i++) if (false === this.constraints[i].isDomConstraint) { 3828 constraints.push(this.constraints[i]); 3829 constraintsByName[this.constraints[i].name] = this.constraints[i]; 3830 } 3831 3832 this.constraints = constraints; 3833 this.constraintsByName = constraintsByName; 3834 3835 // then re-add Parsley DOM-API constraints 3836 for (var name in this.options) this.addConstraint(name, this.options[name], undefined, true); 3837 3838 // finally, bind special HTML5 constraints 3839 return this._bindHtml5Constraints(); 3840 }, 3841 3842 // Internal only. 3843 // Bind specific HTML5 constraints to be HTML5 compliant 3844 _bindHtml5Constraints: function _bindHtml5Constraints() { 3845 // html5 required 3846 if (null !== this.element.getAttribute('required')) this.addConstraint('required', true, undefined, true); 3847 3848 // html5 pattern 3849 if (null !== this.element.getAttribute('pattern')) this.addConstraint('pattern', this.element.getAttribute('pattern'), undefined, true); 3850 3851 // range 3852 var min = this.element.getAttribute('min'); 3853 var max = this.element.getAttribute('max'); 3854 if (null !== min && null !== max) this.addConstraint('range', [min, max], undefined, true); 3855 3856 // HTML5 min 3857 else if (null !== min) this.addConstraint('min', min, undefined, true); 3858 3859 // HTML5 max 3860 else if (null !== max) this.addConstraint('max', max, undefined, true); 3861 3862 // length 3863 if (null !== this.element.getAttribute('minlength') && null !== this.element.getAttribute('maxlength')) this.addConstraint('length', [this.element.getAttribute('minlength'), this.element.getAttribute('maxlength')], undefined, true); 3864 3865 // HTML5 minlength 3866 else if (null !== this.element.getAttribute('minlength')) this.addConstraint('minlength', this.element.getAttribute('minlength'), undefined, true); 3867 3868 // HTML5 maxlength 3869 else if (null !== this.element.getAttribute('maxlength')) this.addConstraint('maxlength', this.element.getAttribute('maxlength'), undefined, true); 3870 3871 // html5 types 3872 var type = Utils.getType(this.element); 3873 3874 // Small special case here for HTML5 number: integer validator if step attribute is undefined or an integer value, number otherwise 3875 if ('number' === type) { 3876 return this.addConstraint('type', ['number', { 3877 step: this.element.getAttribute('step') || '1', 3878 base: min || this.element.getAttribute('value') 3879 }], undefined, true); 3880 // Regular other HTML5 supported types 3881 } else if (/^(email|url|range|date)$/i.test(type)) { 3882 return this.addConstraint('type', type, undefined, true); 3883 } 3884 return this; 3885 }, 3886 3887 // Internal only. 3888 // Field is required if have required constraint without `false` value 3889 _isRequired: function _isRequired() { 3890 if ('undefined' === typeof this.constraintsByName.required) return false; 3891 3892 return false !== this.constraintsByName.required.requirements; 3893 }, 3894 3895 // Internal only. 3896 // Shortcut to trigger an event 3897 _trigger: function _trigger(eventName) { 3898 return this.trigger('field:' + eventName); 3899 }, 3900 3901 // Internal only 3902 // Handles whitespace in a value 3903 // Use `data-parsley-whitespace="squish"` to auto squish input value 3904 // Use `data-parsley-whitespace="trim"` to auto trim input value 3905 _handleWhitespace: function _handleWhitespace(value) { 3906 if (true === this.options.trimValue) Utils.warnOnce('data-parsley-trim-value="true" is deprecated, please use data-parsley-whitespace="trim"'); 3907 3908 if ('squish' === this.options.whitespace) value = value.replace(/\s{2,}/g, ' '); 3909 3910 if ('trim' === this.options.whitespace || 'squish' === this.options.whitespace || true === this.options.trimValue) value = Utils.trimString(value); 3911 3912 return value; 3913 }, 3914 3915 _isDateInput: function _isDateInput() { 3916 var c = this.constraintsByName.type; 3917 return c && c.requirements === 'date'; 3918 }, 3919 3920 // Internal only. 3921 // Returns the constraints, grouped by descending priority. 3922 // The result is thus an array of arrays of constraints. 3923 _getGroupedConstraints: function _getGroupedConstraints() { 3924 if (false === this.options.priorityEnabled) return [this.constraints]; 3925 3926 var groupedConstraints = []; 3927 var index = {}; 3928 3929 // Create array unique of priorities 3930 for (var i = 0; i < this.constraints.length; i++) { 3931 var p = this.constraints[i].priority; 3932 if (!index[p]) groupedConstraints.push(index[p] = []); 3933 index[p].push(this.constraints[i]); 3934 } 3935 // Sort them by priority DESC 3936 groupedConstraints.sort(function (a, b) { 3937 return b[0].priority - a[0].priority; 3938 }); 3939 3940 return groupedConstraints; 3941 } 3942 3943 }; 3944 3945 var parsley_field = Field; 3946 3947 var Multiple = function Multiple() { 3948 this.__class__ = 'FieldMultiple'; 3949 }; 3950 3951 Multiple.prototype = { 3952 // Add new `$element` sibling for multiple field 3953 addElement: function addElement($element) { 3954 this.$elements.push($element); 3955 3956 return this; 3957 }, 3958 3959 // See `Field._refreshConstraints()` 3960 _refreshConstraints: function _refreshConstraints() { 3961 var fieldConstraints; 3962 3963 this.constraints = []; 3964 3965 // Select multiple special treatment 3966 if (this.element.nodeName === 'SELECT') { 3967 this.actualizeOptions()._bindConstraints(); 3968 3969 return this; 3970 } 3971 3972 // Gather all constraints for each input in the multiple group 3973 for (var i = 0; i < this.$elements.length; i++) { 3974 3975 // Check if element have not been dynamically removed since last binding 3976 if (!$('html').has(this.$elements[i]).length) { 3977 this.$elements.splice(i, 1); 3978 continue; 3979 } 3980 3981 fieldConstraints = this.$elements[i].data('FieldMultiple')._refreshConstraints().constraints; 3982 3983 for (var j = 0; j < fieldConstraints.length; j++) this.addConstraint(fieldConstraints[j].name, fieldConstraints[j].requirements, fieldConstraints[j].priority, fieldConstraints[j].isDomConstraint); 3984 } 3985 3986 return this; 3987 }, 3988 3989 // See `Field.getValue()` 3990 getValue: function getValue() { 3991 // Value could be overriden in DOM 3992 if ('function' === typeof this.options.value) return this.options.value(this);else if ('undefined' !== typeof this.options.value) return this.options.value; 3993 3994 // Radio input case 3995 if (this.element.nodeName === 'INPUT') { 3996 var type = Utils.getType(this.element); 3997 if (type === 'radio') return this._findRelated().filter(':checked').val() || ''; 3998 3999 // checkbox input case 4000 if (type === 'checkbox') { 4001 var values = []; 4002 4003 this._findRelated().filter(':checked').each(function () { 4004 values.push($(this).val()); 4005 }); 4006 4007 return values; 4008 } 4009 } 4010 4011 // Select multiple case 4012 if (this.element.nodeName === 'SELECT' && null === this.$element.val()) return []; 4013 4014 // Default case that should never happen 4015 return this.$element.val(); 4016 }, 4017 4018 _init: function _init() { 4019 this.$elements = [this.$element]; 4020 4021 return this; 4022 } 4023 }; 4024 4025 var Factory = function Factory(element, options, parsleyFormInstance) { 4026 this.element = element; 4027 this.$element = $(element); 4028 4029 // If the element has already been bound, returns its saved Parsley instance 4030 var savedparsleyFormInstance = this.$element.data('Parsley'); 4031 if (savedparsleyFormInstance) { 4032 4033 // If the saved instance has been bound without a Form parent and there is one given in this call, add it 4034 if ('undefined' !== typeof parsleyFormInstance && savedparsleyFormInstance.parent === window.Parsley) { 4035 savedparsleyFormInstance.parent = parsleyFormInstance; 4036 savedparsleyFormInstance._resetOptions(savedparsleyFormInstance.options); 4037 } 4038 4039 if ('object' === typeof options) { 4040 _extends(savedparsleyFormInstance.options, options); 4041 } 4042 4043 return savedparsleyFormInstance; 4044 } 4045 4046 // Parsley must be instantiated with a DOM element or jQuery $element 4047 if (!this.$element.length) throw new Error('You must bind Parsley on an existing element.'); 4048 4049 if ('undefined' !== typeof parsleyFormInstance && 'Form' !== parsleyFormInstance.__class__) throw new Error('Parent instance must be a Form instance'); 4050 4051 this.parent = parsleyFormInstance || window.Parsley; 4052 return this.init(options); 4053 }; 4054 4055 Factory.prototype = { 4056 init: function init(options) { 4057 this.__class__ = 'Parsley'; 4058 this.__version__ = '2.8.1'; 4059 this.__id__ = Utils.generateID(); 4060 4061 // Pre-compute options 4062 this._resetOptions(options); 4063 4064 // A Form instance is obviously a `<form>` element but also every node that is not an input and has the `data-parsley-validate` attribute 4065 if (this.element.nodeName === 'FORM' || Utils.checkAttr(this.element, this.options.namespace, 'validate') && !this.$element.is(this.options.inputs)) return this.bind('parsleyForm'); 4066 4067 // Every other element is bound as a `Field` or `FieldMultiple` 4068 return this.isMultiple() ? this.handleMultiple() : this.bind('parsleyField'); 4069 }, 4070 4071 isMultiple: function isMultiple() { 4072 var type = Utils.getType(this.element); 4073 return type === 'radio' || type === 'checkbox' || this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple'); 4074 }, 4075 4076 // Multiples fields are a real nightmare :( 4077 // Maybe some refactoring would be appreciated here... 4078 handleMultiple: function handleMultiple() { 4079 var _this13 = this; 4080 4081 var name; 4082 var multiple; 4083 var parsleyMultipleInstance; 4084 4085 // Handle multiple name 4086 this.options.multiple = this.options.multiple || (name = this.element.getAttribute('name')) || this.element.getAttribute('id'); 4087 4088 // Special select multiple input 4089 if (this.element.nodeName === 'SELECT' && null !== this.element.getAttribute('multiple')) { 4090 this.options.multiple = this.options.multiple || this.__id__; 4091 return this.bind('parsleyFieldMultiple'); 4092 4093 // Else for radio / checkboxes, we need a `name` or `data-parsley-multiple` to properly bind it 4094 } else if (!this.options.multiple) { 4095 Utils.warn('To be bound by Parsley, a radio, a checkbox and a multiple select input must have either a name or a multiple option.', this.$element); 4096 return this; 4097 } 4098 4099 // Remove special chars 4100 this.options.multiple = this.options.multiple.replace(/(:|\.|\[|\]|\{|\}|\$)/g, ''); 4101 4102 // Add proper `data-parsley-multiple` to siblings if we have a valid multiple name 4103 if (name) { 4104 $('input[name="' + name + '"]').each(function (i, input) { 4105 var type = Utils.getType(input); 4106 if (type === 'radio' || type === 'checkbox') input.setAttribute(_this13.options.namespace + 'multiple', _this13.options.multiple); 4107 }); 4108 } 4109 4110 // Check here if we don't already have a related multiple instance saved 4111 var $previouslyRelated = this._findRelated(); 4112 for (var i = 0; i < $previouslyRelated.length; i++) { 4113 parsleyMultipleInstance = $($previouslyRelated.get(i)).data('Parsley'); 4114 if ('undefined' !== typeof parsleyMultipleInstance) { 4115 4116 if (!this.$element.data('FieldMultiple')) { 4117 parsleyMultipleInstance.addElement(this.$element); 4118 } 4119 4120 break; 4121 } 4122 } 4123 4124 // Create a secret Field instance for every multiple field. It will be stored in `data('FieldMultiple')` 4125 // And will be useful later to access classic `Field` stuff while being in a `FieldMultiple` instance 4126 this.bind('parsleyField', true); 4127 4128 return parsleyMultipleInstance || this.bind('parsleyFieldMultiple'); 4129 }, 4130 4131 // Return proper `Form`, `Field` or `FieldMultiple` 4132 bind: function bind(type, doNotStore) { 4133 var parsleyInstance; 4134 4135 switch (type) { 4136 case 'parsleyForm': 4137 parsleyInstance = $.extend(new Form(this.element, this.domOptions, this.options), new Base(), window.ParsleyExtend)._bindFields(); 4138 break; 4139 case 'parsleyField': 4140 parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Base(), window.ParsleyExtend); 4141 break; 4142 case 'parsleyFieldMultiple': 4143 parsleyInstance = $.extend(new parsley_field(this.element, this.domOptions, this.options, this.parent), new Multiple(), new Base(), window.ParsleyExtend)._init(); 4144 break; 4145 default: 4146 throw new Error(type + 'is not a supported Parsley type'); 4147 } 4148 4149 if (this.options.multiple) Utils.setAttr(this.element, this.options.namespace, 'multiple', this.options.multiple); 4150 4151 if ('undefined' !== typeof doNotStore) { 4152 this.$element.data('FieldMultiple', parsleyInstance); 4153 4154 return parsleyInstance; 4155 } 4156 4157 // Store the freshly bound instance in a DOM element for later access using jQuery `data()` 4158 this.$element.data('Parsley', parsleyInstance); 4159 4160 // Tell the world we have a new Form or Field instance! 4161 parsleyInstance._actualizeTriggers(); 4162 parsleyInstance._trigger('init'); 4163 4164 return parsleyInstance; 4165 } 4166 }; 4167 4168 var vernums = $.fn.jquery.split('.'); 4169 if (parseInt(vernums[0]) <= 1 && parseInt(vernums[1]) < 8) { 4170 throw "The loaded version of jQuery is too old. Please upgrade to 1.8.x or better."; 4171 } 4172 if (!vernums.forEach) { 4173 Utils.warn('Parsley requires ES5 to run properly. Please include https://github.com/es-shims/es5-shim'); 4174 } 4175 // Inherit `on`, `off` & `trigger` to Parsley: 4176 var Parsley = _extends(new Base(), { 4177 element: document, 4178 $element: $(document), 4179 actualizeOptions: null, 4180 _resetOptions: null, 4181 Factory: Factory, 4182 version: '2.8.1' 4183 }); 4184 4185 // Supplement Field and Form with Base 4186 // This way, the constructors will have access to those methods 4187 _extends(parsley_field.prototype, UI.Field, Base.prototype); 4188 _extends(Form.prototype, UI.Form, Base.prototype); 4189 // Inherit actualizeOptions and _resetOptions: 4190 _extends(Factory.prototype, Base.prototype); 4191 4192 // ### jQuery API 4193 // `$('.elem').parsley(options)` or `$('.elem').psly(options)` 4194 $.fn.parsley = $.fn.psly = function (options) { 4195 if (this.length > 1) { 4196 var instances = []; 4197 4198 this.each(function () { 4199 instances.push($(this).parsley(options)); 4200 }); 4201 4202 return instances; 4203 } 4204 4205 // Return undefined if applied to non existing DOM element 4206 if (this.length == 0) { 4207 return; 4208 } 4209 4210 return new Factory(this[0], options); 4211 }; 4212 4213 // ### Field and Form extension 4214 // Ensure the extension is now defined if it wasn't previously 4215 if ('undefined' === typeof window.ParsleyExtend) window.ParsleyExtend = {}; 4216 4217 // ### Parsley config 4218 // Inherit from ParsleyDefault, and copy over any existing values 4219 Parsley.options = _extends(Utils.objectCreate(Defaults), window.ParsleyConfig); 4220 window.ParsleyConfig = Parsley.options; // Old way of accessing global options 4221 4222 // ### Globals 4223 window.Parsley = window.psly = Parsley; 4224 Parsley.Utils = Utils; 4225 window.ParsleyUtils = {}; 4226 $.each(Utils, function (key, value) { 4227 if ('function' === typeof value) { 4228 window.ParsleyUtils[key] = function () { 4229 Utils.warnOnce('Accessing `window.ParsleyUtils` is deprecated. Use `window.Parsley.Utils` instead.'); 4230 return Utils[key].apply(Utils, arguments); 4231 }; 4232 } 4233 }); 4234 4235 // ### Define methods that forward to the registry, and deprecate all access except through window.Parsley 4236 var registry = window.Parsley._validatorRegistry = new ValidatorRegistry(window.ParsleyConfig.validators, window.ParsleyConfig.i18n); 4237 window.ParsleyValidator = {}; 4238 $.each('setLocale addCatalog addMessage addMessages getErrorMessage formatMessage addValidator updateValidator removeValidator hasValidator'.split(' '), function (i, method) { 4239 window.Parsley[method] = function () { 4240 return registry[method].apply(registry, arguments); 4241 }; 4242 window.ParsleyValidator[method] = function () { 4243 var _window$Parsley; 4244 4245 Utils.warnOnce('Accessing the method \'' + method + '\' through Validator is deprecated. Simply call \'window.Parsley.' + method + '(...)\''); 4246 return (_window$Parsley = window.Parsley)[method].apply(_window$Parsley, arguments); 4247 }; 4248 }); 4249 4250 // ### UI 4251 // Deprecated global object 4252 window.Parsley.UI = UI; 4253 window.ParsleyUI = { 4254 removeError: function removeError(instance, name, doNotUpdateClass) { 4255 var updateClass = true !== doNotUpdateClass; 4256 Utils.warnOnce('Accessing UI is deprecated. Call \'removeError\' on the instance directly. Please comment in issue 1073 as to your need to call this method.'); 4257 return instance.removeError(name, { updateClass: updateClass }); 4258 }, 4259 getErrorsMessages: function getErrorsMessages(instance) { 4260 Utils.warnOnce('Accessing UI is deprecated. Call \'getErrorsMessages\' on the instance directly.'); 4261 return instance.getErrorsMessages(); 4262 } 4263 }; 4264 $.each('addError updateError'.split(' '), function (i, method) { 4265 window.ParsleyUI[method] = function (instance, name, message, assert, doNotUpdateClass) { 4266 var updateClass = true !== doNotUpdateClass; 4267 Utils.warnOnce('Accessing UI is deprecated. Call \'' + method + '\' on the instance directly. Please comment in issue 1073 as to your need to call this method.'); 4268 return instance[method](name, { message: message, assert: assert, updateClass: updateClass }); 4269 }; 4270 }); 4271 4272 // ### PARSLEY auto-binding 4273 // Prevent it by setting `ParsleyConfig.autoBind` to `false` 4274 if (false !== window.ParsleyConfig.autoBind) { 4275 $(function () { 4276 // Works only on `data-parsley-validate`. 4277 if ($('[data-parsley-validate]').length) $('[data-parsley-validate]').parsley(); 4278 }); 4279 } 4280 4281 var o = $({}); 4282 var deprecated = function deprecated() { 4283 Utils.warnOnce("Parsley's pubsub module is deprecated; use the 'on' and 'off' methods on parsley instances or window.Parsley"); 4284 }; 4285 4286 // Returns an event handler that calls `fn` with the arguments it expects 4287 function adapt(fn, context) { 4288 // Store to allow unbinding 4289 if (!fn.parsleyAdaptedCallback) { 4290 fn.parsleyAdaptedCallback = function () { 4291 var args = Array.prototype.slice.call(arguments, 0); 4292 args.unshift(this); 4293 fn.apply(context || o, args); 4294 }; 4295 } 4296 return fn.parsleyAdaptedCallback; 4297 } 4298 4299 var eventPrefix = 'parsley:'; 4300 // Converts 'parsley:form:validate' into 'form:validate' 4301 function eventName(name) { 4302 if (name.lastIndexOf(eventPrefix, 0) === 0) return name.substr(eventPrefix.length); 4303 return name; 4304 } 4305 4306 // $.listen is deprecated. Use Parsley.on instead. 4307 $.listen = function (name, callback) { 4308 var context; 4309 deprecated(); 4310 if ('object' === typeof arguments[1] && 'function' === typeof arguments[2]) { 4311 context = arguments[1]; 4312 callback = arguments[2]; 4313 } 4314 4315 if ('function' !== typeof callback) throw new Error('Wrong parameters'); 4316 4317 window.Parsley.on(eventName(name), adapt(callback, context)); 4318 }; 4319 4320 $.listenTo = function (instance, name, fn) { 4321 deprecated(); 4322 if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance'); 4323 4324 if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong parameters'); 4325 4326 instance.on(eventName(name), adapt(fn)); 4327 }; 4328 4329 $.unsubscribe = function (name, fn) { 4330 deprecated(); 4331 if ('string' !== typeof name || 'function' !== typeof fn) throw new Error('Wrong arguments'); 4332 window.Parsley.off(eventName(name), fn.parsleyAdaptedCallback); 4333 }; 4334 4335 $.unsubscribeTo = function (instance, name) { 4336 deprecated(); 4337 if (!(instance instanceof parsley_field) && !(instance instanceof Form)) throw new Error('Must give Parsley instance'); 4338 instance.off(eventName(name)); 4339 }; 4340 4341 $.unsubscribeAll = function (name) { 4342 deprecated(); 4343 window.Parsley.off(eventName(name)); 4344 $('form,input,textarea,select').each(function () { 4345 var instance = $(this).data('Parsley'); 4346 if (instance) { 4347 instance.off(eventName(name)); 4348 } 4349 }); 4350 }; 4351 4352 // $.emit is deprecated. Use jQuery events instead. 4353 $.emit = function (name, instance) { 4354 var _instance; 4355 4356 deprecated(); 4357 var instanceGiven = instance instanceof parsley_field || instance instanceof Form; 4358 var args = Array.prototype.slice.call(arguments, instanceGiven ? 2 : 1); 4359 args.unshift(eventName(name)); 4360 if (!instanceGiven) { 4361 instance = window.Parsley; 4362 } 4363 (_instance = instance).trigger.apply(_instance, _toConsumableArray(args)); 4364 }; 4365 4366 var pubsub = {}; 4367 4368 $.extend(true, Parsley, { 4369 asyncValidators: { 4370 'default': { 4371 fn: function fn(xhr) { 4372 // By default, only status 2xx are deemed successful. 4373 // Note: we use status instead of state() because responses with status 200 4374 // but invalid messages (e.g. an empty body for content type set to JSON) will 4375 // result in state() === 'rejected'. 4376 return xhr.status >= 200 && xhr.status < 300; 4377 }, 4378 url: false 4379 }, 4380 reverse: { 4381 fn: function fn(xhr) { 4382 // If reverse option is set, a failing ajax request is considered successful 4383 return xhr.status < 200 || xhr.status >= 300; 4384 }, 4385 url: false 4386 } 4387 }, 4388 4389 addAsyncValidator: function addAsyncValidator(name, fn, url, options) { 4390 Parsley.asyncValidators[name] = { 4391 fn: fn, 4392 url: url || false, 4393 options: options || {} 4394 }; 4395 4396 return this; 4397 } 4398 4399 }); 4400 4401 Parsley.addValidator('remote', { 4402 requirementType: { 4403 '': 'string', 4404 'validator': 'string', 4405 'reverse': 'boolean', 4406 'options': 'object' 4407 }, 4408 4409 validateString: function validateString(value, url, options, instance) { 4410 var data = {}; 4411 var ajaxOptions; 4412 var csr; 4413 var validator = options.validator || (true === options.reverse ? 'reverse' : 'default'); 4414 4415 if ('undefined' === typeof Parsley.asyncValidators[validator]) throw new Error('Calling an undefined async validator: `' + validator + '`'); 4416 4417 url = Parsley.asyncValidators[validator].url || url; 4418 4419 // Fill current value 4420 if (url.indexOf('{value}') > -1) { 4421 url = url.replace('{value}', encodeURIComponent(value)); 4422 } else { 4423 data[instance.element.getAttribute('name') || instance.element.getAttribute('id')] = value; 4424 } 4425 4426 // Merge options passed in from the function with the ones in the attribute 4427 var remoteOptions = $.extend(true, options.options || {}, Parsley.asyncValidators[validator].options); 4428 4429 // All `$.ajax(options)` could be overridden or extended directly from DOM in `data-parsley-remote-options` 4430 ajaxOptions = $.extend(true, {}, { 4431 url: url, 4432 data: data, 4433 type: 'GET' 4434 }, remoteOptions); 4435 4436 // Generate store key based on ajax options 4437 instance.trigger('field:ajaxoptions', instance, ajaxOptions); 4438 4439 csr = $.param(ajaxOptions); 4440 4441 // Initialise querry cache 4442 if ('undefined' === typeof Parsley._remoteCache) Parsley._remoteCache = {}; 4443 4444 // Try to retrieve stored xhr 4445 var xhr = Parsley._remoteCache[csr] = Parsley._remoteCache[csr] || $.ajax(ajaxOptions); 4446 4447 var handleXhr = function handleXhr() { 4448 var result = Parsley.asyncValidators[validator].fn.call(instance, xhr, url, options); 4449 if (!result) // Map falsy results to rejected promise 4450 result = $.Deferred().reject(); 4451 return $.when(result); 4452 }; 4453 4454 return xhr.then(handleXhr, handleXhr); 4455 }, 4456 4457 priority: -1 4458 }); 4459 4460 Parsley.on('form:submit', function () { 4461 Parsley._remoteCache = {}; 4462 }); 4463 4464 Base.prototype.addAsyncValidator = function () { 4465 Utils.warnOnce('Accessing the method `addAsyncValidator` through an instance is deprecated. Simply call `Parsley.addAsyncValidator(...)`'); 4466 return Parsley.addAsyncValidator.apply(Parsley, arguments); 4467 }; 4468 4469 // This is included with the Parsley library itself, 4470 // thus there is no use in adding it to your project. 4471 Parsley.addMessages('en', { 4472 defaultMessage: "This value seems to be invalid.", 4473 type: { 4474 email: "This value should be a valid email.", 4475 url: "This value should be a valid url.", 4476 number: "This value should be a valid number.", 4477 integer: "This value should be a valid integer.", 4478 digits: "This value should be digits.", 4479 alphanum: "This value should be alphanumeric." 4480 }, 4481 notblank: "This value should not be blank.", 4482 required: "This value is required.", 4483 pattern: "This value seems to be invalid.", 4484 min: "This value should be greater than or equal to %s.", 4485 max: "This value should be lower than or equal to %s.", 4486 range: "This value should be between %s and %s.", 4487 minlength: "This value is too short. It should have %s characters or more.", 4488 maxlength: "This value is too long. It should have %s characters or fewer.", 4489 length: "This value length is invalid. It should be between %s and %s characters long.", 4490 mincheck: "You must select at least %s choices.", 4491 maxcheck: "You must select %s choices or fewer.", 4492 check: "You must select between %s and %s choices.", 4493 equalto: "This value should be the same." 4494 }); 4495 4496 Parsley.setLocale('en'); 4497 4498 /** 4499 * inputevent - Alleviate browser bugs for input events 4500 * https://github.com/marcandre/inputevent 4501 * @version v0.0.3 - (built Thu, Apr 14th 2016, 5:58 pm) 4502 * @author Marc-Andre Lafortune <[email protected]> 4503 * @license MIT 4504 */ 4505 4506 function InputEvent() { 4507 var _this14 = this; 4508 4509 var globals = window || global; 4510 4511 // Slightly odd way construct our object. This way methods are force bound. 4512 // Used to test for duplicate library. 4513 _extends(this, { 4514 4515 // For browsers that do not support isTrusted, assumes event is native. 4516 isNativeEvent: function isNativeEvent(evt) { 4517 return evt.originalEvent && evt.originalEvent.isTrusted !== false; 4518 }, 4519 4520 fakeInputEvent: function fakeInputEvent(evt) { 4521 if (_this14.isNativeEvent(evt)) { 4522 $(evt.target).trigger('input'); 4523 } 4524 }, 4525 4526 misbehaves: function misbehaves(evt) { 4527 if (_this14.isNativeEvent(evt)) { 4528 _this14.behavesOk(evt); 4529 $(document).on('change.inputevent', evt.data.selector, _this14.fakeInputEvent); 4530 _this14.fakeInputEvent(evt); 4531 } 4532 }, 4533 4534 behavesOk: function behavesOk(evt) { 4535 if (_this14.isNativeEvent(evt)) { 4536 $(document) // Simply unbinds the testing handler 4537 .off('input.inputevent', evt.data.selector, _this14.behavesOk).off('change.inputevent', evt.data.selector, _this14.misbehaves); 4538 } 4539 }, 4540 4541 // Bind the testing handlers 4542 install: function install() { 4543 if (globals.inputEventPatched) { 4544 return; 4545 } 4546 globals.inputEventPatched = '0.0.3'; 4547 var _arr = ['select', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="file"]']; 4548 for (var _i = 0; _i < _arr.length; _i++) { 4549 var selector = _arr[_i]; 4550 $(document).on('input.inputevent', selector, { selector: selector }, _this14.behavesOk).on('change.inputevent', selector, { selector: selector }, _this14.misbehaves); 4551 } 4552 }, 4553 4554 uninstall: function uninstall() { 4555 delete globals.inputEventPatched; 4556 $(document).off('.inputevent'); 4557 } 4558 4559 }); 4560 }; 4561 4562 var inputevent = new InputEvent(); 4563 4564 inputevent.install(); 4565 4566 var parsley = Parsley; 4567 4568 return parsley; 4569}); 4570//# sourceMappingURL=parsley.js.map 4571 4572/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(2))) 4573 4574/***/ }) 4575/******/ ]);
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.