1/** 2* DO NOT EDIT THIS FILE. 3* See the following change record for more information, 4* https://www.drupal.org/node/2815083 5* @preserve 6**/ 7 8if (!Element.prototype.matches) { 9 Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; 10}; 11/** 12* DO NOT EDIT THIS FILE. 13* See the following change record for more information, 14* https://www.drupal.org/node/2815083 15* @preserve 16**/ 17 18if (typeof Object.assign !== 'function') { 19 Object.defineProperty(Object, 'assign', { 20 value: function assign(target, varArgs) { 21 'use strict'; 22 23 if (target === null || target === undefined) { 24 throw new TypeError('Cannot convert undefined or null to object'); 25 } 26 27 var to = Object(target); 28 29 for (var index = 1; index < arguments.length; index++) { 30 var nextSource = arguments[index]; 31 32 if (nextSource !== null && nextSource !== undefined) { 33 for (var nextKey in nextSource) { 34 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { 35 to[nextKey] = nextSource[nextKey]; 36 } 37 } 38 } 39 } 40 41 return to; 42 }, 43 writable: true, 44 configurable: true 45 }); 46}; 47/*! @drupal/once - v1.0.1 - 2021-06-12 */ 48var once=function(){"use strict";var n=/[\11\12\14\15\40]+/,e="data-once",t=document;function r(n,t,r){return n[t+"Attribute"](e,r)}function o(e){if("string"!=typeof e)throw new TypeError("once ID must be a string");if(""===e||n.test(e))throw new RangeError("once ID must not be empty or contain spaces");return'[data-once~="'+e+'"]'}function u(n){if(!(n instanceof Element))throw new TypeError("The element must be an instance of Element");return!0}function i(n,e){void 0===e&&(e=t);var r=n;if(null===n)r=[];else{if(!n)throw new TypeError("Selector must not be empty");"string"!=typeof n||e!==t&&!u(e)?n instanceof Element&&(r=[n]):r=e.querySelectorAll(n)}return Array.prototype.slice.call(r)}function c(n,e,t){return e.filter((function(e){var r=u(e)&&e.matches(n);return r&&t&&t(e),r}))}function f(e,t){var o=t.add,u=t.remove,i=[];r(e,"has")&&r(e,"get").trim().split(n).forEach((function(n){i.indexOf(n)<0&&n!==u&&i.push(n)})),o&&i.push(o);var c=i.join(" ");r(e,""===c?"remove":"set",c)}function a(n,e,t){return c(":not("+o(n)+")",i(e,t),(function(e){return f(e,{add:n})}))}return a.remove=function(n,e,t){return c(o(n),i(e,t),(function(e){return f(e,{remove:n})}))},a.filter=function(n,e,t){return c(o(n),i(e,t))},a.find=function(n,e){return i(n?o(n):"[data-once]",e)},a}(); 49 50; 51/*! 52 * jQuery Once v2.2.3 - http://github.com/robloach/jquery-once 53 * @license MIT, GPL-2.0 54 * http://opensource.org/licenses/MIT 55 * http://opensource.org/licenses/GPL-2.0 56 */ 57(function(e){"use strict";if(typeof exports==="object"&&typeof exports.nodeName!=="string"){e(require("jquery"))}else if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(t){"use strict";var r=function(e){e=e||"once";if(typeof e!=="string"){throw new TypeError("The jQuery Once id parameter must be a string")}return e};t.fn.once=function(e){var n="jquery-once-"+r(e);return this.filter(function(){return t(this).data(n)!==true}).data(n,true)};t.fn.removeOnce=function(e){return this.findOnce(e).removeData("jquery-once-"+r(e))};t.fn.findOnce=function(e){var n="jquery-once-"+r(e);return this.filter(function(){return t(this).data(n)===true})}}); 58 59/** 60* DO NOT EDIT THIS FILE. 61* See the following change record for more information, 62* https://www.drupal.org/node/2815083 63* @preserve 64**/ 65 66Drupal.debounce = function (func, wait, immediate) { 67 var timeout; 68 var result; 69 return function () { 70 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 71 args[_key] = arguments[_key]; 72 } 73 74 var context = this; 75 76 var later = function later() { 77 timeout = null; 78 79 if (!immediate) { 80 result = func.apply(context, args); 81 } 82 }; 83 84 var callNow = immediate && !timeout; 85 clearTimeout(timeout); 86 timeout = setTimeout(later, wait); 87 88 if (callNow) {
89 result = func.apply(context, args); 90 } 91 92 return result; 93 }; 94};; 95/** 96* DO NOT EDIT THIS FILE. 97* See the following change record for more information, 98* https://www.drupal.org/node/2815083 99* @preserve 100**/ 101 102(function ($, once) { 103 var deprecatedMessageSuffix = "is deprecated in Drupal 9.3.0 and will be removed in Drupal 10.0.0. Use the core/once library instead. See https://www.drupal.org/node/3158256"; 104 var originalJQOnce = $.fn.once; 105 var originalJQRemoveOnce = $.fn.removeOnce; 106 107 $.fn.once = function jQueryOnce(id) { 108 Drupal.deprecationError({ 109 message: "jQuery.once() ".concat(deprecatedMessageSuffix) 110 }); 111 return originalJQOnce.apply(this, [id]); 112 }; 113 114 $.fn.removeOnce = function jQueryRemoveOnce(id) { 115 Drupal.deprecationError({ 116 message: "jQuery.removeOnce() ".concat(deprecatedMessageSuffix) 117 }); 118 return originalJQRemoveOnce.apply(this, [id]); 119 }; 120 121 var drupalOnce = once; 122 123 function augmentedOnce(id, selector, context) { 124 originalJQOnce.apply($(selector, context), [id]); 125 return drupalOnce(id, selector, context); 126 } 127 128 function remove(id, selector, context) { 129 originalJQRemoveOnce.apply($(selector, context), [id]); 130 return drupalOnce.remove(id, selector, context); 131 } 132 133 window.once = Object.assign(augmentedOnce, drupalOnce, { 134 remove: remove 135 }); 136})(jQuery, once);; 137/** 138* DO NOT EDIT THIS FILE. 139* See the following change record for more information, 140* https://www.drupal.org/node/2815083 141* @preserve 142**/ 143 144(function ($, Drupal, debounce) { 145 $.fn.drupalGetSummary = function () { 146 var callback = this.data('summaryCallback'); 147 return this[0] && callback ? callback(this[0]).trim() : ''; 148 }; 149 150 $.fn.drupalSetSummary = function (callback) { 151 var self = this; 152 153 if (typeof callback !== 'function') { 154 var val = callback; 155 156 callback = function callback() { 157 return val; 158 }; 159 } 160 161 return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () { 162 self.trigger('summaryUpdated'); 163 }).trigger('summaryUpdated'); 164 }; 165 166 Drupal.behaviors.formSingleSubmit = { 167 attach: function attach() { 168 function onFormSubmit(e) { 169 var $form = $(e.currentTarget); 170 var formValues = $form.serialize(); 171 var previousValues = $form.attr('data-drupal-form-submit-last'); 172 173 if (previousValues === formValues) { 174 e.preventDefault(); 175 } else { 176 $form.attr('data-drupal-form-submit-last', formValues); 177 } 178 } 179 180 $(once('form-single-submit', 'body')).on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit); 181 } 182 }; 183 184 function triggerFormUpdated(element) { 185 $(element).trigger('formUpdated'); 186 } 187 188 function fieldsList(form) { 189 return [].map.call(form.querySelectorAll('[name][id]'), function (el) { 190 return el.id; 191 }); 192 } 193 194 Drupal.behaviors.formUpdated = { 195 attach: function attach(context) { 196 var $context = $(context); 197 var contextIsForm = $context.is('form'); 198 var $forms = $(once('form-updated', contextIsForm ? $context : $context.find('form'))); 199 var formFields; 200 201 if ($forms.length) { 202 $.makeArray($forms).forEach(function (form) { 203 var events = 'change.formUpdated input.formUpdated '; 204 var eventHandler = debounce(function (event) { 205 triggerFormUpdated(event.target); 206 }, 300); 207 formFields = fieldsList(form).join(','); 208 form.setAttribute('data-drupal-form-fields', formFields); 209 $(form).on(events, eventHandler); 210 }); 211 } 212 213 if (contextIsForm) { 214 formFields = fieldsList(context).join(','); 215 var currentFields = $(context).attr('data-drupal-form-fields'); 216 217 if (formFields !== currentFields) { 218 triggerFormUpdated(context); 219 } 220 } 221 }, 222 detach: function detach(context, settings, trigger) { 223 var $context = $(context); 224 var contextIsForm = $context.is('form'); 225 226 if (trigger === 'unload') { 227 once.remove('form-updated', contextIsForm ? $context : $context.find('form')).forEac
227h(function (form) { 228 form.removeAttribute('data-drupal-form-fields'); 229 $(form).off('.formUpdated'); 230 }); 231 } 232 } 233 }; 234 Drupal.behaviors.fillUserInfoFromBrowser = { 235 attach: function attach(context, settings) { 236 var userInfo = ['name', 'mail', 'homepage']; 237 var $forms = $(once('user-info-from-browser', '[data-user-info-from-browser]')); 238 239 if ($forms.length) { 240 userInfo.forEach(function (info) { 241 var $element = $forms.find("[name=".concat(info, "]")); 242 var browserData = localStorage.getItem("Drupal.visitor.".concat(info)); 243 244 if (!$element.length) { 245 return; 246 } 247 248 var emptyValue = $element[0].value === ''; 249 var defaultValue = $element.attr('data-drupal-default-value') === $element[0].value; 250 251 if (browserData && (emptyValue || defaultValue)) { 252 $element.each(function (index, item) { 253 item.value = browserData; 254 }); 255 } 256 }); 257 } 258 259 $forms.on('submit', function () { 260 userInfo.forEach(function (info) { 261 var $element = $forms.find("[name=".concat(info, "]")); 262 263 if ($element.length) { 264 localStorage.setItem("Drupal.visitor.".concat(info), $element[0].value); 265 } 266 }); 267 }); 268 } 269 }; 270 271 var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) { 272 var url; 273 274 if (e.type === 'click') { 275 url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget; 276 } else { 277 url = window.location; 278 } 279 280 var hash = url.hash.substr(1); 281 282 if (hash) { 283 var $target = $("#".concat(hash)); 284 $('body').trigger('formFragmentLinkClickOrHashChange', [$target]); 285 setTimeout(function () { 286 return $target.trigger('focus'); 287 }, 300); 288 } 289 }; 290 291 var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true); 292 $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange); 293 $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange); 294})(jQuery, Drupal, Drupal.debounce);; 295/** 296 * @file 297 * Webform behaviors. 298 */ 299 300(function ($, Drupal) { 301 302 'use strict'; 303 304 // Trigger Drupal's attaching of behaviors after the page is 305 // completely loaded. 306 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 307 // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422 308 var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase())); 309 if (isChrome) { 310 // Track back button in navigation. 311 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 312 var backButton = false; 313 if (window.performance) { 314 var navEntries = window.performance.getEntriesByType('navigation'); 315 if (navEntries.length > 0 && navEntries[0].type === 'back_forward') { 316 backButton = true; 317 } 318 else if (window.performance.navigation 319 && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) { 320 backButton = true; 321 } 322 } 323 324 // If the back button is pressed, delay Drupal's attaching of behaviors. 325 if (backButton) { 326 var attachBehaviors = Drupal.attachBehaviors; 327 Drupal.attachBehaviors = function (context, settings) { 328 setTimeout(function (context, settings) { 329 attachBehaviors(context, settings); 330 }, 300); 331 }; 332 } 333 } 334 335})(jQuery, Drupal); 336; 337/** 338* DO NOT EDIT THIS FILE. 339* See the following change record for more information, 340* https://www.drupal.org/node/2815083 341* @preserve 342**/ 343 344(function ($, Drupal) { 345 var states = { 346 postponed: [] 347 }; 348 Drupal.states = states; 349 350 function invert(a, invertState) { 351 return invertState && typeof a !== 'undefined' ? !a : a; 352 } 353 354 function _compare2(a, b) { 355 if (a === b) { 356 return typeof a === 'undefined' ? a : true; 357 } 358 359 return typeof a === 'undefined' || typeof b === 'undefined'; 360 } 361 362 function ternary(a, b) { 363 if (typeof a === 'undefined') { 364 return b; 365 } 366 367 if (typeof b === 'undefined') { 368 return a; 369 } 370 371 return a && b; 372 } 373 374 Drupal.behaviors.states = { 375 attach: function attach(context, settings) { 376 var $states = $(context).find('[data-drupal-states]'); 377 var il = $states.length; 378 379 var _loop = function _loop(i) { 380 var config = JSON.parse($states[i].getAttribute('data-drupal-states')); 381 Object.keys(config || {}
381).forEach(function (state) { 382 new states.Dependent({ 383 element: $($states[i]), 384 state: states.State.sanitize(state), 385 constraints: config[state] 386 }); 387 }); 388 }; 389 390 for (var i = 0; i < il; i++) { 391 _loop(i); 392 } 393 394 while (states.postponed.length) { 395 states.postponed.shift()(); 396 } 397 } 398 }; 399 400 states.Dependent = function (args) { 401 var _this = this; 402 403 $.extend(this, { 404 values: {}, 405 oldValue: null 406 }, args); 407 this.dependees = this.getDependees(); 408 Object.keys(this.dependees || {}).forEach(function (selector) { 409 _this.initializeDependee(selector, _this.dependees[selector]); 410 }); 411 }; 412 413 states.Dependent.comparisons = { 414 RegExp: function RegExp(reference, value) { 415 return reference.test(value); 416 }, 417 Function: function Function(reference, value) { 418 return reference(value); 419 }, 420 Number: function Number(reference, value) { 421 return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); 422 } 423 }; 424 states.Dependent.prototype = { 425 initializeDependee: function initializeDependee(selector, dependeeStates) { 426 var _this2 = this; 427 428 this.values[selector] = {}; 429 Object.keys(dependeeStates).forEach(function (i) { 430 var state = dependeeStates[i]; 431 432 if ($.inArray(state, dependeeStates) === -1) { 433 return; 434 } 435 436 state = states.State.sanitize(state); 437 _this2.values[selector][state.name] = null; 438 $(selector).on("state:".concat(state), { 439 selector: selector, 440 state: state 441 }, function (e) { 442 _this2.update(e.data.selector, e.data.state, e.value); 443 }); 444 new states.Trigger({ 445 selector: selector, 446 state: state 447 }); 448 }); 449 }, 450 compare: function compare(reference, selector, state) { 451 var value = this.values[selector][state.name]; 452 453 if (reference.constructor.name in states.Dependent.comparisons) { 454 return states.Dependent.comparisons[reference.constructor.name](reference, value); 455 } 456 457 return _compare2(reference, value); 458 }, 459 update: function update(selector, state, value) { 460 if (value !== this.values[selector][state.name]) { 461 this.values[selector][state.name] = value; 462 this.reevaluate(); 463 } 464 }, 465 reevaluate: function reevaluate() { 466 var value = this.verifyConstraints(this.constraints); 467 468 if (value !== this.oldValue) { 469 this.oldValue = value; 470 value = invert(value, this.state.invert); 471 this.element.trigger({ 472 type: "state:".concat(this.state), 473 value: value, 474 trigger: true 475 }); 476 } 477 }, 478 verifyConstraints: function verifyConstraints(constraints, selector) { 479 var result; 480 481 if ($.isArray(constraints)) { 482 var hasXor = $.inArray('xor', constraints) === -1; 483 var len = constraints.length; 484 485 for (var i = 0; i < len; i++) { 486 if (constraints[i] !== 'xor') { 487 var constraint = this.checkConstraints(constraints[i], selector, i); 488 489 if (constraint && (hasXor || result)) { 490 return hasXor; 491 } 492 493 result = result || constraint; 494 } 495 } 496 } else if ($.isPlainObject(constraints)) { 497 for (var n in constraints) { 498 if (constraints.hasOwnProperty(n)) { 499 result = ternary(result, this.checkConstraints(constraints[n], selector, n)); 500 501 if (result === false) { 502 return false; 503 } 504 } 505 } 506 } 507 508 return result; 509 }, 510 checkConstraints: function checkConstraints(value, selector, state) { 511 if (typeof state !== 'string' || /[0-9]/.test(state[0])) { 512 state = null; 513 } else if (typeof selector === 'undefined') { 514 selector = state; 515 state = null; 516 } 517 518 if (state !== null) { 519 state = states.State.sanitize(state); 520 return invert(this.compare(value, selector, state), state.invert); 521 } 522 523 return this.verifyConstraints(value, selector); 524 }, 525 getDependees: function getDependees() { 526 var cache = {}; 527 var _compare = this.compare; 528 529 this.compare = function (reference, selector, state) { 530 (cache[selector] || (cache[selector] = [])).push(state.name); 531 }; 532 533 this.verifyConstraints(this.constraints); 534 this.compare = _compare; 535 return cache; 536 } 537 }; 538 539 states.Trigger = function (args) { 540 $.extend(this, args); 541 542 if (this.state in states.Trigger.states) { 543 this.element = $(this.selector); 544 545 if (!this.element.data("trigger:".concat(this.state))) { 546 this.initialize(); 547 } 548 } 549 }; 550 551 states.Trigger.prototype = { 552 initialize: function initialize() { 553 var _this3 = this; 554 555 var trigger = states.Trigger.states[this.state]; 556 557 if (typeof trigger === 'function') { 558 trigger.call(window, this.element); 559 } else { 560 Object.keys(trigger || {}
560).forEach(function (event) { 561 _this3.defaultTrigger(event, trigger[event]); 562 }); 563 } 564 565 this.element.data("trigger:".concat(this.state), true); 566 }, 567 defaultTrigger: function defaultTrigger(event, valueFn) { 568 var oldValue = valueFn.call(this.element); 569 this.element.on(event, $.proxy(function (e) { 570 var value = valueFn.call(this.element, e); 571 572 if (oldValue !== value) { 573 this.element.trigger({ 574 type: "state:".concat(this.state), 575 value: value, 576 oldValue: oldValue 577 }); 578 oldValue = value; 579 } 580 }, this)); 581 states.postponed.push($.proxy(function () { 582 this.element.trigger({ 583 type: "state:".concat(this.state), 584 value: oldValue, 585 oldValue: null 586 }); 587 }, this)); 588 } 589 }; 590 states.Trigger.states = { 591 empty: { 592 keyup: function keyup() { 593 return this.val() === ''; 594 } 595 }, 596 checked: { 597 change: function change() { 598 var checked = false; 599 this.each(function () { 600 checked = $(this).prop('checked'); 601 return !checked; 602 }); 603 return checked; 604 } 605 }, 606 value: { 607 keyup: function keyup() { 608 if (this.length > 1) { 609 return this.filter(':checked').val() || false; 610 } 611 612 return this.val(); 613 }, 614 change: function change() { 615 if (this.length > 1) { 616 return this.filter(':checked').val() || false; 617 } 618 619 return this.val(); 620 } 621 }, 622 collapsed: { 623 collapsed: function collapsed(e) { 624 return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); 625 } 626 } 627 }; 628 629 states.State = function (state) { 630 this.pristine = state; 631 this.name = state; 632 var process = true; 633 634 do { 635 while (this.name.charAt(0) === '!') { 636 this.name = this.name.substring(1); 637 this.invert = !this.invert; 638 } 639 640 if (this.name in states.State.aliases) { 641 this.name = states.State.aliases[this.name]; 642 } else { 643 process = false; 644 } 645 } while (process); 646 }; 647 648 states.State.sanitize = function (state) { 649 if (state instanceof states.State) { 650 return state; 651 } 652 653 return new states.State(state); 654 }; 655 656 states.State.aliases = { 657 enabled: '!disabled', 658 invisible: '!visible', 659 invalid: '!valid', 660 untouched: '!touched', 661 optional: '!required', 662 filled: '!empty', 663 unchecked: '!checked', 664 irrelevant: '!relevant', 665 expanded: '!collapsed', 666 open: '!collapsed', 667 closed: 'collapsed', 668 readwrite: '!readonly' 669 }; 670 states.State.prototype = { 671 invert: false, 672 toString: function toString() { 673 return this.name; 674 } 675 }; 676 var $document = $(document); 677 $document.on('state:disabled', function (e) { 678 if (e.trigger) { 679 $(e.target).prop('disabled', e.value).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value); 680 } 681 }); 682 $document.on('state:required', function (e) { 683 if (e.trigger) { 684 if (e.value) { 685 var label = "label".concat(e.target.id ? "[for=".concat(e.target.id, "]") : ''); 686 var $label = $(e.target).attr({ 687 required: 'required', 688 'aria-required': 'true' 689 }).closest('.js-form-item, .js-form-wrapper').find(label); 690 691 if (!$label.hasClass('js-form-required').length) { 692 $label.addClass('js-form-required form-required'); 693 } 694 } else { 695 $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); 696 } 697 } 698 }); 699 $document.on('state:visible', function (e) { 700 if (e.trigger) { 701 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); 702 } 703 }); 704 $document.on('state:checked', function (e) { 705 if (e.trigger) { 706 $(e.target).prop('checked', e.value); 707 } 708 }); 709 $document.on('state:collapsed', function (e) { 710 if (e.trigger) { 711 if ($(e.target).is('[open]') === e.value) { 712 $(e.target).find('> summary').trigger('click'); 713 } 714 } 715 }); 716})(jQuery, Drupal);; 717/** 718 * @file 719 * JavaScript behaviors for custom webform #states. 720 */ 721 722(function ($, Drupal) { 723 724 'use strict'; 725 726 Drupal.webform = Drupal.webform || {}; 727 Drupal.webform.states = Drupal.webform.states || {}; 728 Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {}; 729 Drupal.webform.states.slideDown.duration = 'slow'; 730 Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {}; 731 Drupal.webform.states.slideUp.duration = 'fast'; 732 733 /* ************************************************************************ */ 734 // jQuery functions. 735 /* ************************************************************************ */ 736 737 /** 738 * Check if an element has a specified data attribute. 739 * 740 * @param {string} data 741 * The data attribute name. 742 * 743 * @return {boolean} 744 * TRUE if an element has a specified data attribute. 745 */ 746 $.fn.hasData = function (data) { 747 return (typeof this.data(data) !== 'undefined'); 748 }; 749 750 /**
751 * Check if element is within the webform or not. 752 * 753 * @return {boolean} 754 * TRUE if element is within the webform. 755 */ 756 $.fn.isWebform = function () { 757 return $(this).closest('form.webform-submission-form, form[id^="webform"], form[data-is-webform]').length ? true : false; 758 }; 759 760 /** 761 * Check if element is to be treated as a webform element. 762 * 763 * @return {boolean} 764 * TRUE if element is to be treated as a webform element. 765 */ 766 $.fn.isWebformElement = function () { 767 return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false; 768 }; 769 770 /* ************************************************************************ */ 771 // Trigger. 772 /* ************************************************************************ */ 773 774 // The change event is triggered by cut-n-paste and select menus. 775 // Issue #2445271: #states element empty check not triggered on mouse 776 // based paste. 777 // @see https://www.drupal.org/node/2445271 778 Drupal.states.Trigger.states.empty.change = function change() { 779 return this.val() === ''; 780 }; 781 782 /* ************************************************************************ */ 783 // Dependents. 784 /* ************************************************************************ */ 785 786 // Apply solution included in #1962800 patch. 787 // Issue #1962800: Form #states not working with literal integers as 788 // values in IE11. 789 // @see https://www.drupal.org/project/drupal/issues/1962800 790 // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch 791 // 792 // This issue causes pattern, less than, and greater than support to break. 793 // @see https://www.drupal.org/project/webform/issues/2981724 794 var states = Drupal.states; 795 Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) { 796 var value = this.values[selector][state.name]; 797 798 var name = reference.constructor.name; 799 if (!name) { 800 name = $.type(reference); 801 802 name = name.charAt(0).toUpperCase() + name.slice(1); 803 } 804 if (name in states.Dependent.comparisons) { 805 return states.Dependent.comparisons[name](reference, value); 806 } 807 808 if (reference.constructor.name in states.Dependent.comparisons) { 809 return states.Dependent.comparisons[reference.constructor.name](reference, value); 810 } 811 812 return _compare2(reference, value); 813 }; 814 function _compare2(a, b) { 815 if (a === b) { 816 return typeof a === 'undefined' ? a : true; 817 } 818 819 return typeof a === 'undefined' || typeof b === 'undefined'; 820 } 821 822 // Adds pattern, less than, and greater than support to #state API. 823 // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions 824 Drupal.states.Dependent.comparisons.Object = function (reference, value) { 825 if ('pattern' in reference) { 826 return (new RegExp(reference['pattern'])).test(value); 827 } 828 else if ('!pattern' in reference) { 829 return !((new RegExp(reference['!pattern'])).test(value)); 830 } 831 else if ('less' in reference) { 832 return (value !== '' && parseFloat(reference['less']) > parseFloat(value)); 833 } 834 else if ('less_equal' in reference) { 835 return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value)); 836 } 837 else if ('greater' in reference) { 838 return (value !== '' && parseFloat(reference['greater']) < parseFloat(value)); 839 } 840 else if ('greater_equal' in reference) { 841 return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value)); 842 } 843 else if ('between' in reference || '!between' in reference) { 844 if (value === '') { 845 return false; 846 } 847 848 var between = reference['between'] || reference['!between']; 849 var betweenParts = between.split(':'); 850 var greater = betweenParts[0]; 851 var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null; 852 var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater)); 853 var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less)); 854 var result = (isGreaterThan && isLessThan); 855 return (reference['!between']) ? !result : result; 856 } 857 else { 858 return reference.indexOf(value) !== false; 859 } 860 }; 861 862 /* ************************************************************************ */ 863 // States events. 864 /* ************************************************************************ */ 865 866 var $document = $(document); 867 868 $document.on('state:required', function (e) { 869 if (e.trigger && $(e.target).isWebformElement()) { 870 var $target = $(e.target); 871 // Fix #required file upload. 872 // @see Issue #2860529: Conditional required File upload field don't work. 873 toggleRequired($target.find('input[type="file"]'), e.value); 874 875 // Fix #required for radios and likert. 876 // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted. 877 if ($target.is('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .webform-likert-table')) { 878 $target.toggleClass('required', e.value); 879 toggleRequired($target.find('input[type="radio"]'), e.value); 880 } 881 882 // Fix #required for checkboxes. 883 // @see Issue #2938414: Checkboxes don't support #states required. 884 // @see checkboxRequiredhandler 885 if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) { 886 $target.toggleClass('required', e.value); 887 var $checkboxes = $target.find('input[type="checkbox"]'); 888 if (e.value) { 889 // Add event handler. 890 $checkboxes.on('click', statesCheckboxesRequiredEventHandler); 891 // Initialize and add required attribute. 892 checkboxesRequired($target); 893 } 894 else { 895 // Remove event handler. 896 $checkboxes.off('click', statesCheckboxesRequiredEventHandler); 897 // Remove required attribute. 898 toggleRequired($checkboxes, false); 899 } 900 } 901 902 // Fix #required for tableselect. 903 // @see Issue #3212581: Table select does not trigger client side validation 904 if ($target.is('.js-webform-tableselect')) { 905 $target.toggleClass('required', e.value); 906 var isMultiple = $target.is('[multiple]'); 907 if (isMultiple) { 908 // Checkboxes. 909 var $tbody = $target.find('tbody'); 910 var $checkboxes = $tbody.find('input[type="checkbox"]'); 911 copyRequireMessage($target, $checkboxes); 912 if (e.value) { 913 $checkboxes.on('click change', statesCheckboxesRequiredEventHandler); 914 checkboxesRequired($tbody); 915 } 916 else { 917 $checkboxes.off('click change ', statesCheckboxesRequiredEventHandler); 918 toggleRequired($tbody, false); 919 } 920 } 921 else { 922 // Radios. 923 var $radios = $target.find('input[type="radio"]'); 924 copyRequireMessage($target, $radios); 925 toggleRequired($radios, e.value); 926 } 927 } 928 929 // Fix required label for elements without the for attribute. 930 // @see Issue #3145300: Conditional Visible Select Other not working. 931 if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) { 932 var $select = $target.find('select'); 933 toggleRequired($select, e.value); 934 copyRequireMessage($target, $select); 935 } 936 if ($target.find('> label:not([for])').length) { 937 $target.find('> label').toggleClass('js-form-required form-required', e.value); 938 } 939 940 // Fix required label for checkboxes and radios. 941 // @see Issue #2938414: Checkboxes don't support #states required 942 // @see Issue #2731991: Setting required on radios marks all options required. 943 // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset. 944 // Fix #required for fieldsets. 945 // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required. 946 if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) { 947 $target.find('legend span.fieldset-legend:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value); 948 } 949 950 // Issue #2986017: Fieldsets shouldn't have required attribute. 951 if ($target.is('fieldset')) { 952 $target.removeAttr('required aria-required'); 953 } 954 } 955 }); 956 957 $document.on('state:checked', function (e) { 958 if (e.trigger) { 959 $(e.target).trigger('change'); 960 } 961 }); 962 963 $document.on('state:readonly', function (e) { 964 if (e.trigger && $(e.target).isWebformElement()) { 965 $(e.target).prop('readonly', e.value).closest('.js-form-item, .js-form-wrapper').toggleClass('webform-readonly', e.value).find('input, textarea').prop('readonly', e.value); 966 967 // Trigger webform:readonly. 968 $(e.target).trigger('webform:readonly') 969 .find('select, input, textarea, button').trigger('webform:readonly'); 970 } 971 }); 972 973 $document.on('state:visible state:visible-slide', function (e) { 974 if (e.trigger && $(e.target).isWebformElement()) { 975 if (e.value) { 976 $(':input', e.target).addBack().each(function () { 977 restoreValueAndRequired(this); 978 triggerEventHandlers(this); 979 }); 980 } 981 else { 982 // @see https://www.sitepoint.com/jquery-function-clear-form-data/ 983 $(':input', e.target).addBack().each(function () { 984 backupValueAndRequired(this); 985 clearValueAndRequired(this); 986 triggerEventHandlers(this); 987 }); 988 } 989 } 990 }); 991 992 $document.on('state:visible-slide', function (e) { 993 if (e.trigger && $(e.target).isWebformElement()) { 994 var effect = e.value ? 'slideDown' : 'slideUp'; 995 var duration = Drupal.webform.states[effect].duration; 996 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration); 997 } 998 }); 999 Drupal.states.State.aliases['invisible-slide'] = '!visible-slide'; 1000 1001 $document.on('state:disabled', function (e) { 1002 if (e.trigger && $(e.target).isWebformElement()) { 1003 // Make sure disabled property is set before triggering webform:disabled. 1004 // Copied from: core/misc/states.js 1005 $(e.target) 1006 .prop('disabled', e.value) 1007 .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value) 1008 .find('select, input, textarea, button').prop('disabled', e.value); 1009 1010 // Never disable hidden file[fids] because the existing values will 1011 // be completely lost when the webform is submitted. 1012 var fileElements = $(e.target) 1013 .find(':input[type="hidden"][name$="[fids]"]'); 1014 if (fileElements.length) { 1015 // Remove 'disabled' attribute from fieldset which will block 1016 // all disabled elements from being submitted. 1017 if ($(e.target).is('fieldset')) { 1018 $(e.target).prop('disabled', false); 1019 } 1020 fileElements.removeAttr('disabled'); 1021 } 1022 1023 // Trigger webform:disabled. 1024 $(e.target).trigger('webform:disabled') 1025 .find('select, input, textarea, button').trigger('webform:disabled'); 1026 } 1027 }); 1028 1029 /* ************************************************************************ */ 1030 // Behaviors. 1031 /* ************************************************************************ */ 1032 1033 /** 1034 * Adds HTML5 validation to required checkboxes. 1035 * 1036 * @type {Drupal~behavior} 1037 * 1038 * @see https://www.drupal.org/project/webform/issues/3068998 1039 */ 1040 Drupal.behaviors.webformCheckboxesRequired = { 1041 attach: function (context) { 1042 $('.js-form-type-checkboxes.required, .js-form-type-webform-checkboxes-other.required, .js-webform-type-checkboxes.required, .js-webform-type-webform-checkboxes-other.required, .js-webform-type-webform-radios-other.checkboxes', context) 1043 .once('webform-checkboxes-required') 1044 .each(function () { 1045 var $element = $(this); 1046 $element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler); 1047 setTimeout(function () {checkboxesRequired($element);}); 1048 }); 1049 } 1050 }; 1051 1052 /** 1053 * Adds HTML5 validation to required radios. 1054 * 1055 * @type {Drupal~behavior} 1056 * 1057 * @see https://www.drupal.org/project/webform/issues/2856795 1058 */ 1059 Drupal.behaviors.webformRadiosRequired = { 1060 attach: function (context) { 1061 $('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .js-webform-type-webform-scale', context) 1062 .once('webform-radios-required') 1063 .each(function () { 1064 var $element = $(this); 1065 setTimeout(function () {radiosRequired($element);}); 1066 }); 1067 } 1068 }; 1069 1070 /** 1071 * Adds HTML5 validation to required table select. 1072 * 1073 * @type {Drupal~behavior} 1074 * 1075 * @see https://www.drupal.org/project/webform/issues/2856795 1076 */ 1077 Drupal.behaviors.webformTableSelectRequired = { 1078 attach: function (context) { 1079 $('.js-webform-tableselect.required', context) 1080 .once('webform-tableselect-required') 1081 .each(function () { 1082 var $element = $(this); 1083 var $tbody = $element.find('tbody'); 1084 var isMultiple = $element.is('[multiple]'); 1085 1086 if (isMultiple) { 1087 // Check all checkbox triggers checkbox 'change' event on 1088 // select and deselect all. 1089 // @see Drupal.tableSelect 1090 $tbody.find('input[type="checkbox"]').on('click change', function () { 1091 checkboxesRequired($tbody); 1092 }); 1093 } 1094 1095 setTimeout(function () { 1096 isMultiple ? checkboxesRequired($tbody) : radiosRequired($element); 1097 }); 1098 }); 1099 } 1100 }; 1101 1102 /** 1103 * Add HTML5 multiple checkboxes required validation. 1104 * 1105 * @param {jQuery} $element
1106 * An jQuery object containing HTML5 radios. 1107 * 1108 * @see https://stackoverflow.com/a/37825072/145846 1109 */ 1110 function checkboxesRequired($element) { 1111 var $firstCheckbox = $element.find('input[type="checkbox"]').first(); 1112 var isChecked = $element.find('input[type="checkbox"]').is(':checked'); 1113 toggleRequired($firstCheckbox, !isChecked); 1114 copyRequireMessage($element, $firstCheckbox); 1115 } 1116 1117 /** 1118 * Add HTML5 radios required validation. 1119 * 1120 * @param {jQuery} $element 1121 * An jQuery object containing HTML5 radios. 1122 * 1123 * @see https://www.drupal.org/project/webform/issues/2856795 1124 */ 1125 function radiosRequired($element) { 1126 var $radios = $element.find('input[type="radio"]'); 1127 var isRequired = $element.hasClass('required'); 1128 toggleRequired($radios, isRequired); 1129 copyRequireMessage($element, $radios); 1130 } 1131 1132 /* ************************************************************************ */ 1133 // Event handlers. 1134 /* ************************************************************************ */ 1135 1136 /** 1137 * Trigger #states API HTML5 multiple checkboxes required validation. 1138 * 1139 * @see https://stackoverflow.com/a/37825072/145846 1140 */ 1141 function statesCheckboxesRequiredEventHandler() { 1142 var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other'); 1143 checkboxesRequired($element); 1144 } 1145 1146 /** 1147 * Trigger an input's event handlers. 1148 * 1149 * @param {element} input 1150 * An input. 1151 */ 1152 function triggerEventHandlers(input) { 1153 var $input = $(input); 1154 var type = input.type; 1155 var tag = input.tagName.toLowerCase(); 1156 // Add 'webform.states' as extra parameter to event handlers. 1157 // @see Drupal.behaviors.webformUnsaved 1158 var extraParameters = ['webform.states']; 1159 if (type === 'checkbox' || type === 'radio') { 1160 $input 1161 .trigger('change', extraParameters) 1162 .trigger('blur', extraParameters); 1163 } 1164 else if (tag === 'select') { 1165 // Do not trigger the onchange event for Address element's country code 1166 // when it is initialized. 1167 // @see \Drupal\address\Element\Country 1168 if ($input.closest('.webform-type-address').length) { 1169 if (!$input.data('webform-states-address-initialized') 1170 && $input.attr('autocomplete') === 'country' 1171 && $input.val() === $input.find("option[selected]").attr('value')) { 1172 return; 1173 } 1174 $input.data('webform-states-address-initialized', true); 1175 } 1176 1177 $input 1178 .trigger('change', extraParameters) 1179 .trigger('blur', extraParameters); 1180 } 1181 else if (type !== 'submit' && type !== 'button' && type !== 'file') { 1182 // Make sure input mask is removed and then reset when value is restored. 1183 // @see https://www.drupal.org/project/webform/issues/3124155 1184 // @see https://www.drupal.org/project/webform/issues/3202795 1185 var hasInputMask = ($.fn.inputmask && $input.hasClass('js-webform-input-mask')); 1186 hasInputMask && $input.inputmask('remove'); 1187 1188 $input 1189 .trigger('input', extraParameters) 1190 .trigger('change', extraParameters) 1191 .trigger('keydown', extraParameters) 1192 .trigger('keyup', extraParameters) 1193 .trigger('blur', extraParameters); 1194 1195 hasInputMask && $input.inputmask(); 1196 } 1197 } 1198 1199 /* ************************************************************************ */ 1200 // Backup and restore value functions. 1201 /* ************************************************************************ */ 1202 1203 /** 1204 * Backup an input's current value and required attribute 1205 * 1206 * @param {element} input 1207 * An input. 1208 */ 1209 function backupValueAndRequired(input) { 1210 var $input = $(input); 1211 var type = input.type; 1212 var tag = input.tagName.toLowerCase(); // Normalize case. 1213 1214 // Backup required. 1215 if ($input.prop('required') && !$input.hasData('webform-required')) { 1216 $input.data('webform-required', true); 1217 } 1218 1219 // Backup value. 1220 if (!$input.hasData('webform-value')) { 1221 if (type === 'checkbox' || type === 'radio') { 1222 $input.data('webform-value', $input.prop('checked')); 1223 } 1224 else if (tag === 'select') { 1225 var values = []; 1226 $input.find('option:selected').each(function (i, option) { 1227 values[i] = option.value; 1228 }); 1229 $input.data('webform-value', values); 1230 } 1231 else if (type !== 'submit' && type !== 'button') { 1232 $input.data('webform-value', input.value); 1233 } 1234 } 1235 } 1236 1237 /** 1238 * Restore an input's value and required attribute. 1239 * 1240 * @param {element} input 1241 * An input. 1242 */ 1243 function restoreValueAndRequired(input) { 1244 var $input = $(input); 1245 1246 // Restore value. 1247 var value = $input.data('webform-value'); 1248 if (typeof value !== 'undefined') { 1249 var type = input.type; 1250 var tag = input.tagName.toLowerCase(); // Normalize case. 1251 1252 if (type === 'checkbox' || type === 'radio') { 1253 $input.prop('checked', value); 1254 } 1255 else if (tag === 'select') { 1256 $.each(value, function (i, option_value) { 1257 // Prevent "Syntax error, unrecognized expression" error by 1258 // escaping single quotes. 1259 // @see https://forum.jquery.com/topic/escape-characters-prior-to-using-selector 1260 option_value = option_value.replace(/'/g, "\\\'"); 1261 $input.find("option[value='" + option_value + "']").prop('selected', true); 1262 }); 1263 } 1264 else if (type !== 'submit' && type !== 'button') { 1265 input.value = value; 1266 } 1267 $input.removeData('webform-value'); 1268 } 1269 1270 // Restore required. 1271 var required = $input.data('webform-required'); 1272 if (typeof required !== 'undefined') { 1273 if (required) { 1274 $input.prop('required', true); 1275 } 1276 $input.removeData('webform-required'); 1277 } 1278 } 1279 1280 /** 1281 * Clear an input's value and required attributes. 1282 * 1283 * @param {element} input 1284 * An input. 1285 */ 1286 function clearValueAndRequired(input) { 1287 var $input = $(input); 1288 1289 // Check for #states no clear attribute.
1290 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 1291 if ($input.closest('[data-webform-states-no-clear]').length) { 1292 return; 1293 } 1294 1295 // Clear value. 1296 var type = input.type; 1297 var tag = input.tagName.toLowerCase(); // Normalize case. 1298 if (type === 'checkbox' || type === 'radio') { 1299 $input.prop('checked', false); 1300 } 1301 else if (tag === 'select') { 1302 if ($input.find('option[value=""]').length) { 1303 $input.val(''); 1304 } 1305 else { 1306 input.selectedIndex = -1; 1307 } 1308 } 1309 else if (type !== 'submit' && type !== 'button') { 1310 input.value = (type === 'color') ? '#000000' : ''; 1311 } 1312 1313 // Clear required. 1314 $input.prop('required', false); 1315 } 1316 1317 /* ************************************************************************ */ 1318 // Helper functions. 1319 /* ************************************************************************ */ 1320 1321 /** 1322 * Toggle an input's required attributes. 1323 * 1324 * @param {element} $input 1325 * An input. 1326 * @param {boolean} required 1327 * Is input required. 1328 */ 1329 function toggleRequired($input, required) { 1330 var isCheckboxOrRadio = ($input.attr('type') === 'radio' || $input.attr('type') === 'checkbox'); 1331 if (required) { 1332 if (isCheckboxOrRadio) { 1333 $input.attr({'required': 'required'}); 1334 } 1335 else { 1336 $input.attr({'required': 'required', 'aria-required': 'true'}); 1337 } 1338 } 1339 else { 1340 if (isCheckboxOrRadio) { 1341 $input.removeAttr('required'); 1342 } 1343 else { 1344 $input.removeAttr('required aria-required'); 1345 } 1346 } 1347 } 1348 1349 /** 1350 * Copy the clientside_validation.module's message. 1351 * 1352 * @param {jQuery} $source 1353 * The source element. 1354 * @param {jQuery} $destination 1355 * The destination element. 1356 */ 1357 function copyRequireMessage($source, $destination) { 1358 if ($source.attr('data-msg-required')) { 1359 $destination.attr('data-msg-required', $source.attr('data-msg-required')); 1360 } 1361 } 1362 1363})(jQuery, Drupal); 1364; 1365/** 1366 * @file 1367 * JavaScript behaviors for webforms. 1368 */ 1369 1370(function ($, Drupal) { 1371 1372 'use strict'; 1373 1374 /** 1375 * Remove single submit event listener. 1376 * 1377 * @type {Drupal~behavior} 1378 * 1379 * @prop {Drupal~behaviorAttach} attach 1380 * Attaches the behavior for removing single submit event listener. 1381 * 1382 * @see Drupal.behaviors.formSingleSubmit 1383 */ 1384 Drupal.behaviors.webformRemoveFormSingleSubmit = { 1385 attach: function attach() { 1386 function onFormSubmit(e) { 1387 var $form = $(e.currentTarget); 1388 $form.removeAttr('data-drupal-form-submit-last'); 1389 } 1390 $('body') 1391 .once('webform-single-submit') 1392 .on('submit.singleSubmit', 'form.webform-remove-single-submit', onFormSubmit); 1393 } 1394 }; 1395 1396 /** 1397 * Prevent webform autosubmit on wizard pages. 1398 * 1399 * @type {Drupal~behavior} 1400 * 1401 * @prop {Drupal~behaviorAttach} attach 1402 * Attaches the behavior for disabling webform autosubmit. 1403 * Wizard pages need to be progressed with the Previous or Next buttons, 1404 * not by pressing Enter. 1405 */ 1406 Drupal.behaviors.webformDisableAutoSubmit = { 1407 attach: function (context) { 1408 // Not using context so that inputs loaded via Ajax will have autosubmit 1409 // disabled. 1410 // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter 1411 $('.js-webform-disable-autosubmit input') 1412 .not(':button, :submit, :reset, :image, :file') 1413 .once('webform-disable-autosubmit') 1414 .on('keyup keypress', function (e) { 1415 if (e.which === 13) { 1416 e.preventDefault(); 1417 return false; 1418 } 1419 }); 1420 } 1421 }; 1422 1423 /** 1424 * Custom required and pattern validation error messages. 1425 * 1426 * @type {Drupal~behavior} 1427 * 1428 * @prop {Drupal~behaviorAttach} attach 1429 * Attaches the behavior for the webform custom required and pattern 1430 * validation error messages. 1431 * 1432 * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message 1433 **/ 1434 Drupal.behaviors.webformRequiredError = { 1435 attach: function (context) { 1436 $(context).find(':input[data-webform-required-error], :input[data-webform-pattern-error]').once('webform-required-error') 1437 .on('invalid', function () { 1438 this.setCustomValidity(''); 1439 if (this.valid) { 1440 return; 1441 } 1442 1443 if (this.validity.patternMismatch && $(this).attr('data-webform-pattern-error')) { 1444 this.setCustomValidity($(this).attr('data-webform-pattern-error')); 1445 } 1446 else if (this.validity.valueMissing && $(this).attr('data-webform-required-error')) { 1447 this.setCustomValidity($(this).attr('data-webform-required-error')); 1448 } 1449 }) 1450 .on('input change', function () { 1451 // Find all related elements by name and reset custom validity. 1452 // This specifically applies to required radios and checkboxes. 1453 var name = $(this).attr('name'); 1454 $(this.form).find(':input[name="' + name + '"]').each(function () { 1455 this.setCustomValidity(''); 1456 }); 1457 }); 1458 } 1459 }; 1460 1461 // When #state:required is triggered we need to reset the target elements 1462 // custom validity. 1463 $(document).on('state:required', function (e) { 1464 $(e.target).filter('[data-webform-required-error]') 1465 .each(function () {this.setCustomValidity('');}); 1466 }); 1467 1468})(jQuery, Drupal); 1469; 1470/** 1471 * @file 1472 * JavaScript behaviors for details element. 1473 */ 1474 1475(function ($, Drupal) { 1476 1477 'use strict'; 1478 1479 // Determine if local storage exists and is enabled. 1480 // This approach is copied from Modernizr. 1481 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 1482 var hasLocalStorage = (function () { 1483 try { 1484 localStorage.setItem('webform', 'webform'); 1485 localStorage.removeItem('webform'); 1486 return true; 1487 } 1488 catch (e) { 1489 return false;
1490 } 1491 }()); 1492 1493 /** 1494 * Attach handler to save details open/close state. 1495 * 1496 * @type {Drupal~behavior} 1497 */ 1498 Drupal.behaviors.webformDetailsSave = { 1499 attach: function (context) { 1500 if (!hasLocalStorage) { 1501 return; 1502 } 1503 1504 // Summary click event handler. 1505 $('details > summary', context).once('webform-details-summary-save').on('click', function () { 1506 var $details = $(this).parent(); 1507 1508 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 1509 if ($details[0].hasAttribute('data-webform-details-nosave')) { 1510 return; 1511 } 1512 1513 var name = Drupal.webformDetailsSaveGetName($details); 1514 if (!name) { 1515 return; 1516 } 1517 1518 var open = ($details.attr('open') !== 'open') ? '1' : '0'; 1519 localStorage.setItem(name, open); 1520 }); 1521 1522 // Initialize details open state via local storage. 1523 $('details', context).once('webform-details-save').each(function () { 1524 var $details = $(this); 1525 1526 var name = Drupal.webformDetailsSaveGetName($details); 1527 if (!name) { 1528 return; 1529 } 1530 1531 var open = localStorage.getItem(name); 1532 if (open === null) { 1533 return; 1534 } 1535 1536 if (open === '1') { 1537 $details.attr('open', 'open'); 1538 } 1539 else { 1540 $details.removeAttr('open'); 1541 } 1542 }); 1543 } 1544 1545 }; 1546 1547 /** 1548 * Get the name used to store the state of details element. 1549 * 1550 * @param {jQuery} $details 1551 * A details element. 1552 * 1553 * @return {string} 1554 * The name used to store the state of details element. 1555 */ 1556 Drupal.webformDetailsSaveGetName = function ($details) { 1557 if (!hasLocalStorage) { 1558 return ''; 1559 } 1560 1561 // Ignore details that are vertical tabs pane. 1562 if ($details.hasClass('vertical-tabs__pane')) { 1563 return ''; 1564 } 1565 1566 // Any details element not included a webform must have define its own id. 1567 var webformId = $details.attr('data-webform-element-id'); 1568 if (webformId) { 1569 return 'Drupal.webform.' + webformId.replace('--', '.'); 1570 } 1571 1572 var detailsId = $details.attr('id'); 1573 if (!detailsId) { 1574 return ''; 1575 } 1576 1577 var $form = $details.parents('form'); 1578 if (!$form.length || !$form.attr('id')) { 1579 return ''; 1580 } 1581 1582 var formId = $form.attr('id'); 1583 if (!formId) { 1584 return ''; 1585 } 1586 1587 // ISSUE: When Drupal renders a webform in a modal dialog it appends a unique 1588 // identifier to webform ids and details ids. (i.e. my-form--FeSFISegTUI) 1589 // WORKAROUND: Remove the unique id that delimited using double dashes. 1590 formId = formId.replace(/--.+?$/, '').replace(/-/g, '_'); 1591 detailsId = detailsId.replace(/--.+?$/, '').replace(/-/g, '_'); 1592 return 'Drupal.webform.' + formId + '.' + detailsId; 1593 }; 1594 1595})(jQuery, Drupal); 1596; 1597/** 1598* DO NOT EDIT THIS FILE. 1599* See the following change record for more information, 1600* https://www.drupal.org/node/2815083 1601* @preserve 1602**/ 1603 1604(function (Drupal, debounce) { 1605 var liveElement; 1606 var announcements = []; 1607 Drupal.behaviors.drupalAnnounce = { 1608 attach: function attach(context) { 1609 if (!liveElement) { 1610 liveElement = document.createElement('div'); 1611 liveElement.id = 'drupal-live-announce'; 1612 liveElement.className = 'visually-hidden'; 1613 liveElement.setAttribute('aria-live', 'polite'); 1614 liveElement.setAttribute('aria-busy', 'false'); 1615 document.body.appendChild(liveElement); 1616 } 1617 } 1618 }; 1619 1620 function announce() { 1621 var text = []; 1622 var priority = 'polite'; 1623 var announcement; 1624 var il = announcements.length; 1625 1626 for (var i = 0; i < il; i++) { 1627 announcement = announcements.pop(); 1628 text.unshift(announcement.text); 1629 1630 if (announcement.priority === 'assertive') { 1631 priority = 'assertive'; 1632 } 1633 } 1634 1635 if (text.length) { 1636 liveElement.innerHTML = ''; 1637 liveElement.setAttribute('aria-busy', 'true'); 1638 liveElement.setAttribute('aria-live', priority); 1639 liveElement.innerHTML = text.join('\n'); 1640 liveElement.setAttribute('aria-busy', 'false'); 1641 } 1642 } 1643 1644 Drupal.announce = function (text, priority) { 1645 announcements.push({ 1646 text: text, 1647 priority: priority 1648 }); 1649 return debounce(announce, 200)(); 1650 }; 1651})(Drupal, Drupal.debounce);; 1652/** 1653 * @file 1654 * JavaScript behaviors for details element. 1655 */ 1656 1657(function ($, Drupal) { 1658 1659 'use strict'; 1660 1661 Drupal.webform = Drupal.webform || {}; 1662 Drupal.webform.detailsToggle = Drupal.webform.detailsToggle || {}; 1663 Drupal.webform.detailsToggle.options = Drupal.webform.detailsToggle.options || {}; 1664 1665 /** 1666 * Attach handler to toggle details open/close state. 1667 * 1668 * @type {Drupal~behavior} 1669 */ 1670 Drupal.behaviors.webformDetailsToggle = { 1671 attach: function (context) { 1672 $('.js-webform-details-toggle', context).once('webform-details-toggle').each(function () { 1673 var $form = $(this); 1674 var $tabs = $form.find('.webform-tabs'); 1675 1676 // Get only the main details elements and ignore all nested details. 1677 var selector = ($tabs.length) ? '.webform-tab' : '.js-webform-details-toggle, .webform-elements'; 1678 var $details = $form.find('details').filter(function () { 1679 var $parents = $(this).parentsUntil(selector); 1680 return ($parents.find('details').length === 0); 1681 }); 1682 1683 // Toggle is only useful when there are two or more details elements. 1684 if ($details.length < 2) { 1685 return; 1686 } 1687 1688 var options = $.extend({ 1689 button: '<button type="button" class="webform-details-toggle-state"></button>' 1690 }, Drupal.webform.detailsToggle.options); 1691 1692 // Create toggle buttons. 1693 var $toggle = $(options.button) 1694 .attr('title', Drupal.t('Toggle details widget state.')) 1695 .on('click', function (e) { 1696 // Get details that are not vertical tabs pane. 1697 var $details = $form.find('details:not(.vertical-tabs__pane)'); 1698 var open; 1699 if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) { 1700 $details.removeAttr('open'); 1701 open = 0; 1702 } 1703 else { 1704 $details.attr('open', 'open'); 1705 open = 1; 1706 } 1707 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 1708 1709 // Set the saved states for all the details elements. 1710 // @see webform.element.details.save.js 1711 if (Drupal.webformDetailsSaveGetName) { 1712 $details.each(function () { 1713 // Note: Drupal.webformDetailsSaveGetName checks if localStorage 1714 // exists and is enabled. 1715 // @see webform.element.details.save.js 1716 var name = Drupal.webformDetailsSaveGetName($(this)); 1717 if (name) {
1718 localStorage.setItem(name, open); 1719 } 1720 }); 1721 } 1722 }) 1723 .wrap('<div class="webform-details-toggle-state-wrapper"></div>') 1724 .parent(); 1725 1726 if ($tabs.length) { 1727 // Add toggle state before the tabs. 1728 $tabs.find('.item-list:first-child').eq(0).before($toggle); 1729 } 1730 else { 1731 // Add toggle state link to first details element. 1732 $details.eq(0).before($toggle); 1733 } 1734 1735 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 1736 }); 1737 } 1738 }; 1739 1740 /** 1741 * Determine if a webform's details are all opened. 1742 * 1743 * @param {jQuery} $form 1744 * A webform. 1745 * 1746 * @return {boolean} 1747 * TRUE if a webform's details are all opened. 1748 */ 1749 Drupal.webform.detailsToggle.isFormDetailsOpen = function ($form) { 1750 return ($form.find('details[open]').length === $form.find('details').length); 1751 }; 1752 1753 /** 1754 * Set a webform's details toggle state widget label. 1755 * 1756 * @param {jQuery} $form 1757 * A webform. 1758 */ 1759 Drupal.webform.detailsToggle.setDetailsToggleLabel = function ($form) { 1760 var isOpen = Drupal.webform.detailsToggle.isFormDetailsOpen($form); 1761 1762 var label = (isOpen) ? Drupal.t('Collapse all') : Drupal.t('Expand all'); 1763 $form.find('.webform-details-toggle-state').html(label); 1764 1765 var text = (isOpen) ? Drupal.t('All details have been expanded.') : Drupal.t('All details have been collapsed.'); 1766 Drupal.announce(text); 1767 }; 1768 1769})(jQuery, Drupal); 1770; 1771/** 1772 * @file 1773 * JavaScript behaviors for message element integration. 1774 */ 1775 1776(function ($, Drupal) { 1777 1778 'use strict'; 1779 1780 // Determine if local storage exists and is enabled. 1781 // This approach is copied from Modernizr. 1782 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 1783 var hasLocalStorage = (function () { 1784 try { 1785 localStorage.setItem('webform', 'webform'); 1786 localStorage.removeItem('webform'); 1787 return true; 1788 } 1789 catch (e) { 1790 return false; 1791 } 1792 }()); 1793 1794 // Determine if session storage exists and is enabled. 1795 // This approach is copied from Modernizr. 1796 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 1797 var hasSessionStorage = (function () { 1798 try { 1799 sessionStorage.setItem('webform', 'webform'); 1800 sessionStorage.removeItem('webform'); 1801 return true; 1802 } 1803 catch (e) { 1804 return false; 1805 } 1806 }()); 1807 1808 /** 1809 * Behavior for handler message close. 1810 * 1811 * @type {Drupal~behavior} 1812 */ 1813 Drupal.behaviors.webformMessageClose = { 1814 attach: function (context) { 1815 $(context).find('.js-webform-message--close').once('webform-message--close').each(function () { 1816 var $element = $(this); 1817 1818 var id = $element.attr('data-message-id'); 1819 var storage = $element.attr('data-message-storage'); 1820 var effect = $element.attr('data-message-close-effect') || 'hide'; 1821 switch (effect) { 1822 case 'slide': effect = 'slideUp'; break; 1823 1824 case 'fade': effect = 'fadeOut'; break; 1825 } 1826 1827 // Check storage status. 1828 if (isClosed($element, storage, id)) { 1829 return; 1830 } 1831 1832 // Only show element if it's style is not set to 'display: none' 1833 // and it is not hidden via .js-webform-states-hidden. 1834 if ($element.attr('style') !== 'display: none;' && !$element.hasClass('js-webform-states-hidden')) { 1835 $element.show(); 1836 } 1837 1838 $element.find('.js-webform-message__link').on('click', function (event) { 1839 $element[effect](); 1840 setClosed($element, storage, id); 1841 $element.trigger('close'); 1842 event.preventDefault(); 1843 }); 1844 }); 1845 } 1846 }; 1847 1848 function isClosed($element, storage, id) { 1849 if (!id || !storage) { 1850 return false; 1851 } 1852 1853 switch (storage) { 1854 case 'local': 1855 if (hasLocalStorage) { 1856 return localStorage.getItem('Drupal.webform.message.' + id) || false; 1857 } 1858 return false; 1859 1860 case 'session': 1861 if (hasSessionStorage) { 1862 return sessionStorage.getItem('Drupal.webform.message.' + id) || false; 1863 } 1864 return false;
1865 1866 default: 1867 return false; 1868 } 1869 } 1870 1871 function setClosed($element, storage, id) { 1872 if (!id || !storage) { 1873 return; 1874 } 1875 1876 switch (storage) { 1877 case 'local': 1878 if (hasLocalStorage) { 1879 localStorage.setItem('Drupal.webform.message.' + id, true); 1880 } 1881 break; 1882 1883 case 'session': 1884 if (hasSessionStorage) { 1885 sessionStorage.setItem('Drupal.webform.message.' + id, true); 1886 } 1887 break; 1888 1889 case 'user': 1890 case 'state': 1891 case 'custom': 1892 $.get($element.find('.js-webform-message__link').attr('href')); 1893 return true; 1894 } 1895 } 1896 1897})(jQuery, Drupal); 1898; 1899/*! skrollr 0.6.30 (2015-08-12) | Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr | Free to use under terms of MIT license */ 1900!function(a,b,c){"use strict";function d(c){if(e=b.documentElement,f=b.body,T(),ha=this,c=c||{},ma=c.constants||{},c.easing)for(var d in c.easing)W[d]=c.easing[d];ta=c.edgeStrategy||"set",ka={beforerender:c.beforerender,render:c.render,keyframe:c.keyframe},la=c.forceHeight!==!1,la&&(Ka=c.scale||1),na=c.mobileDeceleration||y,pa=c.smoothScrolling!==!1,qa=c.smoothScrollingDuration||A,ra={targetTop:ha.getScrollTop()},Sa=(c.mobileCheck||function(){return/Android|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent||navigator.vendor||a.opera)})(),Sa?(ja=b.getElementById(c.skrollrBody||z),ja&&ga(),X(),Ea(e,[s,v],[t])):Ea(e,[s,u],[t]),ha.refresh(),wa(a,"resize orientationchange",function(){var a=e.clientWidth,b=e.clientHeight;(b!==Pa||a!==Oa)&&(Pa=b,Oa=a,Qa=!0)});var g=U();return function h(){$(),va=g(h)}(),ha}var e,f,g={get:function(){return ha},init:function(a){return ha||new d(a)},VERSION:"0.6.30"},h=Object.prototype.hasOwnProperty,i=a.Math,j=a.getComputedStyle,k="touchstart",l="touchmove",m="touchcancel",n="touchend",o="skrollable",p=o+"-before",q=o+"-between",r=o+"-after",s="skrollr",t="no-"+s,u=s+"-desktop",v=s+"-mobile",w="linear",x=1e3,y=.004,z="skrollr-body",A=200,B="start",C="end",D="center",E="bottom",F="___skrollable_id",G=/^(?:input|textarea|button|select)$/i,H=/^\s+|\s+$/g,I=/^data(?:-(_\w+))?(?:-?(-?\d*\.?\d+p?))?(?:-?(start|end|top|center|bottom))?(?:-?(top|center|bottom))?$/,J=/\s*(@?[\w\-\[\]]+)\s*:\s*(.+?)\s*(?:;|$)/gi,K=/^(@?[a-z\-]+)\[(\w+)\]$/,L=/-([a-z0-9_])/g,M=function(a,b){return b.toUpperCase()}
1900,N=/[\-+]?[\d]*\.?[\d]+/g,O=/\{\?\}/g,P=/rgba?\(\s*-?\d+\s*,\s*-?\d+\s*,\s*-?\d+/g,Q=/[a-z\-]+-gradient/g,R="",S="",T=function(){var a=/^(?:O|Moz|webkit|ms)|(?:-(?:o|moz|webkit|ms)-)/;if(j){var b=j(f,null);for(var c in b)if(R=c.match(a)||+c==c&&b[c].match(a))break;if(!R)return void(R=S="");R=R[0],"-"===R.slice(0,1)?(S=R,R={"-webkit-":"webkit","-moz-":"Moz","-ms-":"ms","-o-":"O"}[R]):S="-"+R.toLowerCase()+"-"}},U=function(){var b=a.requestAnimationFrame||a[R.toLowerCase()+"RequestAnimationFrame"],c=Ha();return(Sa||!b)&&(b=function(b){var d=Ha()-c,e=i.max(0,1e3/60-d);return a.setTimeout(function(){c=Ha(),b()},e)}),b},V=function(){var b=a.cancelAnimationFrame||a[R.toLowerCase()+"CancelAnimationFrame"];return(Sa||!b)&&(b=function(b){return a.clearTimeout(b)}),b},W={begin:function(){return 0},end:function(){return 1},linear:function(a){return a},quadratic:function(a){return a*a},cubic:function(a){return a*a*a},swing:function(a){return-i.cos(a*i.PI)/2+.5},sqrt:function(a){return i.sqrt(a)},outCubic:function(a){return i.pow(a-1,3)+1},bounce:function(a){var b;if(.5083>=a)b=3;else if(.8489>=a)b=9;else if(.96208>=a)b=27;else{if(!(.99981>=a))return 1;b=91}return 1-i.abs(3*i.cos(a*b*1.028)/b)}};d.prototype.refresh=function(a){var d,e,f=!1;for(a===c?(f=!0,ia=[],Ra=0,a=b.getElementsByTagName("*")):a.length===c&&(a=[a]),d=0,e=a.length;e>d;d++){var g=a[d],h=g,i=[],j=pa,k=ta,l=!1;if(f&&F in g&&delete g[F],g.attributes){for(var m=0,n=g.attributes.length;n>m;m++){var p=g.attributes[m];if("data-anchor-target"!==p.name)if("data-smooth-scrolling"!==p.name)if("data-edge-strategy"!==p.name)if("data-emit-events"!==p.name){var q=p.name.match(I);if(null!==q){var r={props:p.value,element:g,eventType:p.name.replace(L,M)};i.push(r);var s=q[1];s&&(r.constant=s.substr(1));var t=q[2];/p$/.test(t)?(r.isPercentage=!0,r.offset=(0|t.slice(0,-1))/100):r.offset=0|t;var u=q[3],v=q[4]||u;u&&u!==B&&u!==C?(r.mode="relative",r.anchors=[u,v]):(r.mode="absolute",u===C?r.isEnd=!0:r.isPercentage||(r.offset=r.offset*Ka))}}else l=!0;else k=p.value;else j="off"!==p.value;else if(h=b.querySelector(p.value),null===h)throw'Unable to find anchor target "'+p.value+'"'}if(i.length){var w,x,y;!f&&F in g?(y=g[F],w=ia[y].styleAttr,x=ia[y].classAttr):(y=g[F]=Ra++,w=g.style.cssText,x=Da(g)),ia[y]={element:g,styleAttr:w,classAttr:x,anchorTarget:h,keyFrames:i,smoothScrolling:j,edgeStrategy:k,emitEvents:l,lastFrameIndex:-1},Ea(g,[o],[])}}}for(Aa(),d=0,e=a.length;e>d;d++){var z=ia[a[d][F]];z!==c&&(_(z),ba(z))}return ha},d.prototype.relativeToAbsolute=function(a,b,c){var d=e.clientHeight,f=a.getBoundingClientRect(),g=f.top,h=f.bottom-f.top;return b===E?g-=d:b===D&&(g-=d/2),c===E?g+=h:c===D&&(g+=h/2),g+=ha.getScrollTop(),g+.5|0},d.prototype.animateTo=function(a,b){b=b||{};var d=Ha(),e=ha.getScrollTop(),f=b.duration===c?x:b.duration;return oa={startTop:e,topDiff:a-e,targetTop:a,duration:f,startTime:d,endTime:d+f,easing:W[b.easing||w],done:b.done},oa.topDiff||(oa.done&&oa.done.call(ha,!1),oa=c),ha},d.prototype.stopAnimateTo=function(){oa&&oa.done&&oa.done.call(ha,!0),oa=c},d.prototype.isAnimatingTo=function(){return!!oa},d.prototype.isMobile=function(){return Sa},d.prototype.setScrollTop=function(b,c){return sa=c===!0,Sa?Ta=i.min(i.max(b,0),Ja):a.scrollTo(0,b),ha},d.prototype.getScrollTop=function(){return Sa?Ta:a.pageYOffset||e.scrollTop||f.scrollTop||0},d.prototype.getMaxScrollTop=function(){return Ja},d.prototype.on=function(a,b){return ka[a]=b,ha},d.prototype.off=function(a){return delete ka[a],ha},d.prototype.destroy=function(){var a=V();a(va),ya(),Ea(e,[t],[s,u,v]);for(var b=0,d=ia.length;d>b;b++)fa(ia[b].element);e.style.overflow=f.style.overflow="",e.style.height=f.style.height="",ja&&g.setStyle(ja,"transform","none"),ha=c,ja=c,ka=c,la=c,Ja=0,Ka=1,ma=c,na=c,La="down",Ma=-1,Oa=0,Pa=0,Qa=!1,oa=c,pa=c,qa=c,ra=c,sa=c,Ra=0,ta=c,Sa=!1,Ta=0,ua=c};var X=function(){var d,g,h,j,o,p,q,r,s,t,u,v;wa(e,[k,l,m,n].join(" "),function(a){var e=a.changedTouches[0];for(j=a.target;3===j.nodeType;)j=j.parentNode;switch(o=e.clientY,p=e.clientX,t=a.timeStamp,G.test(j.tagName)||a.preventDefault(),a.type){case k:d&&d.blur(),ha.stopAnimateTo(),d=j,g=q=o,h=p,s=t;break;case l:G.test(j.tagName)&&b.activeElement!==j&&a.preventDefault(),r
1900=o-q,v=t-u,ha.setScrollTop(Ta-r,!0),q=o,u=t;break;default:case m:case n:var f=g-o,w=h-p,x=w*w+f*f;if(49>x){if(!G.test(d.tagName)){d.focus();var y=b.createEvent("MouseEvents");y.initMouseEvent("click",!0,!0,a.view,1,e.screenX,e.screenY,e.clientX,e.clientY,a.ctrlKey,a.altKey,a.shiftKey,a.metaKey,0,null),d.dispatchEvent(y)}return}d=c;var z=r/v;z=i.max(i.min(z,3),-3);var A=i.abs(z/na),B=z*A+.5*na*A*A,C=ha.getScrollTop()-B,D=0;C>Ja?(D=(Ja-C)/B,C=Ja):0>C&&(D=-C/B,C=0),A*=1-D,ha.animateTo(C+.5|0,{easing:"outCubic",duration:A})}}),a.scrollTo(0,0),e.style.overflow=f.style.overflow="hidden"},Y=function(){var a,b,c,d,f,g,h,j,k,l,m,n=e.clientHeight,o=Ba();for(j=0,k=ia.length;k>j;j++)for(a=ia[j],b=a.element,c=a.anchorTarget,d=a.keyFrames,f=0,g=d.length;g>f;f++)h=d[f],l=h.offset,m=o[h.constant]||0,h.frame=l,h.isPercentage&&(l*=n,h.frame=l),"relative"===h.mode&&(fa(b),h.frame=ha.relativeToAbsolute(c,h.anchors[0],h.anchors[1])-l,fa(b,!0)),h.frame+=m,la&&!h.isEnd&&h.frame>Ja&&(Ja=h.frame);for(Ja=i.max(Ja,Ca()),j=0,k=ia.length;k>j;j++){for(a=ia[j],d=a.keyFrames,f=0,g=d.length;g>f;f++)h=d[f],m=o[h.constant]||0,h.isEnd&&(h.frame=Ja-h.offset+m);a.keyFrames.sort(Ia)}},Z=function(a,b){for(var c=0,d=ia.length;d>c;c++){var e,f,i=ia[c],j=i.element,k=i.smoothScrolling?a:b,l=i.keyFrames,m=l.length,n=l[0],s=l[l.length-1],t=k<n.frame,u=k>s.frame,v=t?n:s,w=i.emitEvents,x=i.lastFrameIndex;if(t||u){if(t&&-1===i.edge||u&&1===i.edge)continue;switch(t?(Ea(j,[p],[r,q]),w&&x>-1&&(za(j,n.eventType,La),i.lastFrameIndex=-1)):(Ea(j,[r],[p,q]),w&&m>x&&(za(j,s.eventType,La),i.lastFrameIndex=m)),i.edge=t?-1:1,i.edgeStrategy){case"reset":fa(j);continue;case"ease":k=v.frame;break;default:case"set":var y=v.props;for(e in y)h.call(y,e)&&(f=ea(y[e].value),0===e.indexOf("@")?j.setAttribute(e.substr(1),f):g.setStyle(j,e,f));continue}}else 0!==i.edge&&(Ea(j,[o,q],[p,r]),i.edge=0);for(var z=0;m-1>z;z++)if(k>=l[z].frame&&k<=l[z+1].frame){var A=l[z],B=l[z+1];for(e in A.props)if(h.call(A.props,e)){var C=(k-A.frame)/(B.frame-A.frame);C=A.props[e].easing(C),f=da(A.props[e].value,B.props[e].value,C),f=ea(f),0===e.indexOf("@")?j.setAttribute(e.substr(1),f):g.setStyle(j,e,f)}w&&x!==z&&("down"===La?za(j,A.eventType,La):za(j,B.eventType,La),i.lastFrameIndex=z);break}}},$=function(){Qa&&(Qa=!1,Aa());var a,b,d=ha.getScrollTop(),e=Ha();if(oa)e>=oa.endTime?(d=oa.targetTop,a=oa.done,oa=c):(b=oa.easing((e-oa.startTime)/oa.duration),d=oa.startTop+b*oa.topDiff|0),ha.setScrollTop(d,!0);else if(!sa){var f=ra.targetTop-d;f&&(ra={startTop:Ma,topDiff:d-Ma,targetTop:d,startTime:Na,endTime:Na+qa}),e<=ra.endTime&&(b=W.sqrt((e-ra.startTime)/qa),d=ra.startTop+b*ra.topDiff|0)}if(sa||Ma!==d){La=d>Ma?"down":Ma>d?"up":La,sa=!1;var h={curTop:d,lastTop:Ma,maxTop:Ja,direction:La},i=ka.beforerender&&ka.beforerender.call(ha,h);i!==!1&&(Z(d,ha.getScrollTop()),Sa&&ja&&g.setStyle(ja,"transform","translate(0, "+-Ta+"px) "+ua),Ma=d,ka.render&&ka.render.call(ha,h)),a&&a.call(ha,!1)}Na=e},_=function(a){for(var b=0,c=a.keyFrames.length;c>b;b++){for(var d,e,f,g,h=a.keyFrames[b],i={};null!==(g=J.exec(h.props));)f=g[1],e=g[2],d=f.match(K),null!==d?(f=d[1],d=d[2]):d=w,e=e.indexOf("!")?aa(e):[e.slice(1)],i[f]={value:e,easing:W[d]};h.props=i}},aa=function(a){var b=[];return P.lastIndex=0,a=a.replace(P,function(a){return a.replace(N,function(a){return a/255*100+"%"})}),S&&(Q.lastIndex=0,a=a.replace(Q,function(a){return S+a})),a=a.replace(N,function(a){return b.push(+a),"{?}"}),b.unshift(a),b},ba=function(a){var b,c,d={};for(b=0,c=a.keyFrames.length;c>b;b++)ca(a.keyFrames[b],d);for(d={},b=a.keyFrames.length-1;b>=0;b--)ca(a.keyFrames[b],d)},ca=function(a,b){var c;for(c in b)h.call(a.props,c)||(a.props[c]=b[c]);for(c in a.props)b[c]=a.props[c]},da=function(a,b,c){var d,e=a.length;if(e!==b.length)throw"Can't interpolate between \""+a[0]+'" and "'+b[0]+'"';var f=[a[0]];for(d=1;e>d;d++)f[d]=a[d]+(b[d]-a[d])*c;return f},ea=function(a){var b=1;return O.lastIndex=0,a[0].replace(O,function(){return a[b++]})},fa=function(a,b){a=[].concat(a);for(var c,d,e=0,f=a.length;f>e;e++)d=a[e],c=ia[d[F]],c&&(b?(d.style.cssText=c.dirtyStyleAttr,Ea(d,c.dirtyClassAttr)):(c.dirtyStyleAttr=d.style.cssText,c.dirtyClassAttr=Da(d),d.style.cssText=c.styleAttr,E
1900a(d,c.classAttr)))},ga=function(){ua="translateZ(0)",g.setStyle(ja,"transform",ua);var a=j(ja),b=a.getPropertyValue("transform"),c=a.getPropertyValue(S+"transform"),d=b&&"none"!==b||c&&"none"!==c;d||(ua="")};g.setStyle=function(a,b,c){var d=a.style;if(b=b.replace(L,M).replace("-",""),"zIndex"===b)isNaN(c)?d[b]=c:d[b]=""+(0|c);else if("float"===b)d.styleFloat=d.cssFloat=c;else try{R&&(d[R+b.slice(0,1).toUpperCase()+b.slice(1)]=c),d[b]=c}catch(e){}};var ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua,va,wa=g.addEvent=function(b,c,d){var e=function(b){return b=b||a.event,b.target||(b.target=b.srcElement),b.preventDefault||(b.preventDefault=function(){b.returnValue=!1,b.defaultPrevented=!0}),d.call(this,b)};c=c.split(" ");for(var f,g=0,h=c.length;h>g;g++)f=c[g],b.addEventListener?b.addEventListener(f,d,!1):b.attachEvent("on"+f,e),Ua.push({element:b,name:f,listener:d})},xa=g.removeEvent=function(a,b,c){b=b.split(" ");for(var d=0,e=b.length;e>d;d++)a.removeEventListener?a.removeEventListener(b[d],c,!1):a.detachEvent("on"+b[d],c)},ya=function(){for(var a,b=0,c=Ua.length;c>b;b++)a=Ua[b],xa(a.element,a.name,a.listener);Ua=[]},za=function(a,b,c){ka.keyframe&&ka.keyframe.call(ha,a,b,c)},Aa=function(){var a=ha.getScrollTop();Ja=0,la&&!Sa&&(f.style.height=""),Y(),la&&!Sa&&(f.style.height=Ja+e.clientHeight+"px"),Sa?ha.setScrollTop(i.min(ha.getScrollTop(),Ja)):ha.setScrollTop(a,!0),sa=!0},Ba=function(){var a,b,c=e.clientHeight,d={};for(a in ma)b=ma[a],"function"==typeof b?b=b.call(ha):/p$/.test(b)&&(b=b.slice(0,-1)/100*c),d[a]=b;return d},Ca=function(){var a,b=0;return ja&&(b=i.max(ja.offsetHeight,ja.scrollHeight)),a=i.max(b,f.scrollHeight,f.offsetHeight,e.scrollHeight,e.offsetHeight,e.clientHeight),a-e.clientHeight},Da=function(b){var c="className";return a.SVGElement&&b instanceof a.SVGElement&&(b=b[c],c="baseVal"),b[c]},Ea=function(b,d,e){var f="className";if(a.SVGElement&&b instanceof a.SVGElement&&(b=b[f],f="baseVal"),e===c)return void(b[f]=d);for(var g=b[f],h=0,i=e.length;i>h;h++)g=Ga(g).replace(Ga(e[h])," ");g=Fa(g);for(var j=0,k=d.length;k>j;j++)-1===Ga(g).indexOf(Ga(d[j]))&&(g+=" "+d[j]);b[f]=Fa(g)},Fa=function(a){return a.replace(H,"")},Ga=function(a){return" "+a+" "},Ha=Date.now||function(){return+new Date},Ia=function(a,b){return a.frame-b.frame},Ja=0,Ka=1,La="down",Ma=-1,Na=Ha(),Oa=0,Pa=0,Qa=!1,Ra=0,Sa=!1,Ta=0,Ua=[];"function"==typeof define&&define.amd?define([],function(){return g}):"undefined"!=typeof module&&module.exports?module.exports=g:a.skrollr=g}(window,document);; 1901(function ($) { 1902 $.fn.gav_skrollr = function(s) { 1903 var $w = $(window), 1904 loaded, 1905 skrollr = this 1906 th = 200; 1907 this.one("gav_skrollr", function() { 1908 s.refresh(); 1909 }); 1910 function gav_skrollr() { 1911 var inview = skrollr.filter(function() { 1912 var $e = $(this); 1913 var wt = $w.scrollTop(), 1914 wb = wt + $w.height(), 1915 et = $e.offset().top, 1916 eb = et + $e.height(); 1917 1918 return eb >= wt - th && et <= wb + th; 1919 }); 1920 loaded = inview.trigger("gav_skrollr"); 1921 skrollr = skrollr.not(loaded); 1922 } 1923 $(window).on("scroll.gav_skrollr", gav_skrollr); 1924 }; 1925 $(window).on('load', function(){ 1926 setTimeout(function() { 1927 s = skrollr.init({forceHeight:!1,smoothScrolling:!1,mobileCheck:function(){return!1}}); 1928 if($('.skrollable.refresh').length){ 1929 $('.skrollable.refresh').gav_skrollr(s); 1930 } 1931 }, 50); 1932 }); 1933})(jQuery); 1934;
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.