/*! * OneCloud Reimagine v0.402.0 * MWF (Moray) v2.8.1 * Copyright (c) Microsoft Corporation. All rights reserved. * Copyright 2011-2020 The Bootstrap Authors and Twitter, Inc. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ocrReimagine = {})); })(this, (function (exports) { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var check = function (it) { return it && it.Math == Math && it; }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global$y = // eslint-disable-next-line es/no-global-this -- safe check(typeof globalThis == 'object' && globalThis) || check(typeof window == 'object' && window) || // eslint-disable-next-line no-restricted-globals -- safe check(typeof self == 'object' && self) || check(typeof commonjsGlobal == 'object' && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback (function () { return this; })() || Function('return this')(); var objectGetOwnPropertyDescriptor = {}; var fails$I = function (exec) { try { return !!exec(); } catch (error) { return true; } }; var fails$H = fails$I; // Detect IE8's incomplete defineProperty implementation var descriptors = !fails$H(function () { // eslint-disable-next-line es/no-object-defineproperty -- required for testing return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] != 7; }); var fails$G = fails$I; var functionBindNative = !fails$G(function () { // eslint-disable-next-line es/no-function-prototype-bind -- safe var test = (function () { /* empty */ }).bind(); // eslint-disable-next-line no-prototype-builtins -- safe return typeof test != 'function' || test.hasOwnProperty('prototype'); }); var NATIVE_BIND$4 = functionBindNative; var call$o = Function.prototype.call; var functionCall = NATIVE_BIND$4 ? call$o.bind(call$o) : function () { return call$o.apply(call$o, arguments); }; var objectPropertyIsEnumerable = {}; var $propertyIsEnumerable$1 = {}.propertyIsEnumerable; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var getOwnPropertyDescriptor$6 = Object.getOwnPropertyDescriptor; // Nashorn ~ JDK8 bug var NASHORN_BUG = getOwnPropertyDescriptor$6 && !$propertyIsEnumerable$1.call({ 1: 2 }, 1); // `Object.prototype.propertyIsEnumerable` method implementation // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V) { var descriptor = getOwnPropertyDescriptor$6(this, V); return !!descriptor && descriptor.enumerable; } : $propertyIsEnumerable$1; var createPropertyDescriptor$8 = function (bitmap, value) { return { enumerable: !(bitmap & 1), configurable: !(bitmap & 2), writable: !(bitmap & 4), value: value }; }; var NATIVE_BIND$3 = functionBindNative; var FunctionPrototype$3 = Function.prototype; var call$n = FunctionPrototype$3.call; var uncurryThisWithBind = NATIVE_BIND$3 && FunctionPrototype$3.bind.bind(call$n, call$n); var functionUncurryThis = NATIVE_BIND$3 ? uncurryThisWithBind : function (fn) { return function () { return call$n.apply(fn, arguments); }; }; var uncurryThis$N = functionUncurryThis; var toString$l = uncurryThis$N({}.toString); var stringSlice$a = uncurryThis$N(''.slice); var classofRaw$2 = function (it) { return stringSlice$a(toString$l(it), 8, -1); }; var uncurryThis$M = functionUncurryThis; var fails$F = fails$I; var classof$d = classofRaw$2; var $Object$5 = Object; var split$3 = uncurryThis$M(''.split); // fallback for non-array-like ES3 and non-enumerable old V8 strings var indexedObject = fails$F(function () { // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 // eslint-disable-next-line no-prototype-builtins -- safe return !$Object$5('z').propertyIsEnumerable(0); }) ? function (it) { return classof$d(it) == 'String' ? split$3(it, '') : $Object$5(it); } : $Object$5; // we can't use just `it == null` since of `document.all` special case // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec var isNullOrUndefined$9 = function (it) { return it === null || it === undefined; }; var isNullOrUndefined$8 = isNullOrUndefined$9; var $TypeError$h = TypeError; // `RequireObjectCoercible` abstract operation // https://tc39.es/ecma262/#sec-requireobjectcoercible var requireObjectCoercible$b = function (it) { if (isNullOrUndefined$8(it)) throw $TypeError$h("Can't call method on " + it); return it; }; // toObject with fallback for non-array-like ES3 strings var IndexedObject$3 = indexedObject; var requireObjectCoercible$a = requireObjectCoercible$b; var toIndexedObject$a = function (it) { return IndexedObject$3(requireObjectCoercible$a(it)); }; var documentAll$2 = typeof document == 'object' && document.all; // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot // eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing var IS_HTMLDDA = typeof documentAll$2 == 'undefined' && documentAll$2 !== undefined; var documentAll_1 = { all: documentAll$2, IS_HTMLDDA: IS_HTMLDDA }; var $documentAll$1 = documentAll_1; var documentAll$1 = $documentAll$1.all; // `IsCallable` abstract operation // https://tc39.es/ecma262/#sec-iscallable var isCallable$u = $documentAll$1.IS_HTMLDDA ? function (argument) { return typeof argument == 'function' || argument === documentAll$1; } : function (argument) { return typeof argument == 'function'; }; var isCallable$t = isCallable$u; var $documentAll = documentAll_1; var documentAll = $documentAll.all; var isObject$l = $documentAll.IS_HTMLDDA ? function (it) { return typeof it == 'object' ? it !== null : isCallable$t(it) || it === documentAll; } : function (it) { return typeof it == 'object' ? it !== null : isCallable$t(it); }; var global$x = global$y; var isCallable$s = isCallable$u; var aFunction = function (argument) { return isCallable$s(argument) ? argument : undefined; }; var getBuiltIn$e = function (namespace, method) { return arguments.length < 2 ? aFunction(global$x[namespace]) : global$x[namespace] && global$x[namespace][method]; }; var uncurryThis$L = functionUncurryThis; var objectIsPrototypeOf = uncurryThis$L({}.isPrototypeOf); var engineUserAgent = typeof navigator != 'undefined' && String(navigator.userAgent) || ''; var global$w = global$y; var userAgent$6 = engineUserAgent; var process$4 = global$w.process; var Deno$1 = global$w.Deno; var versions = process$4 && process$4.versions || Deno$1 && Deno$1.version; var v8 = versions && versions.v8; var match, version; if (v8) { match = v8.split('.'); // in old Chrome, versions of V8 isn't V8 = Chrome / 10 // but their correct versions are not interesting for us version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); } // BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` // so check `userAgent` even if `.v8` exists, but 0 if (!version && userAgent$6) { match = userAgent$6.match(/Edge\/(\d+)/); if (!match || match[1] >= 74) { match = userAgent$6.match(/Chrome\/(\d+)/); if (match) version = +match[1]; } } var engineV8Version = version; /* eslint-disable es/no-symbol -- required for testing */ var V8_VERSION$3 = engineV8Version; var fails$E = fails$I; // eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$E(function () { var symbol = Symbol(); // Chrome 38 Symbol has incorrect toString conversion // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances return !String(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances !Symbol.sham && V8_VERSION$3 && V8_VERSION$3 < 41; }); /* eslint-disable es/no-symbol -- required for testing */ var NATIVE_SYMBOL$2 = symbolConstructorDetection; var useSymbolAsUid = NATIVE_SYMBOL$2 && !Symbol.sham && typeof Symbol.iterator == 'symbol'; var getBuiltIn$d = getBuiltIn$e; var isCallable$r = isCallable$u; var isPrototypeOf$5 = objectIsPrototypeOf; var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; var $Object$4 = Object; var isSymbol$4 = USE_SYMBOL_AS_UID$1 ? function (it) { return typeof it == 'symbol'; } : function (it) { var $Symbol = getBuiltIn$d('Symbol'); return isCallable$r($Symbol) && isPrototypeOf$5($Symbol.prototype, $Object$4(it)); }; var $String$5 = String; var tryToString$5 = function (argument) { try { return $String$5(argument); } catch (error) { return 'Object'; } }; var isCallable$q = isCallable$u; var tryToString$4 = tryToString$5; var $TypeError$g = TypeError; // `Assert: IsCallable(argument) is true` var aCallable$a = function (argument) { if (isCallable$q(argument)) return argument; throw $TypeError$g(tryToString$4(argument) + ' is not a function'); }; var aCallable$9 = aCallable$a; var isNullOrUndefined$7 = isNullOrUndefined$9; // `GetMethod` abstract operation // https://tc39.es/ecma262/#sec-getmethod var getMethod$5 = function (V, P) { var func = V[P]; return isNullOrUndefined$7(func) ? undefined : aCallable$9(func); }; var call$m = functionCall; var isCallable$p = isCallable$u; var isObject$k = isObject$l; var $TypeError$f = TypeError; // `OrdinaryToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-ordinarytoprimitive var ordinaryToPrimitive$1 = function (input, pref) { var fn, val; if (pref === 'string' && isCallable$p(fn = input.toString) && !isObject$k(val = call$m(fn, input))) return val; if (isCallable$p(fn = input.valueOf) && !isObject$k(val = call$m(fn, input))) return val; if (pref !== 'string' && isCallable$p(fn = input.toString) && !isObject$k(val = call$m(fn, input))) return val; throw $TypeError$f("Can't convert object to primitive value"); }; var shared$4 = {exports: {}}; var isPure = false; var global$v = global$y; // eslint-disable-next-line es/no-object-defineproperty -- safe var defineProperty$c = Object.defineProperty; var defineGlobalProperty$3 = function (key, value) { try { defineProperty$c(global$v, key, { value: value, configurable: true, writable: true }); } catch (error) { global$v[key] = value; } return value; }; var global$u = global$y; var defineGlobalProperty$2 = defineGlobalProperty$3; var SHARED = '__core-js_shared__'; var store$3 = global$u[SHARED] || defineGlobalProperty$2(SHARED, {}); var sharedStore = store$3; var store$2 = sharedStore; (shared$4.exports = function (key, value) { return store$2[key] || (store$2[key] = value !== undefined ? value : {}); })('versions', []).push({ version: '3.30.1', mode: 'global', copyright: '© 2014-2023 Denis Pushkarev (zloirock.ru)', license: 'https://github.com/zloirock/core-js/blob/v3.30.1/LICENSE', source: 'https://github.com/zloirock/core-js' }); var sharedExports = shared$4.exports; var requireObjectCoercible$9 = requireObjectCoercible$b; var $Object$3 = Object; // `ToObject` abstract operation // https://tc39.es/ecma262/#sec-toobject var toObject$b = function (argument) { return $Object$3(requireObjectCoercible$9(argument)); }; var uncurryThis$K = functionUncurryThis; var toObject$a = toObject$b; var hasOwnProperty = uncurryThis$K({}.hasOwnProperty); // `HasOwnProperty` abstract operation // https://tc39.es/ecma262/#sec-hasownproperty // eslint-disable-next-line es/no-object-hasown -- safe var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { return hasOwnProperty(toObject$a(it), key); }; var uncurryThis$J = functionUncurryThis; var id$3 = 0; var postfix = Math.random(); var toString$k = uncurryThis$J(1.0.toString); var uid$3 = function (key) { return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString$k(++id$3 + postfix, 36); }; var global$t = global$y; var shared$3 = sharedExports; var hasOwn$l = hasOwnProperty_1; var uid$2 = uid$3; var NATIVE_SYMBOL$1 = symbolConstructorDetection; var USE_SYMBOL_AS_UID = useSymbolAsUid; var Symbol$3 = global$t.Symbol; var WellKnownSymbolsStore = shared$3('wks'); var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$3['for'] || Symbol$3 : Symbol$3 && Symbol$3.withoutSetter || uid$2; var wellKnownSymbol$o = function (name) { if (!hasOwn$l(WellKnownSymbolsStore, name)) { WellKnownSymbolsStore[name] = NATIVE_SYMBOL$1 && hasOwn$l(Symbol$3, name) ? Symbol$3[name] : createWellKnownSymbol('Symbol.' + name); } return WellKnownSymbolsStore[name]; }; var call$l = functionCall; var isObject$j = isObject$l; var isSymbol$3 = isSymbol$4; var getMethod$4 = getMethod$5; var ordinaryToPrimitive = ordinaryToPrimitive$1; var wellKnownSymbol$n = wellKnownSymbol$o; var $TypeError$e = TypeError; var TO_PRIMITIVE = wellKnownSymbol$n('toPrimitive'); // `ToPrimitive` abstract operation // https://tc39.es/ecma262/#sec-toprimitive var toPrimitive$2 = function (input, pref) { if (!isObject$j(input) || isSymbol$3(input)) return input; var exoticToPrim = getMethod$4(input, TO_PRIMITIVE); var result; if (exoticToPrim) { if (pref === undefined) pref = 'default'; result = call$l(exoticToPrim, input, pref); if (!isObject$j(result) || isSymbol$3(result)) return result; throw $TypeError$e("Can't convert object to primitive value"); } if (pref === undefined) pref = 'number'; return ordinaryToPrimitive(input, pref); }; var toPrimitive$1 = toPrimitive$2; var isSymbol$2 = isSymbol$4; // `ToPropertyKey` abstract operation // https://tc39.es/ecma262/#sec-topropertykey var toPropertyKey$3 = function (argument) { var key = toPrimitive$1(argument, 'string'); return isSymbol$2(key) ? key : key + ''; }; var global$s = global$y; var isObject$i = isObject$l; var document$3 = global$s.document; // typeof document.createElement is 'object' in old IE var EXISTS$1 = isObject$i(document$3) && isObject$i(document$3.createElement); var documentCreateElement$2 = function (it) { return EXISTS$1 ? document$3.createElement(it) : {}; }; var DESCRIPTORS$o = descriptors; var fails$D = fails$I; var createElement$1 = documentCreateElement$2; // Thanks to IE8 for its funny defineProperty var ie8DomDefine = !DESCRIPTORS$o && !fails$D(function () { // eslint-disable-next-line es/no-object-defineproperty -- required for testing return Object.defineProperty(createElement$1('div'), 'a', { get: function () { return 7; } }).a != 7; }); var DESCRIPTORS$n = descriptors; var call$k = functionCall; var propertyIsEnumerableModule$1 = objectPropertyIsEnumerable; var createPropertyDescriptor$7 = createPropertyDescriptor$8; var toIndexedObject$9 = toIndexedObject$a; var toPropertyKey$2 = toPropertyKey$3; var hasOwn$k = hasOwnProperty_1; var IE8_DOM_DEFINE$1 = ie8DomDefine; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; // `Object.getOwnPropertyDescriptor` method // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor objectGetOwnPropertyDescriptor.f = DESCRIPTORS$n ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) { O = toIndexedObject$9(O); P = toPropertyKey$2(P); if (IE8_DOM_DEFINE$1) try { return $getOwnPropertyDescriptor$1(O, P); } catch (error) { /* empty */ } if (hasOwn$k(O, P)) return createPropertyDescriptor$7(!call$k(propertyIsEnumerableModule$1.f, O, P), O[P]); }; var objectDefineProperty = {}; var DESCRIPTORS$m = descriptors; var fails$C = fails$I; // V8 ~ Chrome 36- // https://bugs.chromium.org/p/v8/issues/detail?id=3334 var v8PrototypeDefineBug = DESCRIPTORS$m && fails$C(function () { // eslint-disable-next-line es/no-object-defineproperty -- required for testing return Object.defineProperty(function () { /* empty */ }, 'prototype', { value: 42, writable: false }).prototype != 42; }); var isObject$h = isObject$l; var $String$4 = String; var $TypeError$d = TypeError; // `Assert: Type(argument) is Object` var anObject$l = function (argument) { if (isObject$h(argument)) return argument; throw $TypeError$d($String$4(argument) + ' is not an object'); }; var DESCRIPTORS$l = descriptors; var IE8_DOM_DEFINE = ie8DomDefine; var V8_PROTOTYPE_DEFINE_BUG$1 = v8PrototypeDefineBug; var anObject$k = anObject$l; var toPropertyKey$1 = toPropertyKey$3; var $TypeError$c = TypeError; // eslint-disable-next-line es/no-object-defineproperty -- safe var $defineProperty = Object.defineProperty; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; var ENUMERABLE = 'enumerable'; var CONFIGURABLE$1 = 'configurable'; var WRITABLE = 'writable'; // `Object.defineProperty` method // https://tc39.es/ecma262/#sec-object.defineproperty objectDefineProperty.f = DESCRIPTORS$l ? V8_PROTOTYPE_DEFINE_BUG$1 ? function defineProperty(O, P, Attributes) { anObject$k(O); P = toPropertyKey$1(P); anObject$k(Attributes); if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { var current = $getOwnPropertyDescriptor(O, P); if (current && current[WRITABLE]) { O[P] = Attributes.value; Attributes = { configurable: CONFIGURABLE$1 in Attributes ? Attributes[CONFIGURABLE$1] : current[CONFIGURABLE$1], enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], writable: false }; } } return $defineProperty(O, P, Attributes); } : $defineProperty : function defineProperty(O, P, Attributes) { anObject$k(O); P = toPropertyKey$1(P); anObject$k(Attributes); if (IE8_DOM_DEFINE) try { return $defineProperty(O, P, Attributes); } catch (error) { /* empty */ } if ('get' in Attributes || 'set' in Attributes) throw $TypeError$c('Accessors not supported'); if ('value' in Attributes) O[P] = Attributes.value; return O; }; var DESCRIPTORS$k = descriptors; var definePropertyModule$4 = objectDefineProperty; var createPropertyDescriptor$6 = createPropertyDescriptor$8; var createNonEnumerableProperty$9 = DESCRIPTORS$k ? function (object, key, value) { return definePropertyModule$4.f(object, key, createPropertyDescriptor$6(1, value)); } : function (object, key, value) { object[key] = value; return object; }; var makeBuiltIn$3 = {exports: {}}; var DESCRIPTORS$j = descriptors; var hasOwn$j = hasOwnProperty_1; var FunctionPrototype$2 = Function.prototype; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var getDescriptor = DESCRIPTORS$j && Object.getOwnPropertyDescriptor; var EXISTS = hasOwn$j(FunctionPrototype$2, 'name'); // additional protection from minified / mangled / dropped function names var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; var CONFIGURABLE = EXISTS && (!DESCRIPTORS$j || (DESCRIPTORS$j && getDescriptor(FunctionPrototype$2, 'name').configurable)); var functionName = { EXISTS: EXISTS, PROPER: PROPER, CONFIGURABLE: CONFIGURABLE }; var uncurryThis$I = functionUncurryThis; var isCallable$o = isCallable$u; var store$1 = sharedStore; var functionToString$1 = uncurryThis$I(Function.toString); // this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper if (!isCallable$o(store$1.inspectSource)) { store$1.inspectSource = function (it) { return functionToString$1(it); }; } var inspectSource$3 = store$1.inspectSource; var global$r = global$y; var isCallable$n = isCallable$u; var WeakMap$2 = global$r.WeakMap; var weakMapBasicDetection = isCallable$n(WeakMap$2) && /native code/.test(String(WeakMap$2)); var shared$2 = sharedExports; var uid$1 = uid$3; var keys = shared$2('keys'); var sharedKey$3 = function (key) { return keys[key] || (keys[key] = uid$1(key)); }; var hiddenKeys$5 = {}; var NATIVE_WEAK_MAP$1 = weakMapBasicDetection; var global$q = global$y; var isObject$g = isObject$l; var createNonEnumerableProperty$8 = createNonEnumerableProperty$9; var hasOwn$i = hasOwnProperty_1; var shared$1 = sharedStore; var sharedKey$2 = sharedKey$3; var hiddenKeys$4 = hiddenKeys$5; var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; var TypeError$5 = global$q.TypeError; var WeakMap$1 = global$q.WeakMap; var set$1, get, has; var enforce = function (it) { return has(it) ? get(it) : set$1(it, {}); }; var getterFor$1 = function (TYPE) { return function (it) { var state; if (!isObject$g(it) || (state = get(it)).type !== TYPE) { throw TypeError$5('Incompatible receiver, ' + TYPE + ' required'); } return state; }; }; if (NATIVE_WEAK_MAP$1 || shared$1.state) { var store = shared$1.state || (shared$1.state = new WeakMap$1()); /* eslint-disable no-self-assign -- prototype methods protection */ store.get = store.get; store.has = store.has; store.set = store.set; /* eslint-enable no-self-assign -- prototype methods protection */ set$1 = function (it, metadata) { if (store.has(it)) throw TypeError$5(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; store.set(it, metadata); return metadata; }; get = function (it) { return store.get(it) || {}; }; has = function (it) { return store.has(it); }; } else { var STATE = sharedKey$2('state'); hiddenKeys$4[STATE] = true; set$1 = function (it, metadata) { if (hasOwn$i(it, STATE)) throw TypeError$5(OBJECT_ALREADY_INITIALIZED); metadata.facade = it; createNonEnumerableProperty$8(it, STATE, metadata); return metadata; }; get = function (it) { return hasOwn$i(it, STATE) ? it[STATE] : {}; }; has = function (it) { return hasOwn$i(it, STATE); }; } var internalState = { set: set$1, get: get, has: has, enforce: enforce, getterFor: getterFor$1 }; var uncurryThis$H = functionUncurryThis; var fails$B = fails$I; var isCallable$m = isCallable$u; var hasOwn$h = hasOwnProperty_1; var DESCRIPTORS$i = descriptors; var CONFIGURABLE_FUNCTION_NAME$1 = functionName.CONFIGURABLE; var inspectSource$2 = inspectSource$3; var InternalStateModule$8 = internalState; var enforceInternalState$1 = InternalStateModule$8.enforce; var getInternalState$4 = InternalStateModule$8.get; var $String$3 = String; // eslint-disable-next-line es/no-object-defineproperty -- safe var defineProperty$b = Object.defineProperty; var stringSlice$9 = uncurryThis$H(''.slice); var replace$a = uncurryThis$H(''.replace); var join$4 = uncurryThis$H([].join); var CONFIGURABLE_LENGTH = DESCRIPTORS$i && !fails$B(function () { return defineProperty$b(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; }); var TEMPLATE = String(String).split('String'); var makeBuiltIn$2 = makeBuiltIn$3.exports = function (value, name, options) { if (stringSlice$9($String$3(name), 0, 7) === 'Symbol(') { name = '[' + replace$a($String$3(name), /^Symbol\(([^)]*)\)/, '$1') + ']'; } if (options && options.getter) name = 'get ' + name; if (options && options.setter) name = 'set ' + name; if (!hasOwn$h(value, 'name') || (CONFIGURABLE_FUNCTION_NAME$1 && value.name !== name)) { if (DESCRIPTORS$i) defineProperty$b(value, 'name', { value: name, configurable: true }); else value.name = name; } if (CONFIGURABLE_LENGTH && options && hasOwn$h(options, 'arity') && value.length !== options.arity) { defineProperty$b(value, 'length', { value: options.arity }); } try { if (options && hasOwn$h(options, 'constructor') && options.constructor) { if (DESCRIPTORS$i) defineProperty$b(value, 'prototype', { writable: false }); // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable } else if (value.prototype) value.prototype = undefined; } catch (error) { /* empty */ } var state = enforceInternalState$1(value); if (!hasOwn$h(state, 'source')) { state.source = join$4(TEMPLATE, typeof name == 'string' ? name : ''); } return value; }; // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative // eslint-disable-next-line no-extend-native -- required Function.prototype.toString = makeBuiltIn$2(function toString() { return isCallable$m(this) && getInternalState$4(this).source || inspectSource$2(this); }, 'toString'); var makeBuiltInExports = makeBuiltIn$3.exports; var isCallable$l = isCallable$u; var definePropertyModule$3 = objectDefineProperty; var makeBuiltIn$1 = makeBuiltInExports; var defineGlobalProperty$1 = defineGlobalProperty$3; var defineBuiltIn$g = function (O, key, value, options) { if (!options) options = {}; var simple = options.enumerable; var name = options.name !== undefined ? options.name : key; if (isCallable$l(value)) makeBuiltIn$1(value, name, options); if (options.global) { if (simple) O[key] = value; else defineGlobalProperty$1(key, value); } else { try { if (!options.unsafe) delete O[key]; else if (O[key]) simple = true; } catch (error) { /* empty */ } if (simple) O[key] = value; else definePropertyModule$3.f(O, key, { value: value, enumerable: false, configurable: !options.nonConfigurable, writable: !options.nonWritable }); } return O; }; var objectGetOwnPropertyNames = {}; var ceil$1 = Math.ceil; var floor$4 = Math.floor; // `Math.trunc` method // https://tc39.es/ecma262/#sec-math.trunc // eslint-disable-next-line es/no-math-trunc -- safe var mathTrunc = Math.trunc || function trunc(x) { var n = +x; return (n > 0 ? floor$4 : ceil$1)(n); }; var trunc = mathTrunc; // `ToIntegerOrInfinity` abstract operation // https://tc39.es/ecma262/#sec-tointegerorinfinity var toIntegerOrInfinity$7 = function (argument) { var number = +argument; // eslint-disable-next-line no-self-compare -- NaN check return number !== number || number === 0 ? 0 : trunc(number); }; var toIntegerOrInfinity$6 = toIntegerOrInfinity$7; var max$4 = Math.max; var min$5 = Math.min; // Helper for a popular repeating case of the spec: // Let integer be ? ToInteger(index). // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). var toAbsoluteIndex$4 = function (index, length) { var integer = toIntegerOrInfinity$6(index); return integer < 0 ? max$4(integer + length, 0) : min$5(integer, length); }; var toIntegerOrInfinity$5 = toIntegerOrInfinity$7; var min$4 = Math.min; // `ToLength` abstract operation // https://tc39.es/ecma262/#sec-tolength var toLength$5 = function (argument) { return argument > 0 ? min$4(toIntegerOrInfinity$5(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 }; var toLength$4 = toLength$5; // `LengthOfArrayLike` abstract operation // https://tc39.es/ecma262/#sec-lengthofarraylike var lengthOfArrayLike$b = function (obj) { return toLength$4(obj.length); }; var toIndexedObject$8 = toIndexedObject$a; var toAbsoluteIndex$3 = toAbsoluteIndex$4; var lengthOfArrayLike$a = lengthOfArrayLike$b; // `Array.prototype.{ indexOf, includes }` methods implementation var createMethod$5 = function (IS_INCLUDES) { return function ($this, el, fromIndex) { var O = toIndexedObject$8($this); var length = lengthOfArrayLike$a(O); var index = toAbsoluteIndex$3(fromIndex, length); var value; // Array#includes uses SameValueZero equality algorithm // eslint-disable-next-line no-self-compare -- NaN check if (IS_INCLUDES && el != el) while (length > index) { value = O[index++]; // eslint-disable-next-line no-self-compare -- NaN check if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not } else for (;length > index; index++) { if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; } return !IS_INCLUDES && -1; }; }; var arrayIncludes = { // `Array.prototype.includes` method // https://tc39.es/ecma262/#sec-array.prototype.includes includes: createMethod$5(true), // `Array.prototype.indexOf` method // https://tc39.es/ecma262/#sec-array.prototype.indexof indexOf: createMethod$5(false) }; var uncurryThis$G = functionUncurryThis; var hasOwn$g = hasOwnProperty_1; var toIndexedObject$7 = toIndexedObject$a; var indexOf$1 = arrayIncludes.indexOf; var hiddenKeys$3 = hiddenKeys$5; var push$8 = uncurryThis$G([].push); var objectKeysInternal = function (object, names) { var O = toIndexedObject$7(object); var i = 0; var result = []; var key; for (key in O) !hasOwn$g(hiddenKeys$3, key) && hasOwn$g(O, key) && push$8(result, key); // Don't enum bug & hidden keys while (names.length > i) if (hasOwn$g(O, key = names[i++])) { ~indexOf$1(result, key) || push$8(result, key); } return result; }; // IE8- don't enum bug keys var enumBugKeys$3 = [ 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf' ]; var internalObjectKeys$1 = objectKeysInternal; var enumBugKeys$2 = enumBugKeys$3; var hiddenKeys$2 = enumBugKeys$2.concat('length', 'prototype'); // `Object.getOwnPropertyNames` method // https://tc39.es/ecma262/#sec-object.getownpropertynames // eslint-disable-next-line es/no-object-getownpropertynames -- safe objectGetOwnPropertyNames.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { return internalObjectKeys$1(O, hiddenKeys$2); }; var objectGetOwnPropertySymbols = {}; // eslint-disable-next-line es/no-object-getownpropertysymbols -- safe objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols; var getBuiltIn$c = getBuiltIn$e; var uncurryThis$F = functionUncurryThis; var getOwnPropertyNamesModule$1 = objectGetOwnPropertyNames; var getOwnPropertySymbolsModule$1 = objectGetOwnPropertySymbols; var anObject$j = anObject$l; var concat$3 = uncurryThis$F([].concat); // all object keys, includes non-enumerable and symbols var ownKeys$1 = getBuiltIn$c('Reflect', 'ownKeys') || function ownKeys(it) { var keys = getOwnPropertyNamesModule$1.f(anObject$j(it)); var getOwnPropertySymbols = getOwnPropertySymbolsModule$1.f; return getOwnPropertySymbols ? concat$3(keys, getOwnPropertySymbols(it)) : keys; }; var hasOwn$f = hasOwnProperty_1; var ownKeys = ownKeys$1; var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor; var definePropertyModule$2 = objectDefineProperty; var copyConstructorProperties$3 = function (target, source, exceptions) { var keys = ownKeys(source); var defineProperty = definePropertyModule$2.f; var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (!hasOwn$f(target, key) && !(exceptions && hasOwn$f(exceptions, key))) { defineProperty(target, key, getOwnPropertyDescriptor(source, key)); } } }; var fails$A = fails$I; var isCallable$k = isCallable$u; var replacement = /#|\.prototype\./; var isForced$4 = function (feature, detection) { var value = data[normalize(feature)]; return value == POLYFILL ? true : value == NATIVE ? false : isCallable$k(detection) ? fails$A(detection) : !!detection; }; var normalize = isForced$4.normalize = function (string) { return String(string).replace(replacement, '.').toLowerCase(); }; var data = isForced$4.data = {}; var NATIVE = isForced$4.NATIVE = 'N'; var POLYFILL = isForced$4.POLYFILL = 'P'; var isForced_1 = isForced$4; var global$p = global$y; var getOwnPropertyDescriptor$5 = objectGetOwnPropertyDescriptor.f; var createNonEnumerableProperty$7 = createNonEnumerableProperty$9; var defineBuiltIn$f = defineBuiltIn$g; var defineGlobalProperty = defineGlobalProperty$3; var copyConstructorProperties$2 = copyConstructorProperties$3; var isForced$3 = isForced_1; /* options.target - name of the target object options.global - target is the global object options.stat - export as static methods of target options.proto - export as prototype methods of target options.real - real prototype method for the `pure` version options.forced - export even if the native feature is available options.bind - bind methods to the target, required for the `pure` version options.wrap - wrap constructors to preventing global pollution, required for the `pure` version options.unsafe - use the simple assignment of property instead of delete + defineProperty options.sham - add a flag to not completely full polyfills options.enumerable - export as enumerable property options.dontCallGetSet - prevent calling a getter on target options.name - the .name of the function if it does not match the key */ var _export = function (options, source) { var TARGET = options.target; var GLOBAL = options.global; var STATIC = options.stat; var FORCED, target, key, targetProperty, sourceProperty, descriptor; if (GLOBAL) { target = global$p; } else if (STATIC) { target = global$p[TARGET] || defineGlobalProperty(TARGET, {}); } else { target = (global$p[TARGET] || {}).prototype; } if (target) for (key in source) { sourceProperty = source[key]; if (options.dontCallGetSet) { descriptor = getOwnPropertyDescriptor$5(target, key); targetProperty = descriptor && descriptor.value; } else targetProperty = target[key]; FORCED = isForced$3(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contained in target if (!FORCED && targetProperty !== undefined) { if (typeof sourceProperty == typeof targetProperty) continue; copyConstructorProperties$2(sourceProperty, targetProperty); } // add a flag to not completely full polyfills if (options.sham || (targetProperty && targetProperty.sham)) { createNonEnumerableProperty$7(sourceProperty, 'sham', true); } defineBuiltIn$f(target, key, sourceProperty, options); } }; var classofRaw$1 = classofRaw$2; var uncurryThis$E = functionUncurryThis; var functionUncurryThisClause = function (fn) { // Nashorn bug: // https://github.com/zloirock/core-js/issues/1128 // https://github.com/zloirock/core-js/issues/1130 if (classofRaw$1(fn) === 'Function') return uncurryThis$E(fn); }; var uncurryThis$D = functionUncurryThisClause; var aCallable$8 = aCallable$a; var NATIVE_BIND$2 = functionBindNative; var bind$a = uncurryThis$D(uncurryThis$D.bind); // optional / simple context binding var functionBindContext = function (fn, that) { aCallable$8(fn); return that === undefined ? fn : NATIVE_BIND$2 ? bind$a(fn, that) : function (/* ...args */) { return fn.apply(that, arguments); }; }; var classof$c = classofRaw$2; // `IsArray` abstract operation // https://tc39.es/ecma262/#sec-isarray // eslint-disable-next-line es/no-array-isarray -- safe var isArray$7 = Array.isArray || function isArray(argument) { return classof$c(argument) == 'Array'; }; var wellKnownSymbol$m = wellKnownSymbol$o; var TO_STRING_TAG$3 = wellKnownSymbol$m('toStringTag'); var test$1 = {}; test$1[TO_STRING_TAG$3] = 'z'; var toStringTagSupport = String(test$1) === '[object z]'; var TO_STRING_TAG_SUPPORT$2 = toStringTagSupport; var isCallable$j = isCallable$u; var classofRaw = classofRaw$2; var wellKnownSymbol$l = wellKnownSymbol$o; var TO_STRING_TAG$2 = wellKnownSymbol$l('toStringTag'); var $Object$2 = Object; // ES3 wrong here var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments'; // fallback for IE11 Script Access Denied error var tryGet = function (it, key) { try { return it[key]; } catch (error) { /* empty */ } }; // getting tag from ES6+ `Object.prototype.toString` var classof$b = TO_STRING_TAG_SUPPORT$2 ? classofRaw : function (it) { var O, tag, result; return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case : typeof (tag = tryGet(O = $Object$2(it), TO_STRING_TAG$2)) == 'string' ? tag // builtinTag case : CORRECT_ARGUMENTS ? classofRaw(O) // ES3 arguments fallback : (result = classofRaw(O)) == 'Object' && isCallable$j(O.callee) ? 'Arguments' : result; }; var uncurryThis$C = functionUncurryThis; var fails$z = fails$I; var isCallable$i = isCallable$u; var classof$a = classof$b; var getBuiltIn$b = getBuiltIn$e; var inspectSource$1 = inspectSource$3; var noop = function () { /* empty */ }; var empty = []; var construct$1 = getBuiltIn$b('Reflect', 'construct'); var constructorRegExp = /^\s*(?:class|function)\b/; var exec$6 = uncurryThis$C(constructorRegExp.exec); var INCORRECT_TO_STRING$2 = !constructorRegExp.exec(noop); var isConstructorModern = function isConstructor(argument) { if (!isCallable$i(argument)) return false; try { construct$1(noop, empty, argument); return true; } catch (error) { return false; } }; var isConstructorLegacy = function isConstructor(argument) { if (!isCallable$i(argument)) return false; switch (classof$a(argument)) { case 'AsyncFunction': case 'GeneratorFunction': case 'AsyncGeneratorFunction': return false; } try { // we can't check .prototype since constructors produced by .bind haven't it // `Function#toString` throws on some built-it function in some legacy engines // (for example, `DOMQuad` and similar in FF41-) return INCORRECT_TO_STRING$2 || !!exec$6(constructorRegExp, inspectSource$1(argument)); } catch (error) { return true; } }; isConstructorLegacy.sham = true; // `IsConstructor` abstract operation // https://tc39.es/ecma262/#sec-isconstructor var isConstructor$4 = !construct$1 || fails$z(function () { var called; return isConstructorModern(isConstructorModern.call) || !isConstructorModern(Object) || !isConstructorModern(function () { called = true; }) || called; }) ? isConstructorLegacy : isConstructorModern; var isArray$6 = isArray$7; var isConstructor$3 = isConstructor$4; var isObject$f = isObject$l; var wellKnownSymbol$k = wellKnownSymbol$o; var SPECIES$6 = wellKnownSymbol$k('species'); var $Array$3 = Array; // a part of `ArraySpeciesCreate` abstract operation // https://tc39.es/ecma262/#sec-arrayspeciescreate var arraySpeciesConstructor$1 = function (originalArray) { var C; if (isArray$6(originalArray)) { C = originalArray.constructor; // cross-realm fallback if (isConstructor$3(C) && (C === $Array$3 || isArray$6(C.prototype))) C = undefined; else if (isObject$f(C)) { C = C[SPECIES$6]; if (C === null) C = undefined; } } return C === undefined ? $Array$3 : C; }; var arraySpeciesConstructor = arraySpeciesConstructor$1; // `ArraySpeciesCreate` abstract operation // https://tc39.es/ecma262/#sec-arrayspeciescreate var arraySpeciesCreate$3 = function (originalArray, length) { return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); }; var bind$9 = functionBindContext; var uncurryThis$B = functionUncurryThis; var IndexedObject$2 = indexedObject; var toObject$9 = toObject$b; var lengthOfArrayLike$9 = lengthOfArrayLike$b; var arraySpeciesCreate$2 = arraySpeciesCreate$3; var push$7 = uncurryThis$B([].push); // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation var createMethod$4 = function (TYPE) { var IS_MAP = TYPE == 1; var IS_FILTER = TYPE == 2; var IS_SOME = TYPE == 3; var IS_EVERY = TYPE == 4; var IS_FIND_INDEX = TYPE == 6; var IS_FILTER_REJECT = TYPE == 7; var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; return function ($this, callbackfn, that, specificCreate) { var O = toObject$9($this); var self = IndexedObject$2(O); var boundFunction = bind$9(callbackfn, that); var length = lengthOfArrayLike$9(self); var index = 0; var create = specificCreate || arraySpeciesCreate$2; var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined; var value, result; for (;length > index; index++) if (NO_HOLES || index in self) { value = self[index]; result = boundFunction(value, index, O); if (TYPE) { if (IS_MAP) target[index] = result; // map else if (result) switch (TYPE) { case 3: return true; // some case 5: return value; // find case 6: return index; // findIndex case 2: push$7(target, value); // filter } else switch (TYPE) { case 4: return false; // every case 7: push$7(target, value); // filterReject } } } return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target; }; }; var arrayIteration = { // `Array.prototype.forEach` method // https://tc39.es/ecma262/#sec-array.prototype.foreach forEach: createMethod$4(0), // `Array.prototype.map` method // https://tc39.es/ecma262/#sec-array.prototype.map map: createMethod$4(1), // `Array.prototype.filter` method // https://tc39.es/ecma262/#sec-array.prototype.filter filter: createMethod$4(2), // `Array.prototype.some` method // https://tc39.es/ecma262/#sec-array.prototype.some some: createMethod$4(3), // `Array.prototype.every` method // https://tc39.es/ecma262/#sec-array.prototype.every every: createMethod$4(4), // `Array.prototype.find` method // https://tc39.es/ecma262/#sec-array.prototype.find find: createMethod$4(5), // `Array.prototype.findIndex` method // https://tc39.es/ecma262/#sec-array.prototype.findIndex findIndex: createMethod$4(6), // `Array.prototype.filterReject` method // https://github.com/tc39/proposal-array-filtering filterReject: createMethod$4(7) }; var fails$y = fails$I; var arrayMethodIsStrict$7 = function (METHOD_NAME, argument) { var method = [][METHOD_NAME]; return !!method && fails$y(function () { // eslint-disable-next-line no-useless-call -- required for testing method.call(null, argument || function () { return 1; }, 1); }); }; var $forEach = arrayIteration.forEach; var arrayMethodIsStrict$6 = arrayMethodIsStrict$7; var STRICT_METHOD$4 = arrayMethodIsStrict$6('forEach'); // `Array.prototype.forEach` method implementation // https://tc39.es/ecma262/#sec-array.prototype.foreach var arrayForEach = !STRICT_METHOD$4 ? function forEach(callbackfn /* , thisArg */) { return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); // eslint-disable-next-line es/no-array-prototype-foreach -- safe } : [].forEach; var $$U = _export; var forEach$1 = arrayForEach; // `Array.prototype.forEach` method // https://tc39.es/ecma262/#sec-array.prototype.foreach // eslint-disable-next-line es/no-array-prototype-foreach -- safe $$U({ target: 'Array', proto: true, forced: [].forEach != forEach$1 }, { forEach: forEach$1 }); var TO_STRING_TAG_SUPPORT$1 = toStringTagSupport; var classof$9 = classof$b; // `Object.prototype.toString` method implementation // https://tc39.es/ecma262/#sec-object.prototype.tostring var objectToString = TO_STRING_TAG_SUPPORT$1 ? {}.toString : function toString() { return '[object ' + classof$9(this) + ']'; }; var TO_STRING_TAG_SUPPORT = toStringTagSupport; var defineBuiltIn$e = defineBuiltIn$g; var toString$j = objectToString; // `Object.prototype.toString` method // https://tc39.es/ecma262/#sec-object.prototype.tostring if (!TO_STRING_TAG_SUPPORT) { defineBuiltIn$e(Object.prototype, 'toString', toString$j, { unsafe: true }); } // iterable DOM collections // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods var domIterables = { CSSRuleList: 0, CSSStyleDeclaration: 0, CSSValueList: 0, ClientRectList: 0, DOMRectList: 0, DOMStringList: 0, DOMTokenList: 1, DataTransferItemList: 0, FileList: 0, HTMLAllCollection: 0, HTMLCollection: 0, HTMLFormElement: 0, HTMLSelectElement: 0, MediaList: 0, MimeTypeArray: 0, NamedNodeMap: 0, NodeList: 1, PaintRequestList: 0, Plugin: 0, PluginArray: 0, SVGLengthList: 0, SVGNumberList: 0, SVGPathSegList: 0, SVGPointList: 0, SVGStringList: 0, SVGTransformList: 0, SourceBufferList: 0, StyleSheetList: 0, TextTrackCueList: 0, TextTrackList: 0, TouchList: 0 }; // in old WebKit versions, `element.classList` is not an instance of global `DOMTokenList` var documentCreateElement$1 = documentCreateElement$2; var classList = documentCreateElement$1('span').classList; var DOMTokenListPrototype$2 = classList && classList.constructor && classList.constructor.prototype; var domTokenListPrototype = DOMTokenListPrototype$2 === Object.prototype ? undefined : DOMTokenListPrototype$2; var global$o = global$y; var DOMIterables$1 = domIterables; var DOMTokenListPrototype$1 = domTokenListPrototype; var forEach = arrayForEach; var createNonEnumerableProperty$6 = createNonEnumerableProperty$9; var handlePrototype$1 = function (CollectionPrototype) { // some Chrome versions have non-configurable methods on DOMTokenList if (CollectionPrototype && CollectionPrototype.forEach !== forEach) try { createNonEnumerableProperty$6(CollectionPrototype, 'forEach', forEach); } catch (error) { CollectionPrototype.forEach = forEach; } }; for (var COLLECTION_NAME$1 in DOMIterables$1) { if (DOMIterables$1[COLLECTION_NAME$1]) { handlePrototype$1(global$o[COLLECTION_NAME$1] && global$o[COLLECTION_NAME$1].prototype); } } handlePrototype$1(DOMTokenListPrototype$1); var uncurryThis$A = functionUncurryThis; var arraySlice$7 = uncurryThis$A([].slice); var uncurryThis$z = functionUncurryThis; var aCallable$7 = aCallable$a; var isObject$e = isObject$l; var hasOwn$e = hasOwnProperty_1; var arraySlice$6 = arraySlice$7; var NATIVE_BIND$1 = functionBindNative; var $Function = Function; var concat$2 = uncurryThis$z([].concat); var join$3 = uncurryThis$z([].join); var factories = {}; var construct = function (C, argsLength, args) { if (!hasOwn$e(factories, argsLength)) { for (var list = [], i = 0; i < argsLength; i++) list[i] = 'a[' + i + ']'; factories[argsLength] = $Function('C,a', 'return new C(' + join$3(list, ',') + ')'); } return factories[argsLength](C, args); }; // `Function.prototype.bind` method implementation // https://tc39.es/ecma262/#sec-function.prototype.bind // eslint-disable-next-line es/no-function-prototype-bind -- detection var functionBind = NATIVE_BIND$1 ? $Function.bind : function bind(that /* , ...args */) { var F = aCallable$7(this); var Prototype = F.prototype; var partArgs = arraySlice$6(arguments, 1); var boundFunction = function bound(/* args... */) { var args = concat$2(partArgs, arraySlice$6(arguments)); return this instanceof boundFunction ? construct(F, args.length, args) : F.apply(that, args); }; if (isObject$e(Prototype)) boundFunction.prototype = Prototype; return boundFunction; }; // TODO: Remove from `core-js@4` var $$T = _export; var bind$8 = functionBind; // `Function.prototype.bind` method // https://tc39.es/ecma262/#sec-function.prototype.bind // eslint-disable-next-line es/no-function-prototype-bind -- detection $$T({ target: 'Function', proto: true, forced: Function.bind !== bind$8 }, { bind: bind$8 }); var classof$8 = classof$b; var $String$2 = String; var toString$i = function (argument) { if (classof$8(argument) === 'Symbol') throw TypeError('Cannot convert a Symbol value to a string'); return $String$2(argument); }; // a string of all valid unicode whitespaces var whitespaces$5 = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; var uncurryThis$y = functionUncurryThis; var requireObjectCoercible$8 = requireObjectCoercible$b; var toString$h = toString$i; var whitespaces$4 = whitespaces$5; var replace$9 = uncurryThis$y(''.replace); var ltrim = RegExp('^[' + whitespaces$4 + ']+'); var rtrim = RegExp('(^|[^' + whitespaces$4 + '])[' + whitespaces$4 + ']+$'); // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation var createMethod$3 = function (TYPE) { return function ($this) { var string = toString$h(requireObjectCoercible$8($this)); if (TYPE & 1) string = replace$9(string, ltrim, ''); if (TYPE & 2) string = replace$9(string, rtrim, '$1'); return string; }; }; var stringTrim = { // `String.prototype.{ trimLeft, trimStart }` methods // https://tc39.es/ecma262/#sec-string.prototype.trimstart start: createMethod$3(1), // `String.prototype.{ trimRight, trimEnd }` methods // https://tc39.es/ecma262/#sec-string.prototype.trimend end: createMethod$3(2), // `String.prototype.trim` method // https://tc39.es/ecma262/#sec-string.prototype.trim trim: createMethod$3(3) }; var global$n = global$y; var fails$x = fails$I; var uncurryThis$x = functionUncurryThis; var toString$g = toString$i; var trim$2 = stringTrim.trim; var whitespaces$3 = whitespaces$5; var $parseInt$1 = global$n.parseInt; var Symbol$2 = global$n.Symbol; var ITERATOR$9 = Symbol$2 && Symbol$2.iterator; var hex = /^[+-]?0x/i; var exec$5 = uncurryThis$x(hex.exec); var FORCED$9 = $parseInt$1(whitespaces$3 + '08') !== 8 || $parseInt$1(whitespaces$3 + '0x16') !== 22 // MS Edge 18- broken with boxed symbols || (ITERATOR$9 && !fails$x(function () { $parseInt$1(Object(ITERATOR$9)); })); // `parseInt` method // https://tc39.es/ecma262/#sec-parseint-string-radix var numberParseInt = FORCED$9 ? function parseInt(string, radix) { var S = trim$2(toString$g(string)); return $parseInt$1(S, (radix >>> 0) || (exec$5(hex, S) ? 16 : 10)); } : $parseInt$1; var $$S = _export; var $parseInt = numberParseInt; // `parseInt` method // https://tc39.es/ecma262/#sec-parseint-string-radix $$S({ global: true, forced: parseInt != $parseInt }, { parseInt: $parseInt }); var fails$w = fails$I; var wellKnownSymbol$j = wellKnownSymbol$o; var V8_VERSION$2 = engineV8Version; var SPECIES$5 = wellKnownSymbol$j('species'); var arrayMethodHasSpeciesSupport$5 = function (METHOD_NAME) { // We can't use this feature detection in V8 since it causes // deoptimization and serious performance degradation // https://github.com/zloirock/core-js/issues/677 return V8_VERSION$2 >= 51 || !fails$w(function () { var array = []; var constructor = array.constructor = {}; constructor[SPECIES$5] = function () { return { foo: 1 }; }; return array[METHOD_NAME](Boolean).foo !== 1; }); }; var $$R = _export; var $filter = arrayIteration.filter; var arrayMethodHasSpeciesSupport$4 = arrayMethodHasSpeciesSupport$5; var HAS_SPECIES_SUPPORT$3 = arrayMethodHasSpeciesSupport$4('filter'); // `Array.prototype.filter` method // https://tc39.es/ecma262/#sec-array.prototype.filter // with adding support of @@species $$R({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$3 }, { filter: function filter(callbackfn /* , thisArg */) { return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); var internalObjectKeys = objectKeysInternal; var enumBugKeys$1 = enumBugKeys$3; // `Object.keys` method // https://tc39.es/ecma262/#sec-object.keys // eslint-disable-next-line es/no-object-keys -- safe var objectKeys$3 = Object.keys || function keys(O) { return internalObjectKeys(O, enumBugKeys$1); }; var $$Q = _export; var toObject$8 = toObject$b; var nativeKeys = objectKeys$3; var fails$v = fails$I; var FAILS_ON_PRIMITIVES$1 = fails$v(function () { nativeKeys(1); }); // `Object.keys` method // https://tc39.es/ecma262/#sec-object.keys $$Q({ target: 'Object', stat: true, forced: FAILS_ON_PRIMITIVES$1 }, { keys: function keys(it) { return nativeKeys(toObject$8(it)); } }); var global$m = global$y; var path$1 = global$m; var uncurryThis$w = functionUncurryThis; var aCallable$6 = aCallable$a; var functionUncurryThisAccessor = function (object, key, method) { try { // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe return uncurryThis$w(aCallable$6(Object.getOwnPropertyDescriptor(object, key)[method])); } catch (error) { /* empty */ } }; var isCallable$h = isCallable$u; var $String$1 = String; var $TypeError$b = TypeError; var aPossiblePrototype$1 = function (argument) { if (typeof argument == 'object' || isCallable$h(argument)) return argument; throw $TypeError$b("Can't set " + $String$1(argument) + ' as a prototype'); }; /* eslint-disable no-proto -- safe */ var uncurryThisAccessor = functionUncurryThisAccessor; var anObject$i = anObject$l; var aPossiblePrototype = aPossiblePrototype$1; // `Object.setPrototypeOf` method // https://tc39.es/ecma262/#sec-object.setprototypeof // Works with __proto__ only. Old v8 can't work with null proto objects. // eslint-disable-next-line es/no-object-setprototypeof -- safe var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () { var CORRECT_SETTER = false; var test = {}; var setter; try { setter = uncurryThisAccessor(Object.prototype, '__proto__', 'set'); setter(test, []); CORRECT_SETTER = test instanceof Array; } catch (error) { /* empty */ } return function setPrototypeOf(O, proto) { anObject$i(O); aPossiblePrototype(proto); if (CORRECT_SETTER) setter(O, proto); else O.__proto__ = proto; return O; }; }() : undefined); var isCallable$g = isCallable$u; var isObject$d = isObject$l; var setPrototypeOf$3 = objectSetPrototypeOf; // makes subclassing work correct for wrapped built-ins var inheritIfRequired$4 = function ($this, dummy, Wrapper) { var NewTarget, NewTargetPrototype; if ( // it can work only with native `setPrototypeOf` setPrototypeOf$3 && // we haven't completely correct pre-ES6 way for getting `new.target`, so use this isCallable$g(NewTarget = dummy.constructor) && NewTarget !== Wrapper && isObject$d(NewTargetPrototype = NewTarget.prototype) && NewTargetPrototype !== Wrapper.prototype ) setPrototypeOf$3($this, NewTargetPrototype); return $this; }; var uncurryThis$v = functionUncurryThis; // `thisNumberValue` abstract operation // https://tc39.es/ecma262/#sec-thisnumbervalue var thisNumberValue$1 = uncurryThis$v(1.0.valueOf); var $$P = _export; var IS_PURE$1 = isPure; var DESCRIPTORS$h = descriptors; var global$l = global$y; var path = path$1; var uncurryThis$u = functionUncurryThis; var isForced$2 = isForced_1; var hasOwn$d = hasOwnProperty_1; var inheritIfRequired$3 = inheritIfRequired$4; var isPrototypeOf$4 = objectIsPrototypeOf; var isSymbol$1 = isSymbol$4; var toPrimitive = toPrimitive$2; var fails$u = fails$I; var getOwnPropertyNames = objectGetOwnPropertyNames.f; var getOwnPropertyDescriptor$4 = objectGetOwnPropertyDescriptor.f; var defineProperty$a = objectDefineProperty.f; var thisNumberValue = thisNumberValue$1; var trim$1 = stringTrim.trim; var NUMBER = 'Number'; var NativeNumber = global$l[NUMBER]; path[NUMBER]; var NumberPrototype = NativeNumber.prototype; var TypeError$4 = global$l.TypeError; var stringSlice$8 = uncurryThis$u(''.slice); var charCodeAt$3 = uncurryThis$u(''.charCodeAt); // `ToNumeric` abstract operation // https://tc39.es/ecma262/#sec-tonumeric var toNumeric = function (value) { var primValue = toPrimitive(value, 'number'); return typeof primValue == 'bigint' ? primValue : toNumber(primValue); }; // `ToNumber` abstract operation // https://tc39.es/ecma262/#sec-tonumber var toNumber = function (argument) { var it = toPrimitive(argument, 'number'); var first, third, radix, maxCode, digits, length, index, code; if (isSymbol$1(it)) throw TypeError$4('Cannot convert a Symbol value to a number'); if (typeof it == 'string' && it.length > 2) { it = trim$1(it); first = charCodeAt$3(it, 0); if (first === 43 || first === 45) { third = charCodeAt$3(it, 2); if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix } else if (first === 48) { switch (charCodeAt$3(it, 1)) { case 66: case 98: radix = 2; maxCode = 49; break; // fast equal of /^0b[01]+$/i case 79: case 111: radix = 8; maxCode = 55; break; // fast equal of /^0o[0-7]+$/i default: return +it; } digits = stringSlice$8(it, 2); length = digits.length; for (index = 0; index < length; index++) { code = charCodeAt$3(digits, index); // parseInt parses a string to a first unavailable symbol // but ToNumber should return NaN if a string contains unavailable symbols if (code < 48 || code > maxCode) return NaN; } return parseInt(digits, radix); } } return +it; }; var FORCED$8 = isForced$2(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1')); var calledWithNew = function (dummy) { // includes check on 1..constructor(foo) case return isPrototypeOf$4(NumberPrototype, dummy) && fails$u(function () { thisNumberValue(dummy); }); }; // `Number` constructor // https://tc39.es/ecma262/#sec-number-constructor var NumberWrapper = function Number(value) { var n = arguments.length < 1 ? 0 : NativeNumber(toNumeric(value)); return calledWithNew(this) ? inheritIfRequired$3(Object(n), this, NumberWrapper) : n; }; NumberWrapper.prototype = NumberPrototype; if (FORCED$8 && !IS_PURE$1) NumberPrototype.constructor = NumberWrapper; $$P({ global: true, constructor: true, wrap: true, forced: FORCED$8 }, { Number: NumberWrapper }); // Use `internal/copy-constructor-properties` helper in `core-js@4` var copyConstructorProperties$1 = function (target, source) { for (var keys = DESCRIPTORS$h ? getOwnPropertyNames(source) : ( // ES3: 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES2015 (in case, if modules with ES2015 Number statics required before): 'EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,' + // ESNext 'fromString,range' ).split(','), j = 0, key; keys.length > j; j++) { if (hasOwn$d(source, key = keys[j]) && !hasOwn$d(target, key)) { defineProperty$a(target, key, getOwnPropertyDescriptor$4(source, key)); } } }; if (FORCED$8 || IS_PURE$1) copyConstructorProperties$1(path[NUMBER], NativeNumber); var DESCRIPTORS$g = descriptors; var isArray$5 = isArray$7; var $TypeError$a = TypeError; // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe var getOwnPropertyDescriptor$3 = Object.getOwnPropertyDescriptor; // Safari < 13 does not throw an error in this case var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS$g && !function () { // makes no sense without proper strict mode support if (this !== undefined) return true; try { // eslint-disable-next-line es/no-object-defineproperty -- safe Object.defineProperty([], 'length', { writable: false }).length = 1; } catch (error) { return error instanceof TypeError; } }(); var arraySetLength = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { if (isArray$5(O) && !getOwnPropertyDescriptor$3(O, 'length').writable) { throw $TypeError$a('Cannot set read only .length'); } return O.length = length; } : function (O, length) { return O.length = length; }; var $TypeError$9 = TypeError; var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 var doesNotExceedSafeInteger$3 = function (it) { if (it > MAX_SAFE_INTEGER) throw $TypeError$9('Maximum allowed index exceeded'); return it; }; var $$O = _export; var toObject$7 = toObject$b; var lengthOfArrayLike$8 = lengthOfArrayLike$b; var setArrayLength$1 = arraySetLength; var doesNotExceedSafeInteger$2 = doesNotExceedSafeInteger$3; var fails$t = fails$I; var INCORRECT_TO_LENGTH = fails$t(function () { return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; }); // V8 and Safari <= 15.4, FF < 23 throws InternalError // https://bugs.chromium.org/p/v8/issues/detail?id=12681 var properErrorOnNonWritableLength = function () { try { // eslint-disable-next-line es/no-object-defineproperty -- safe Object.defineProperty([], 'length', { writable: false }).push(); } catch (error) { return error instanceof TypeError; } }; var FORCED$7 = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); // `Array.prototype.push` method // https://tc39.es/ecma262/#sec-array.prototype.push $$O({ target: 'Array', proto: true, arity: 1, forced: FORCED$7 }, { // eslint-disable-next-line no-unused-vars -- required for `.length` push: function push(item) { var O = toObject$7(this); var len = lengthOfArrayLike$8(O); var argCount = arguments.length; doesNotExceedSafeInteger$2(len + argCount); for (var i = 0; i < argCount; i++) { O[len] = arguments[i]; len++; } setArrayLength$1(O, len); return len; } }); var DESCRIPTORS$f = descriptors; var uncurryThis$t = functionUncurryThis; var call$j = functionCall; var fails$s = fails$I; var objectKeys$2 = objectKeys$3; var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols; var propertyIsEnumerableModule = objectPropertyIsEnumerable; var toObject$6 = toObject$b; var IndexedObject$1 = indexedObject; // eslint-disable-next-line es/no-object-assign -- safe var $assign = Object.assign; // eslint-disable-next-line es/no-object-defineproperty -- required for testing var defineProperty$9 = Object.defineProperty; var concat$1 = uncurryThis$t([].concat); // `Object.assign` method // https://tc39.es/ecma262/#sec-object.assign var objectAssign = !$assign || fails$s(function () { // should have correct order of operations (Edge bug) if (DESCRIPTORS$f && $assign({ b: 1 }, $assign(defineProperty$9({}, 'a', { enumerable: true, get: function () { defineProperty$9(this, 'b', { value: 3, enumerable: false }); } }), { b: 2 })).b !== 1) return true; // should work with symbols and should have deterministic property order (V8 bug) var A = {}; var B = {}; // eslint-disable-next-line es/no-symbol -- safe var symbol = Symbol(); var alphabet = 'abcdefghijklmnopqrst'; A[symbol] = 7; alphabet.split('').forEach(function (chr) { B[chr] = chr; }); return $assign({}, A)[symbol] != 7 || objectKeys$2($assign({}, B)).join('') != alphabet; }) ? function assign(target, source) { // eslint-disable-line no-unused-vars -- required for `.length` var T = toObject$6(target); var argumentsLength = arguments.length; var index = 1; var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; var propertyIsEnumerable = propertyIsEnumerableModule.f; while (argumentsLength > index) { var S = IndexedObject$1(arguments[index++]); var keys = getOwnPropertySymbols ? concat$1(objectKeys$2(S), getOwnPropertySymbols(S)) : objectKeys$2(S); var length = keys.length; var j = 0; var key; while (length > j) { key = keys[j++]; if (!DESCRIPTORS$f || call$j(propertyIsEnumerable, S, key)) T[key] = S[key]; } } return T; } : $assign; var $$N = _export; var assign$1 = objectAssign; // `Object.assign` method // https://tc39.es/ecma262/#sec-object.assign // eslint-disable-next-line es/no-object-assign -- required for testing $$N({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== assign$1 }, { assign: assign$1 }); var anObject$h = anObject$l; // `RegExp.prototype.flags` getter implementation // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags var regexpFlags$1 = function () { var that = anObject$h(this); var result = ''; if (that.hasIndices) result += 'd'; if (that.global) result += 'g'; if (that.ignoreCase) result += 'i'; if (that.multiline) result += 'm'; if (that.dotAll) result += 's'; if (that.unicode) result += 'u'; if (that.unicodeSets) result += 'v'; if (that.sticky) result += 'y'; return result; }; var fails$r = fails$I; var global$k = global$y; // babel-minify and Closure Compiler transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError var $RegExp$2 = global$k.RegExp; var UNSUPPORTED_Y$1 = fails$r(function () { var re = $RegExp$2('a', 'y'); re.lastIndex = 2; return re.exec('abcd') != null; }); // UC Browser bug // https://github.com/zloirock/core-js/issues/1008 var MISSED_STICKY = UNSUPPORTED_Y$1 || fails$r(function () { return !$RegExp$2('a', 'y').sticky; }); var BROKEN_CARET = UNSUPPORTED_Y$1 || fails$r(function () { // https://bugzilla.mozilla.org/show_bug.cgi?id=773687 var re = $RegExp$2('^r', 'gy'); re.lastIndex = 2; return re.exec('str') != null; }); var regexpStickyHelpers = { BROKEN_CARET: BROKEN_CARET, MISSED_STICKY: MISSED_STICKY, UNSUPPORTED_Y: UNSUPPORTED_Y$1 }; var objectDefineProperties = {}; var DESCRIPTORS$e = descriptors; var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug; var definePropertyModule$1 = objectDefineProperty; var anObject$g = anObject$l; var toIndexedObject$6 = toIndexedObject$a; var objectKeys$1 = objectKeys$3; // `Object.defineProperties` method // https://tc39.es/ecma262/#sec-object.defineproperties // eslint-disable-next-line es/no-object-defineproperties -- safe objectDefineProperties.f = DESCRIPTORS$e && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) { anObject$g(O); var props = toIndexedObject$6(Properties); var keys = objectKeys$1(Properties); var length = keys.length; var index = 0; var key; while (length > index) definePropertyModule$1.f(O, key = keys[index++], props[key]); return O; }; var getBuiltIn$a = getBuiltIn$e; var html$2 = getBuiltIn$a('document', 'documentElement'); /* global ActiveXObject -- old IE, WSH */ var anObject$f = anObject$l; var definePropertiesModule = objectDefineProperties; var enumBugKeys = enumBugKeys$3; var hiddenKeys$1 = hiddenKeys$5; var html$1 = html$2; var documentCreateElement = documentCreateElement$2; var sharedKey$1 = sharedKey$3; var GT = '>'; var LT = '<'; var PROTOTYPE = 'prototype'; var SCRIPT = 'script'; var IE_PROTO$1 = sharedKey$1('IE_PROTO'); var EmptyConstructor = function () { /* empty */ }; var scriptTag = function (content) { return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; }; // Create object with fake `null` prototype: use ActiveX Object with cleared prototype var NullProtoObjectViaActiveX = function (activeXDocument) { activeXDocument.write(scriptTag('')); activeXDocument.close(); var temp = activeXDocument.parentWindow.Object; activeXDocument = null; // avoid memory leak return temp; }; // Create object with fake `null` prototype: use iframe Object with cleared prototype var NullProtoObjectViaIFrame = function () { // Thrash, waste and sodomy: IE GC bug var iframe = documentCreateElement('iframe'); var JS = 'java' + SCRIPT + ':'; var iframeDocument; iframe.style.display = 'none'; html$1.appendChild(iframe); // https://github.com/zloirock/core-js/issues/475 iframe.src = String(JS); iframeDocument = iframe.contentWindow.document; iframeDocument.open(); iframeDocument.write(scriptTag('document.F=Object')); iframeDocument.close(); return iframeDocument.F; }; // Check for document.domain and active x support // No need to use active x approach when document.domain is not set // see https://github.com/es-shims/es5-shim/issues/150 // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 // avoid IE GC bug var activeXDocument; var NullProtoObject = function () { try { activeXDocument = new ActiveXObject('htmlfile'); } catch (error) { /* ignore */ } NullProtoObject = typeof document != 'undefined' ? document.domain && activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) // old IE : NullProtoObjectViaIFrame() : NullProtoObjectViaActiveX(activeXDocument); // WSH var length = enumBugKeys.length; while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; return NullProtoObject(); }; hiddenKeys$1[IE_PROTO$1] = true; // `Object.create` method // https://tc39.es/ecma262/#sec-object.create // eslint-disable-next-line es/no-object-create -- safe var objectCreate = Object.create || function create(O, Properties) { var result; if (O !== null) { EmptyConstructor[PROTOTYPE] = anObject$f(O); result = new EmptyConstructor(); EmptyConstructor[PROTOTYPE] = null; // add "__proto__" for Object.getPrototypeOf polyfill result[IE_PROTO$1] = O; } else result = NullProtoObject(); return Properties === undefined ? result : definePropertiesModule.f(result, Properties); }; var fails$q = fails$I; var global$j = global$y; // babel-minify and Closure Compiler transpiles RegExp('.', 's') -> /./s and it causes SyntaxError var $RegExp$1 = global$j.RegExp; var regexpUnsupportedDotAll = fails$q(function () { var re = $RegExp$1('.', 's'); return !(re.dotAll && re.exec('\n') && re.flags === 's'); }); var fails$p = fails$I; var global$i = global$y; // babel-minify and Closure Compiler transpiles RegExp('(?b)', 'g') -> /(?b)/g and it causes SyntaxError var $RegExp = global$i.RegExp; var regexpUnsupportedNcg = fails$p(function () { var re = $RegExp('(?b)', 'g'); return re.exec('b').groups.a !== 'b' || 'b'.replace(re, '$c') !== 'bc'; }); /* eslint-disable regexp/no-empty-capturing-group, regexp/no-empty-group, regexp/no-lazy-ends -- testing */ /* eslint-disable regexp/no-useless-quantifier -- testing */ var call$i = functionCall; var uncurryThis$s = functionUncurryThis; var toString$f = toString$i; var regexpFlags = regexpFlags$1; var stickyHelpers = regexpStickyHelpers; var shared = sharedExports; var create$7 = objectCreate; var getInternalState$3 = internalState.get; var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll; var UNSUPPORTED_NCG = regexpUnsupportedNcg; var nativeReplace = shared('native-string-replace', String.prototype.replace); var nativeExec = RegExp.prototype.exec; var patchedExec = nativeExec; var charAt$9 = uncurryThis$s(''.charAt); var indexOf = uncurryThis$s(''.indexOf); var replace$8 = uncurryThis$s(''.replace); var stringSlice$7 = uncurryThis$s(''.slice); var UPDATES_LAST_INDEX_WRONG = (function () { var re1 = /a/; var re2 = /b*/g; call$i(nativeExec, re1, 'a'); call$i(nativeExec, re2, 'a'); return re1.lastIndex !== 0 || re2.lastIndex !== 0; })(); var UNSUPPORTED_Y = stickyHelpers.BROKEN_CARET; // nonparticipating capturing group, copied from es5-shim's String#split patch. var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined; var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG; if (PATCH) { patchedExec = function exec(string) { var re = this; var state = getInternalState$3(re); var str = toString$f(string); var raw = state.raw; var result, reCopy, lastIndex, match, i, object, group; if (raw) { raw.lastIndex = re.lastIndex; result = call$i(patchedExec, raw, str); re.lastIndex = raw.lastIndex; return result; } var groups = state.groups; var sticky = UNSUPPORTED_Y && re.sticky; var flags = call$i(regexpFlags, re); var source = re.source; var charsAdded = 0; var strCopy = str; if (sticky) { flags = replace$8(flags, 'y', ''); if (indexOf(flags, 'g') === -1) { flags += 'g'; } strCopy = stringSlice$7(str, re.lastIndex); // Support anchored sticky behavior. if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt$9(str, re.lastIndex - 1) !== '\n')) { source = '(?: ' + source + ')'; strCopy = ' ' + strCopy; charsAdded++; } // ^(? + rx + ) is needed, in combination with some str slicing, to // simulate the 'y' flag. reCopy = new RegExp('^(?:' + source + ')', flags); } if (NPCG_INCLUDED) { reCopy = new RegExp('^' + source + '$(?!\\s)', flags); } if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex; match = call$i(nativeExec, sticky ? reCopy : re, strCopy); if (sticky) { if (match) { match.input = stringSlice$7(match.input, charsAdded); match[0] = stringSlice$7(match[0], charsAdded); match.index = re.lastIndex; re.lastIndex += match[0].length; } else re.lastIndex = 0; } else if (UPDATES_LAST_INDEX_WRONG && match) { re.lastIndex = re.global ? match.index + match[0].length : lastIndex; } if (NPCG_INCLUDED && match && match.length > 1) { // Fix browsers whose `exec` methods don't consistently return `undefined` // for NPCG, like IE8. NOTE: This doesn't work for /(.?)?/ call$i(nativeReplace, match[0], reCopy, function () { for (i = 1; i < arguments.length - 2; i++) { if (arguments[i] === undefined) match[i] = undefined; } }); } if (match && groups) { match.groups = object = create$7(null); for (i = 0; i < groups.length; i++) { group = groups[i]; object[group[0]] = match[group[1]]; } } return match; }; } var regexpExec$2 = patchedExec; var $$M = _export; var exec$4 = regexpExec$2; // `RegExp.prototype.exec` method // https://tc39.es/ecma262/#sec-regexp.prototype.exec $$M({ target: 'RegExp', proto: true, forced: /./.exec !== exec$4 }, { exec: exec$4 }); // TODO: Remove from `core-js@4` since it's moved to entry points var $$L = _export; var call$h = functionCall; var isCallable$f = isCallable$u; var anObject$e = anObject$l; var toString$e = toString$i; var DELEGATES_TO_EXEC = function () { var execCalled = false; var re = /[ac]/; re.exec = function () { execCalled = true; return /./.exec.apply(this, arguments); }; return re.test('abc') === true && execCalled; }(); var nativeTest = /./.test; // `RegExp.prototype.test` method // https://tc39.es/ecma262/#sec-regexp.prototype.test $$L({ target: 'RegExp', proto: true, forced: !DELEGATES_TO_EXEC }, { test: function (S) { var R = anObject$e(this); var string = toString$e(S); var exec = R.exec; if (!isCallable$f(exec)) return call$h(nativeTest, R, string); var result = call$h(exec, R, string); if (result === null) return false; anObject$e(result); return true; } }); var toPropertyKey = toPropertyKey$3; var definePropertyModule = objectDefineProperty; var createPropertyDescriptor$5 = createPropertyDescriptor$8; var createProperty$5 = function (object, key, value) { var propertyKey = toPropertyKey(key); if (propertyKey in object) definePropertyModule.f(object, propertyKey, createPropertyDescriptor$5(0, value)); else object[propertyKey] = value; }; var $$K = _export; var isArray$4 = isArray$7; var isConstructor$2 = isConstructor$4; var isObject$c = isObject$l; var toAbsoluteIndex$2 = toAbsoluteIndex$4; var lengthOfArrayLike$7 = lengthOfArrayLike$b; var toIndexedObject$5 = toIndexedObject$a; var createProperty$4 = createProperty$5; var wellKnownSymbol$i = wellKnownSymbol$o; var arrayMethodHasSpeciesSupport$3 = arrayMethodHasSpeciesSupport$5; var nativeSlice = arraySlice$7; var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport$3('slice'); var SPECIES$4 = wellKnownSymbol$i('species'); var $Array$2 = Array; var max$3 = Math.max; // `Array.prototype.slice` method // https://tc39.es/ecma262/#sec-array.prototype.slice // fallback for not array-like ES3 strings and DOM objects $$K({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$2 }, { slice: function slice(start, end) { var O = toIndexedObject$5(this); var length = lengthOfArrayLike$7(O); var k = toAbsoluteIndex$2(start, length); var fin = toAbsoluteIndex$2(end === undefined ? length : end, length); // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible var Constructor, result, n; if (isArray$4(O)) { Constructor = O.constructor; // cross-realm fallback if (isConstructor$2(Constructor) && (Constructor === $Array$2 || isArray$4(Constructor.prototype))) { Constructor = undefined; } else if (isObject$c(Constructor)) { Constructor = Constructor[SPECIES$4]; if (Constructor === null) Constructor = undefined; } if (Constructor === $Array$2 || Constructor === undefined) { return nativeSlice(O, k, fin); } } result = new (Constructor === undefined ? $Array$2 : Constructor)(max$3(fin - k, 0)); for (n = 0; k < fin; k++, n++) if (k in O) createProperty$4(result, n, O[k]); result.length = n; return result; } }); var ViewPort = { XS: 0, SM: 540, MD: 860, LG: 1084, XL: 1400 }; var DetectionUtil = { /* eslint-disable no-useless-escape, unicorn/better-regex */detectMobile: function detectMobile(includeTabletCheck) { if (includeTabletCheck === void 0) { includeTabletCheck = false; } /** * detect if mobile and/or tablet device * returns bool */ var check = false; if (includeTabletCheck) { (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.slice(0, 4))) { check = true; } })(navigator.userAgent || navigator.vendor || window.opera); } else { (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.slice(0, 4))) { check = true; } })(navigator.userAgent || navigator.vendor || window.opera); } return check; }, /** * Gets viewport based on brower's window width. * @returns {string} viewport */ detectViewport: function detectViewport() { var windowWidth = window.innerWidth; if (windowWidth >= ViewPort.XS && windowWidth < ViewPort.SM) { return 'xs'; } if (windowWidth < ViewPort.MD && windowWidth >= ViewPort.SM) { return 'sm'; } if (windowWidth < ViewPort.LG && windowWidth >= ViewPort.MD) { return 'md'; } if (windowWidth < ViewPort.XL && windowWidth >= ViewPort.LG) { return 'lg'; } if (windowWidth >= ViewPort.XL) { return 'xl'; } }, /* eslint-enable no-useless-escape */isBiDirectional: function isBiDirectional(el) { if (!el) { el = document.querySelector('html'); } return el.getAttribute('dir') === 'rtl'; }, /** * Detects whether a user has enabled the prefers reduced motion setting * @returns {boolean} */ prefersReducedMotion: function prefersReducedMotion() { var preference = window.matchMedia('(prefers-reduced-motion: reduce)'); return preference.matches; } }; function _regeneratorRuntime() { _regeneratorRuntime = function () { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function (obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function (skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function () { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function (exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function (type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function (record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function (finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, catch: function (tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function (iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } var id$2 = 0; function _classPrivateFieldLooseKey(name) { return "__private_" + id$2++ + "_" + name; } function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; } var toString$d = toString$i; var normalizeStringArgument$4 = function (argument, $default) { return argument === undefined ? arguments.length < 2 ? '' : $default : toString$d(argument); }; var DESCRIPTORS$d = descriptors; var fails$o = fails$I; var anObject$d = anObject$l; var create$6 = objectCreate; var normalizeStringArgument$3 = normalizeStringArgument$4; var nativeErrorToString = Error.prototype.toString; var INCORRECT_TO_STRING$1 = fails$o(function () { if (DESCRIPTORS$d) { // Chrome 32- incorrectly call accessor // eslint-disable-next-line es/no-object-defineproperty -- safe var object = create$6(Object.defineProperty({}, 'name', { get: function () { return this === object; } })); if (nativeErrorToString.call(object) !== 'true') return true; } // FF10- does not properly handle non-strings return nativeErrorToString.call({ message: 1, name: 2 }) !== '2: 1' // IE8 does not properly handle defaults || nativeErrorToString.call({}) !== 'Error'; }); var errorToString$2 = INCORRECT_TO_STRING$1 ? function toString() { var O = anObject$d(this); var name = normalizeStringArgument$3(O.name, 'Error'); var message = normalizeStringArgument$3(O.message); return !name ? message : !message ? name : name + ': ' + message; } : nativeErrorToString; var defineBuiltIn$d = defineBuiltIn$g; var errorToString$1 = errorToString$2; var ErrorPrototype$1 = Error.prototype; // `Error.prototype.toString` method fix // https://tc39.es/ecma262/#sec-error.prototype.tostring if (ErrorPrototype$1.toString !== errorToString$1) { defineBuiltIn$d(ErrorPrototype$1, 'toString', errorToString$1); } // TODO: Remove from `core-js@4` var uncurryThis$r = functionUncurryThis; var defineBuiltIn$c = defineBuiltIn$g; var DatePrototype$1 = Date.prototype; var INVALID_DATE = 'Invalid Date'; var TO_STRING$1 = 'toString'; var nativeDateToString = uncurryThis$r(DatePrototype$1[TO_STRING$1]); var thisTimeValue$2 = uncurryThis$r(DatePrototype$1.getTime); // `Date.prototype.toString` method // https://tc39.es/ecma262/#sec-date.prototype.tostring if (String(new Date(NaN)) != INVALID_DATE) { defineBuiltIn$c(DatePrototype$1, TO_STRING$1, function toString() { var value = thisTimeValue$2(this); // eslint-disable-next-line no-self-compare -- NaN check return value === value ? nativeDateToString(this) : INVALID_DATE; }); } var call$g = functionCall; var hasOwn$c = hasOwnProperty_1; var isPrototypeOf$3 = objectIsPrototypeOf; var regExpFlags = regexpFlags$1; var RegExpPrototype$2 = RegExp.prototype; var regexpGetFlags = function (R) { var flags = R.flags; return flags === undefined && !('flags' in RegExpPrototype$2) && !hasOwn$c(R, 'flags') && isPrototypeOf$3(RegExpPrototype$2, R) ? call$g(regExpFlags, R) : flags; }; var PROPER_FUNCTION_NAME$2 = functionName.PROPER; var defineBuiltIn$b = defineBuiltIn$g; var anObject$c = anObject$l; var $toString$2 = toString$i; var fails$n = fails$I; var getRegExpFlags = regexpGetFlags; var TO_STRING = 'toString'; var RegExpPrototype$1 = RegExp.prototype; var nativeToString = RegExpPrototype$1[TO_STRING]; var NOT_GENERIC = fails$n(function () { return nativeToString.call({ source: 'a', flags: 'b' }) != '/a/b'; }); // FF44- RegExp#toString has a wrong name var INCORRECT_NAME = PROPER_FUNCTION_NAME$2 && nativeToString.name != TO_STRING; // `RegExp.prototype.toString` method // https://tc39.es/ecma262/#sec-regexp.prototype.tostring if (NOT_GENERIC || INCORRECT_NAME) { defineBuiltIn$b(RegExp.prototype, TO_STRING, function toString() { var R = anObject$c(this); var pattern = $toString$2(R.source); var flags = $toString$2(getRegExpFlags(R)); return '/' + pattern + '/' + flags; }, { unsafe: true }); } var $$J = _export; var isArray$3 = isArray$7; // `Array.isArray` method // https://tc39.es/ecma262/#sec-array.isarray $$J({ target: 'Array', stat: true }, { isArray: isArray$3 }); var InitializationUtil = { /** * Initialize a component after DOM is loaded * @param {string} selector - DOM selector for component * @param {Function} init - Callback function to initialize the component */ initializeComponent: function initializeComponent(selector, init) { document.querySelectorAll(selector).forEach(function (node) { return init(node); }); }, /** * Iterate over list to add event listeners * @param {Array.<{ * el: Element | Document | Window, * handler: Function, * type: String, * options?: Object * }>} eventList - List of event maps */ addEvents: function addEvents(eventList) { for (var _iterator = _createForOfIteratorHelperLoose(eventList), _step; !(_step = _iterator()).done;) { var obj = _step.value; if (typeof obj.options === 'undefined') { obj.options = {}; } if (typeof obj.el.addEventListener === 'function') { obj.el.addEventListener(obj.type, obj.handler, obj.options); } else if (obj.el.toString() === '[object MediaQueryList]' && typeof obj.el.addListener === 'function') { obj.el.addListener(obj.handler); // for Safari <14 } } }, /** * Iterate over list to remove event listeners * @param {array} eventList - List of event maps */ removeEvents: function removeEvents(eventList) { for (var _iterator2 = _createForOfIteratorHelperLoose(eventList), _step2; !(_step2 = _iterator2()).done;) { var obj = _step2.value; if (typeof obj.el.removeEventListener === 'function') { obj.el.removeEventListener(obj.type, obj.handler); } else if (obj.el.toString() === '[object MediaQueryList]' && typeof obj.el.removeListener === 'function') { obj.el.removeListener(obj.handler); // for Safari <14 } } }, /** * Tears down each in a list of mwf component instances * @param {Array} componentList an array of mwf component instance */ tearDownComponentList: function tearDownComponentList(componentList) { if (Array.isArray(componentList)) { var component; while (componentList.length > 0) { component = componentList.pop(); if (typeof component.remove === 'function') { component.remove(); } } } } }; var $$I = _export; var fails$m = fails$I; var isArray$2 = isArray$7; var isObject$b = isObject$l; var toObject$5 = toObject$b; var lengthOfArrayLike$6 = lengthOfArrayLike$b; var doesNotExceedSafeInteger$1 = doesNotExceedSafeInteger$3; var createProperty$3 = createProperty$5; var arraySpeciesCreate$1 = arraySpeciesCreate$3; var arrayMethodHasSpeciesSupport$2 = arrayMethodHasSpeciesSupport$5; var wellKnownSymbol$h = wellKnownSymbol$o; var V8_VERSION$1 = engineV8Version; var IS_CONCAT_SPREADABLE = wellKnownSymbol$h('isConcatSpreadable'); // We can't use this feature detection in V8 since it causes // deoptimization and serious performance degradation // https://github.com/zloirock/core-js/issues/679 var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION$1 >= 51 || !fails$m(function () { var array = []; array[IS_CONCAT_SPREADABLE] = false; return array.concat()[0] !== array; }); var isConcatSpreadable = function (O) { if (!isObject$b(O)) return false; var spreadable = O[IS_CONCAT_SPREADABLE]; return spreadable !== undefined ? !!spreadable : isArray$2(O); }; var FORCED$6 = !IS_CONCAT_SPREADABLE_SUPPORT || !arrayMethodHasSpeciesSupport$2('concat'); // `Array.prototype.concat` method // https://tc39.es/ecma262/#sec-array.prototype.concat // with adding support of @@isConcatSpreadable and @@species $$I({ target: 'Array', proto: true, arity: 1, forced: FORCED$6 }, { // eslint-disable-next-line no-unused-vars -- required for `.length` concat: function concat(arg) { var O = toObject$5(this); var A = arraySpeciesCreate$1(O, 0); var n = 0; var i, k, length, len, E; for (i = -1, length = arguments.length; i < length; i++) { E = i === -1 ? O : arguments[i]; if (isConcatSpreadable(E)) { len = lengthOfArrayLike$6(E); doesNotExceedSafeInteger$1(n + len); for (k = 0; k < len; k++, n++) if (k in E) createProperty$3(A, n, E[k]); } else { doesNotExceedSafeInteger$1(n + 1); createProperty$3(A, n++, E); } } A.length = n; return A; } }); var call$f = functionCall; var anObject$b = anObject$l; var getMethod$3 = getMethod$5; var iteratorClose$2 = function (iterator, kind, value) { var innerResult, innerError; anObject$b(iterator); try { innerResult = getMethod$3(iterator, 'return'); if (!innerResult) { if (kind === 'throw') throw value; return value; } innerResult = call$f(innerResult, iterator); } catch (error) { innerError = true; innerResult = error; } if (kind === 'throw') throw value; if (innerError) throw innerResult; anObject$b(innerResult); return value; }; var anObject$a = anObject$l; var iteratorClose$1 = iteratorClose$2; // call something on iterator step with safe closing on error var callWithSafeIterationClosing$1 = function (iterator, fn, value, ENTRIES) { try { return ENTRIES ? fn(anObject$a(value)[0], value[1]) : fn(value); } catch (error) { iteratorClose$1(iterator, 'throw', error); } }; var iterators = {}; var wellKnownSymbol$g = wellKnownSymbol$o; var Iterators$4 = iterators; var ITERATOR$8 = wellKnownSymbol$g('iterator'); var ArrayPrototype$1 = Array.prototype; // check on default Array iterator var isArrayIteratorMethod$2 = function (it) { return it !== undefined && (Iterators$4.Array === it || ArrayPrototype$1[ITERATOR$8] === it); }; var classof$7 = classof$b; var getMethod$2 = getMethod$5; var isNullOrUndefined$6 = isNullOrUndefined$9; var Iterators$3 = iterators; var wellKnownSymbol$f = wellKnownSymbol$o; var ITERATOR$7 = wellKnownSymbol$f('iterator'); var getIteratorMethod$4 = function (it) { if (!isNullOrUndefined$6(it)) return getMethod$2(it, ITERATOR$7) || getMethod$2(it, '@@iterator') || Iterators$3[classof$7(it)]; }; var call$e = functionCall; var aCallable$5 = aCallable$a; var anObject$9 = anObject$l; var tryToString$3 = tryToString$5; var getIteratorMethod$3 = getIteratorMethod$4; var $TypeError$8 = TypeError; var getIterator$3 = function (argument, usingIterator) { var iteratorMethod = arguments.length < 2 ? getIteratorMethod$3(argument) : usingIterator; if (aCallable$5(iteratorMethod)) return anObject$9(call$e(iteratorMethod, argument)); throw $TypeError$8(tryToString$3(argument) + ' is not iterable'); }; var bind$7 = functionBindContext; var call$d = functionCall; var toObject$4 = toObject$b; var callWithSafeIterationClosing = callWithSafeIterationClosing$1; var isArrayIteratorMethod$1 = isArrayIteratorMethod$2; var isConstructor$1 = isConstructor$4; var lengthOfArrayLike$5 = lengthOfArrayLike$b; var createProperty$2 = createProperty$5; var getIterator$2 = getIterator$3; var getIteratorMethod$2 = getIteratorMethod$4; var $Array$1 = Array; // `Array.from` method implementation // https://tc39.es/ecma262/#sec-array.from var arrayFrom$1 = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) { var O = toObject$4(arrayLike); var IS_CONSTRUCTOR = isConstructor$1(this); var argumentsLength = arguments.length; var mapfn = argumentsLength > 1 ? arguments[1] : undefined; var mapping = mapfn !== undefined; if (mapping) mapfn = bind$7(mapfn, argumentsLength > 2 ? arguments[2] : undefined); var iteratorMethod = getIteratorMethod$2(O); var index = 0; var length, result, step, iterator, next, value; // if the target is not iterable or it's an array with the default iterator - use a simple case if (iteratorMethod && !(this === $Array$1 && isArrayIteratorMethod$1(iteratorMethod))) { iterator = getIterator$2(O, iteratorMethod); next = iterator.next; result = IS_CONSTRUCTOR ? new this() : []; for (;!(step = call$d(next, iterator)).done; index++) { value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value; createProperty$2(result, index, value); } } else { length = lengthOfArrayLike$5(O); result = IS_CONSTRUCTOR ? new this(length) : $Array$1(length); for (;length > index; index++) { value = mapping ? mapfn(O[index], index) : O[index]; createProperty$2(result, index, value); } } result.length = index; return result; }; var wellKnownSymbol$e = wellKnownSymbol$o; var ITERATOR$6 = wellKnownSymbol$e('iterator'); var SAFE_CLOSING = false; try { var called = 0; var iteratorWithReturn = { next: function () { return { done: !!called++ }; }, 'return': function () { SAFE_CLOSING = true; } }; iteratorWithReturn[ITERATOR$6] = function () { return this; }; // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing Array.from(iteratorWithReturn, function () { throw 2; }); } catch (error) { /* empty */ } var checkCorrectnessOfIteration$3 = function (exec, SKIP_CLOSING) { if (!SKIP_CLOSING && !SAFE_CLOSING) return false; var ITERATION_SUPPORT = false; try { var object = {}; object[ITERATOR$6] = function () { return { next: function () { return { done: ITERATION_SUPPORT = true }; } }; }; exec(object); } catch (error) { /* empty */ } return ITERATION_SUPPORT; }; var $$H = _export; var from = arrayFrom$1; var checkCorrectnessOfIteration$2 = checkCorrectnessOfIteration$3; var INCORRECT_ITERATION = !checkCorrectnessOfIteration$2(function (iterable) { // eslint-disable-next-line es/no-array-from -- required for testing Array.from(iterable); }); // `Array.from` method // https://tc39.es/ecma262/#sec-array.from $$H({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, { from: from }); var uncurryThis$q = functionUncurryThis; var toIntegerOrInfinity$4 = toIntegerOrInfinity$7; var toString$c = toString$i; var requireObjectCoercible$7 = requireObjectCoercible$b; var charAt$8 = uncurryThis$q(''.charAt); var charCodeAt$2 = uncurryThis$q(''.charCodeAt); var stringSlice$6 = uncurryThis$q(''.slice); var createMethod$2 = function (CONVERT_TO_STRING) { return function ($this, pos) { var S = toString$c(requireObjectCoercible$7($this)); var position = toIntegerOrInfinity$4(pos); var size = S.length; var first, second; if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined; first = charCodeAt$2(S, position); return first < 0xD800 || first > 0xDBFF || position + 1 === size || (second = charCodeAt$2(S, position + 1)) < 0xDC00 || second > 0xDFFF ? CONVERT_TO_STRING ? charAt$8(S, position) : first : CONVERT_TO_STRING ? stringSlice$6(S, position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; }; }; var stringMultibyte = { // `String.prototype.codePointAt` method // https://tc39.es/ecma262/#sec-string.prototype.codepointat codeAt: createMethod$2(false), // `String.prototype.at` method // https://github.com/mathiasbynens/String.prototype.at charAt: createMethod$2(true) }; var fails$l = fails$I; var correctPrototypeGetter = !fails$l(function () { function F() { /* empty */ } F.prototype.constructor = null; // eslint-disable-next-line es/no-object-getprototypeof -- required for testing return Object.getPrototypeOf(new F()) !== F.prototype; }); var hasOwn$b = hasOwnProperty_1; var isCallable$e = isCallable$u; var toObject$3 = toObject$b; var sharedKey = sharedKey$3; var CORRECT_PROTOTYPE_GETTER = correctPrototypeGetter; var IE_PROTO = sharedKey('IE_PROTO'); var $Object$1 = Object; var ObjectPrototype = $Object$1.prototype; // `Object.getPrototypeOf` method // https://tc39.es/ecma262/#sec-object.getprototypeof // eslint-disable-next-line es/no-object-getprototypeof -- safe var objectGetPrototypeOf = CORRECT_PROTOTYPE_GETTER ? $Object$1.getPrototypeOf : function (O) { var object = toObject$3(O); if (hasOwn$b(object, IE_PROTO)) return object[IE_PROTO]; var constructor = object.constructor; if (isCallable$e(constructor) && object instanceof constructor) { return constructor.prototype; } return object instanceof $Object$1 ? ObjectPrototype : null; }; var fails$k = fails$I; var isCallable$d = isCallable$u; var isObject$a = isObject$l; var getPrototypeOf$1 = objectGetPrototypeOf; var defineBuiltIn$a = defineBuiltIn$g; var wellKnownSymbol$d = wellKnownSymbol$o; var ITERATOR$5 = wellKnownSymbol$d('iterator'); var BUGGY_SAFARI_ITERATORS$1 = false; // `%IteratorPrototype%` object // https://tc39.es/ecma262/#sec-%iteratorprototype%-object var IteratorPrototype$2, PrototypeOfArrayIteratorPrototype, arrayIterator; /* eslint-disable es/no-array-prototype-keys -- safe */ if ([].keys) { arrayIterator = [].keys(); // Safari 8 has buggy iterators w/o `next` if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS$1 = true; else { PrototypeOfArrayIteratorPrototype = getPrototypeOf$1(getPrototypeOf$1(arrayIterator)); if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype$2 = PrototypeOfArrayIteratorPrototype; } } var NEW_ITERATOR_PROTOTYPE = !isObject$a(IteratorPrototype$2) || fails$k(function () { var test = {}; // FF44- legacy iterators case return IteratorPrototype$2[ITERATOR$5].call(test) !== test; }); if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype$2 = {}; // `%IteratorPrototype%[@@iterator]()` method // https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator if (!isCallable$d(IteratorPrototype$2[ITERATOR$5])) { defineBuiltIn$a(IteratorPrototype$2, ITERATOR$5, function () { return this; }); } var iteratorsCore = { IteratorPrototype: IteratorPrototype$2, BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS$1 }; var defineProperty$8 = objectDefineProperty.f; var hasOwn$a = hasOwnProperty_1; var wellKnownSymbol$c = wellKnownSymbol$o; var TO_STRING_TAG$1 = wellKnownSymbol$c('toStringTag'); var setToStringTag$7 = function (target, TAG, STATIC) { if (target && !STATIC) target = target.prototype; if (target && !hasOwn$a(target, TO_STRING_TAG$1)) { defineProperty$8(target, TO_STRING_TAG$1, { configurable: true, value: TAG }); } }; var IteratorPrototype$1 = iteratorsCore.IteratorPrototype; var create$5 = objectCreate; var createPropertyDescriptor$4 = createPropertyDescriptor$8; var setToStringTag$6 = setToStringTag$7; var Iterators$2 = iterators; var returnThis$1 = function () { return this; }; var iteratorCreateConstructor = function (IteratorConstructor, NAME, next, ENUMERABLE_NEXT) { var TO_STRING_TAG = NAME + ' Iterator'; IteratorConstructor.prototype = create$5(IteratorPrototype$1, { next: createPropertyDescriptor$4(+!ENUMERABLE_NEXT, next) }); setToStringTag$6(IteratorConstructor, TO_STRING_TAG, false); Iterators$2[TO_STRING_TAG] = returnThis$1; return IteratorConstructor; }; var $$G = _export; var call$c = functionCall; var FunctionName = functionName; var isCallable$c = isCallable$u; var createIteratorConstructor$1 = iteratorCreateConstructor; var getPrototypeOf = objectGetPrototypeOf; var setPrototypeOf$2 = objectSetPrototypeOf; var setToStringTag$5 = setToStringTag$7; var createNonEnumerableProperty$5 = createNonEnumerableProperty$9; var defineBuiltIn$9 = defineBuiltIn$g; var wellKnownSymbol$b = wellKnownSymbol$o; var Iterators$1 = iterators; var IteratorsCore = iteratorsCore; var PROPER_FUNCTION_NAME$1 = FunctionName.PROPER; var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE; var IteratorPrototype = IteratorsCore.IteratorPrototype; var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS; var ITERATOR$4 = wellKnownSymbol$b('iterator'); var KEYS$1 = 'keys'; var VALUES = 'values'; var ENTRIES = 'entries'; var returnThis = function () { return this; }; var iteratorDefine = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) { createIteratorConstructor$1(IteratorConstructor, NAME, next); var getIterationMethod = function (KIND) { if (KIND === DEFAULT && defaultIterator) return defaultIterator; if (!BUGGY_SAFARI_ITERATORS && KIND in IterablePrototype) return IterablePrototype[KIND]; switch (KIND) { case KEYS$1: return function keys() { return new IteratorConstructor(this, KIND); }; case VALUES: return function values() { return new IteratorConstructor(this, KIND); }; case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); }; } return function () { return new IteratorConstructor(this); }; }; var TO_STRING_TAG = NAME + ' Iterator'; var INCORRECT_VALUES_NAME = false; var IterablePrototype = Iterable.prototype; var nativeIterator = IterablePrototype[ITERATOR$4] || IterablePrototype['@@iterator'] || DEFAULT && IterablePrototype[DEFAULT]; var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT); var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator; var CurrentIteratorPrototype, methods, KEY; // fix native if (anyNativeIterator) { CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable())); if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { if (getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) { if (setPrototypeOf$2) { setPrototypeOf$2(CurrentIteratorPrototype, IteratorPrototype); } else if (!isCallable$c(CurrentIteratorPrototype[ITERATOR$4])) { defineBuiltIn$9(CurrentIteratorPrototype, ITERATOR$4, returnThis); } } // Set @@toStringTag to native iterators setToStringTag$5(CurrentIteratorPrototype, TO_STRING_TAG, true); } } // fix Array.prototype.{ values, @@iterator }.name in V8 / FF if (PROPER_FUNCTION_NAME$1 && DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) { if (CONFIGURABLE_FUNCTION_NAME) { createNonEnumerableProperty$5(IterablePrototype, 'name', VALUES); } else { INCORRECT_VALUES_NAME = true; defaultIterator = function values() { return call$c(nativeIterator, this); }; } } // export additional methods if (DEFAULT) { methods = { values: getIterationMethod(VALUES), keys: IS_SET ? defaultIterator : getIterationMethod(KEYS$1), entries: getIterationMethod(ENTRIES) }; if (FORCED) for (KEY in methods) { if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { defineBuiltIn$9(IterablePrototype, KEY, methods[KEY]); } } else $$G({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods); } // define iterator if (IterablePrototype[ITERATOR$4] !== defaultIterator) { defineBuiltIn$9(IterablePrototype, ITERATOR$4, defaultIterator, { name: DEFAULT }); } Iterators$1[NAME] = defaultIterator; return methods; }; // `CreateIterResultObject` abstract operation // https://tc39.es/ecma262/#sec-createiterresultobject var createIterResultObject$3 = function (value, done) { return { value: value, done: done }; }; var charAt$7 = stringMultibyte.charAt; var toString$b = toString$i; var InternalStateModule$7 = internalState; var defineIterator$2 = iteratorDefine; var createIterResultObject$2 = createIterResultObject$3; var STRING_ITERATOR = 'String Iterator'; var setInternalState$7 = InternalStateModule$7.set; var getInternalState$2 = InternalStateModule$7.getterFor(STRING_ITERATOR); // `String.prototype[@@iterator]` method // https://tc39.es/ecma262/#sec-string.prototype-@@iterator defineIterator$2(String, 'String', function (iterated) { setInternalState$7(this, { type: STRING_ITERATOR, string: toString$b(iterated), index: 0 }); // `%StringIteratorPrototype%.next` method // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next }, function next() { var state = getInternalState$2(this); var string = state.string; var index = state.index; var point; if (index >= string.length) return createIterResultObject$2(undefined, true); point = charAt$7(string, index); state.index += point.length; return createIterResultObject$2(point, false); }); var $$F = _export; var uncurryThis$p = functionUncurryThis; var IndexedObject = indexedObject; var toIndexedObject$4 = toIndexedObject$a; var arrayMethodIsStrict$5 = arrayMethodIsStrict$7; var nativeJoin = uncurryThis$p([].join); var ES3_STRINGS = IndexedObject != Object; var FORCED$5 = ES3_STRINGS || !arrayMethodIsStrict$5('join', ','); // `Array.prototype.join` method // https://tc39.es/ecma262/#sec-array.prototype.join $$F({ target: 'Array', proto: true, forced: FORCED$5 }, { join: function join(separator) { return nativeJoin(toIndexedObject$4(this), separator === undefined ? ',' : separator); } }); var wellKnownSymbol$a = wellKnownSymbol$o; var create$4 = objectCreate; var defineProperty$7 = objectDefineProperty.f; var UNSCOPABLES = wellKnownSymbol$a('unscopables'); var ArrayPrototype = Array.prototype; // Array.prototype[@@unscopables] // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables if (ArrayPrototype[UNSCOPABLES] == undefined) { defineProperty$7(ArrayPrototype, UNSCOPABLES, { configurable: true, value: create$4(null) }); } // add a key to Array.prototype[@@unscopables] var addToUnscopables$4 = function (key) { ArrayPrototype[UNSCOPABLES][key] = true; }; var $$E = _export; var $includes = arrayIncludes.includes; var fails$j = fails$I; var addToUnscopables$3 = addToUnscopables$4; // FF99+ bug var BROKEN_ON_SPARSE = fails$j(function () { // eslint-disable-next-line es/no-array-prototype-includes -- detection return !Array(1).includes(); }); // `Array.prototype.includes` method // https://tc39.es/ecma262/#sec-array.prototype.includes $$E({ target: 'Array', proto: true, forced: BROKEN_ON_SPARSE }, { includes: function includes(el /* , fromIndex = 0 */) { return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables addToUnscopables$3('includes'); var isObject$9 = isObject$l; var classof$6 = classofRaw$2; var wellKnownSymbol$9 = wellKnownSymbol$o; var MATCH$1 = wellKnownSymbol$9('match'); // `IsRegExp` abstract operation // https://tc39.es/ecma262/#sec-isregexp var isRegexp = function (it) { var isRegExp; return isObject$9(it) && ((isRegExp = it[MATCH$1]) !== undefined ? !!isRegExp : classof$6(it) == 'RegExp'); }; var isRegExp = isRegexp; var $TypeError$7 = TypeError; var notARegexp = function (it) { if (isRegExp(it)) { throw $TypeError$7("The method doesn't accept regular expressions"); } return it; }; var wellKnownSymbol$8 = wellKnownSymbol$o; var MATCH = wellKnownSymbol$8('match'); var correctIsRegexpLogic = function (METHOD_NAME) { var regexp = /./; try { '/./'[METHOD_NAME](regexp); } catch (error1) { try { regexp[MATCH] = false; return '/./'[METHOD_NAME](regexp); } catch (error2) { /* empty */ } } return false; }; var $$D = _export; var uncurryThis$o = functionUncurryThis; var notARegExp$1 = notARegexp; var requireObjectCoercible$6 = requireObjectCoercible$b; var toString$a = toString$i; var correctIsRegExpLogic$1 = correctIsRegexpLogic; var stringIndexOf$1 = uncurryThis$o(''.indexOf); // `String.prototype.includes` method // https://tc39.es/ecma262/#sec-string.prototype.includes $$D({ target: 'String', proto: true, forced: !correctIsRegExpLogic$1('includes') }, { includes: function includes(searchString /* , position = 0 */) { return !!~stringIndexOf$1( toString$a(requireObjectCoercible$6(this)), toString$a(notARegExp$1(searchString)), arguments.length > 1 ? arguments[1] : undefined ); } }); var toIndexedObject$3 = toIndexedObject$a; var addToUnscopables$2 = addToUnscopables$4; var Iterators = iterators; var InternalStateModule$6 = internalState; var defineProperty$6 = objectDefineProperty.f; var defineIterator$1 = iteratorDefine; var createIterResultObject$1 = createIterResultObject$3; var DESCRIPTORS$c = descriptors; var ARRAY_ITERATOR = 'Array Iterator'; var setInternalState$6 = InternalStateModule$6.set; var getInternalState$1 = InternalStateModule$6.getterFor(ARRAY_ITERATOR); // `Array.prototype.entries` method // https://tc39.es/ecma262/#sec-array.prototype.entries // `Array.prototype.keys` method // https://tc39.es/ecma262/#sec-array.prototype.keys // `Array.prototype.values` method // https://tc39.es/ecma262/#sec-array.prototype.values // `Array.prototype[@@iterator]` method // https://tc39.es/ecma262/#sec-array.prototype-@@iterator // `CreateArrayIterator` internal method // https://tc39.es/ecma262/#sec-createarrayiterator var es_array_iterator = defineIterator$1(Array, 'Array', function (iterated, kind) { setInternalState$6(this, { type: ARRAY_ITERATOR, target: toIndexedObject$3(iterated), // target index: 0, // next index kind: kind // kind }); // `%ArrayIteratorPrototype%.next` method // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next }, function () { var state = getInternalState$1(this); var target = state.target; var kind = state.kind; var index = state.index++; if (!target || index >= target.length) { state.target = undefined; return createIterResultObject$1(undefined, true); } if (kind == 'keys') return createIterResultObject$1(index, false); if (kind == 'values') return createIterResultObject$1(target[index], false); return createIterResultObject$1([index, target[index]], false); }, 'values'); // argumentsList[@@iterator] is %ArrayProto_values% // https://tc39.es/ecma262/#sec-createunmappedargumentsobject // https://tc39.es/ecma262/#sec-createmappedargumentsobject var values = Iterators.Arguments = Iterators.Array; // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables addToUnscopables$2('keys'); addToUnscopables$2('values'); addToUnscopables$2('entries'); // V8 ~ Chrome 45- bug if (DESCRIPTORS$c && values.name !== 'values') try { defineProperty$6(values, 'name', { value: 'values' }); } catch (error) { /* empty */ } var global$h = global$y; var DOMIterables = domIterables; var DOMTokenListPrototype = domTokenListPrototype; var ArrayIteratorMethods = es_array_iterator; var createNonEnumerableProperty$4 = createNonEnumerableProperty$9; var wellKnownSymbol$7 = wellKnownSymbol$o; var ITERATOR$3 = wellKnownSymbol$7('iterator'); var TO_STRING_TAG = wellKnownSymbol$7('toStringTag'); var ArrayValues = ArrayIteratorMethods.values; var handlePrototype = function (CollectionPrototype, COLLECTION_NAME) { if (CollectionPrototype) { // some Chrome versions have non-configurable methods on DOMTokenList if (CollectionPrototype[ITERATOR$3] !== ArrayValues) try { createNonEnumerableProperty$4(CollectionPrototype, ITERATOR$3, ArrayValues); } catch (error) { CollectionPrototype[ITERATOR$3] = ArrayValues; } if (!CollectionPrototype[TO_STRING_TAG]) { createNonEnumerableProperty$4(CollectionPrototype, TO_STRING_TAG, COLLECTION_NAME); } if (DOMIterables[COLLECTION_NAME]) for (var METHOD_NAME in ArrayIteratorMethods) { // some Chrome versions have non-configurable methods on DOMTokenList if (CollectionPrototype[METHOD_NAME] !== ArrayIteratorMethods[METHOD_NAME]) try { createNonEnumerableProperty$4(CollectionPrototype, METHOD_NAME, ArrayIteratorMethods[METHOD_NAME]); } catch (error) { CollectionPrototype[METHOD_NAME] = ArrayIteratorMethods[METHOD_NAME]; } } } }; for (var COLLECTION_NAME in DOMIterables) { handlePrototype(global$h[COLLECTION_NAME] && global$h[COLLECTION_NAME].prototype, COLLECTION_NAME); } handlePrototype(DOMTokenListPrototype, 'DOMTokenList'); var PROPER_FUNCTION_NAME = functionName.PROPER; var fails$i = fails$I; var whitespaces$2 = whitespaces$5; var non = '\u200B\u0085\u180E'; // check that a method works with the correct list // of whitespaces and has a correct name var stringTrimForced = function (METHOD_NAME) { return fails$i(function () { return !!whitespaces$2[METHOD_NAME]() || non[METHOD_NAME]() !== non || (PROPER_FUNCTION_NAME && whitespaces$2[METHOD_NAME].name !== METHOD_NAME); }); }; var $$C = _export; var $trim = stringTrim.trim; var forcedStringTrimMethod = stringTrimForced; // `String.prototype.trim` method // https://tc39.es/ecma262/#sec-string.prototype.trim $$C({ target: 'String', proto: true, forced: forcedStringTrimMethod('trim') }, { trim: function trim() { return $trim(this); } }); var selectors = ['input:not([disabled])', 'select:not([disabled])', 'textarea:not([disabled])', 'a[href]', 'button:not([disabled])', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])']; var tabSelectors = [].concat(selectors, ['[tabindex]:not([tabindex^="-"]):not([disabled])']); var focusSelectors = [].concat(selectors, ['[tabindex]:not([disabled])']); var HelpersUtil = { /** * Returns array of tabbable elements * @param {HTMLElement} node container to search, default is document * @returns {Array} returns elements that can be tabbed to using the keyboard */ getTabbableElements: function getTabbableElements(node) { if (node === void 0) { node = document; } return Array.from(node.querySelectorAll(tabSelectors.join(', '))); }, /** * Checks if a node is a tabbable element * @param {HTMLElement} node the node to compare * @returns {boolean} returns true or false depending on whether the node is considered tabbable or not */ isElementTabbable: function isElementTabbable(node) { return node.matches(tabSelectors.join(', ')); }, getUid: function getUid() { // Convert random number to base 36 (numbers + letters), // and grab the first 9 characters after the decimal. return Math.random().toString(36).slice(2, 9); }, /** * Returns array of focusable elements * @param {HTMLElement} node container to search, default is document * @returns {Array} returns elements that can receive focus */ getFocusableElements: function getFocusableElements(node) { if (node === void 0) { node = document; } return Array.from(node.querySelectorAll(focusSelectors.join(', '))); }, /** * Returns outer height of element, includes element offsetHeight * @param {HTMLElement} node container to search * @param {object} options * @param {string[]} options.cssSelectors array of css properties * @example * const options = { cssSelectors: ['margin', 'padding'] }; * const options = { cssSelectors: ['marginTop'] }; * @returns {number} returns height value */ getElementOuterHeight: function getElementOuterHeight(node, options) { if (options === void 0) { options = null; } var computedNodeStyles = getComputedStyle(node); if (!options) { return computedNodeStyles.offsetHeight; } var outerHeight = node.offsetHeight; options.cssSelectors.forEach(function (selector) { // if no values are specified, calculate spacing for the top and bottom if (!selector.toLowerCase().includes('top') && !selector.toLowerCase().includes('bottom')) { outerHeight += parseInt(computedNodeStyles[selector + 'Top'], 10) + parseInt(computedNodeStyles[selector + 'Bottom'], 10); } else if (selector.values.length > 0) { outerHeight += parseInt(computedNodeStyles[selector], 10); } }); return outerHeight; }, /** * Returns outer width of element, includes element offsetWidth * @param {HTMLElement} node container to search * @param {object} options * @param {string[]} options.cssSelectors array of css properties * @example * const options = { cssSelectors: ['margin', 'padding'] }; * const options = { cssSelectors: ['marginLeft'] }; * @returns {number} returns width value */ getElementOuterWidth: function getElementOuterWidth(node, options) { if (options === void 0) { options = null; } var computedNodeStyles = getComputedStyle(node); if (!options) { return computedNodeStyles.offsetWidth; } var outerWidth = node.offsetWidth; options.cssSelectors.forEach(function (selector) { // if no values are specifed, calculate spacing for the left and right if (!selector.toLowerCase().includes('left') && !selector.toLowerCase().includes('right')) { outerWidth += parseInt(computedNodeStyles[selector + 'Left'], 10) + parseInt(computedNodeStyles[selector + 'Right'], 10); } else if (selector.values.length > 0) { outerWidth += parseInt(computedNodeStyles[selector], 10); } }); return outerWidth; }, /** * Returns the value of the data-target attribute or null * @param {HTMLElement} element element with the data-target attribute * @returns {HTMLElement} returns the value of the data-target attribute or null */ getSelectorFromElement: function getSelectorFromElement(element) { try { var selector = element.getAttribute('data-target'); if (!selector || selector === '#') { var hrefAttr = element.getAttribute('href'); selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; } return selector; } catch (_unused) { return null; } }, /** * Gets the offset height of the element * @param {HTMLElement} element the element * @returns {number} returns the offset height */ reflow: function reflow(element) { return element.offsetHeight; }, /** * Gets the full height of the document * May be a little dated but this seems to be an established approach * https://javascript.info/size-and-scroll-window#width-height-of-the-document * @returns {number} the full height of the document */ getDocumentHeight: function getDocumentHeight() { return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight); } }; // TODO: Remove from `core-js@4` since it's moved to entry points var uncurryThis$n = functionUncurryThisClause; var defineBuiltIn$8 = defineBuiltIn$g; var regexpExec$1 = regexpExec$2; var fails$h = fails$I; var wellKnownSymbol$6 = wellKnownSymbol$o; var createNonEnumerableProperty$3 = createNonEnumerableProperty$9; var SPECIES$3 = wellKnownSymbol$6('species'); var RegExpPrototype = RegExp.prototype; var fixRegexpWellKnownSymbolLogic = function (KEY, exec, FORCED, SHAM) { var SYMBOL = wellKnownSymbol$6(KEY); var DELEGATES_TO_SYMBOL = !fails$h(function () { // String methods call symbol-named RegEp methods var O = {}; O[SYMBOL] = function () { return 7; }; return ''[KEY](O) != 7; }); var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$h(function () { // Symbol-named RegExp methods call .exec var execCalled = false; var re = /a/; if (KEY === 'split') { // We can't use real regex here since it causes deoptimization // and serious performance degradation in V8 // https://github.com/zloirock/core-js/issues/306 re = {}; // RegExp[@@split] doesn't call the regex's exec method, but first creates // a new one. We need to return the patched regex when creating the new one. re.constructor = {}; re.constructor[SPECIES$3] = function () { return re; }; re.flags = ''; re[SYMBOL] = /./[SYMBOL]; } re.exec = function () { execCalled = true; return null; }; re[SYMBOL](''); return !execCalled; }); if ( !DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || FORCED ) { var uncurriedNativeRegExpMethod = uncurryThis$n(/./[SYMBOL]); var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) { var uncurriedNativeMethod = uncurryThis$n(nativeMethod); var $exec = regexp.exec; if ($exec === regexpExec$1 || $exec === RegExpPrototype.exec) { if (DELEGATES_TO_SYMBOL && !forceStringMethod) { // The native String method already delegates to @@method (this // polyfilled function), leasing to infinite recursion. // We avoid it by directly calling the native @@method method. return { done: true, value: uncurriedNativeRegExpMethod(regexp, str, arg2) }; } return { done: true, value: uncurriedNativeMethod(str, regexp, arg2) }; } return { done: false }; }); defineBuiltIn$8(String.prototype, KEY, methods[0]); defineBuiltIn$8(RegExpPrototype, SYMBOL, methods[1]); } if (SHAM) createNonEnumerableProperty$3(RegExpPrototype[SYMBOL], 'sham', true); }; var charAt$6 = stringMultibyte.charAt; // `AdvanceStringIndex` abstract operation // https://tc39.es/ecma262/#sec-advancestringindex var advanceStringIndex$2 = function (S, index, unicode) { return index + (unicode ? charAt$6(S, index).length : 1); }; var call$b = functionCall; var anObject$8 = anObject$l; var isCallable$b = isCallable$u; var classof$5 = classofRaw$2; var regexpExec = regexpExec$2; var $TypeError$6 = TypeError; // `RegExpExec` abstract operation // https://tc39.es/ecma262/#sec-regexpexec var regexpExecAbstract = function (R, S) { var exec = R.exec; if (isCallable$b(exec)) { var result = call$b(exec, R, S); if (result !== null) anObject$8(result); return result; } if (classof$5(R) === 'RegExp') return call$b(regexpExec, R, S); throw $TypeError$6('RegExp#exec called on incompatible receiver'); }; var call$a = functionCall; var fixRegExpWellKnownSymbolLogic$1 = fixRegexpWellKnownSymbolLogic; var anObject$7 = anObject$l; var isNullOrUndefined$5 = isNullOrUndefined$9; var toLength$3 = toLength$5; var toString$9 = toString$i; var requireObjectCoercible$5 = requireObjectCoercible$b; var getMethod$1 = getMethod$5; var advanceStringIndex$1 = advanceStringIndex$2; var regExpExec$2 = regexpExecAbstract; // @@match logic fixRegExpWellKnownSymbolLogic$1('match', function (MATCH, nativeMatch, maybeCallNative) { return [ // `String.prototype.match` method // https://tc39.es/ecma262/#sec-string.prototype.match function match(regexp) { var O = requireObjectCoercible$5(this); var matcher = isNullOrUndefined$5(regexp) ? undefined : getMethod$1(regexp, MATCH); return matcher ? call$a(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$9(O)); }, // `RegExp.prototype[@@match]` method // https://tc39.es/ecma262/#sec-regexp.prototype-@@match function (string) { var rx = anObject$7(this); var S = toString$9(string); var res = maybeCallNative(nativeMatch, rx, S); if (res.done) return res.value; if (!rx.global) return regExpExec$2(rx, S); var fullUnicode = rx.unicode; rx.lastIndex = 0; var A = []; var n = 0; var result; while ((result = regExpExec$2(rx, S)) !== null) { var matchStr = toString$9(result[0]); A[n] = matchStr; if (matchStr === '') rx.lastIndex = advanceStringIndex$1(S, toLength$3(rx.lastIndex), fullUnicode); n++; } return n === 0 ? null : A; } ]; }); var ColorUtil = { /** * Calculates the YIQ of the color * @param {object} rgb The RGB notation of the color * @returns {number} */ getYiq: function getYiq(_ref) { var r = _ref.r, g = _ref.g, b = _ref.b; return (r * 299 + g * 587 + b * 114) / 1000; }, /** * Gets the RGB object notation for a string * @param {string} str a string representing a css rgb value * @returns {object} an object for rgb notation */ getRGB: function getRGB(str) { var match = str.match(/rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d\.\d?)\))?/); return match ? { r: match[1], g: match[2], b: match[3] } : {}; } }; // https://keycode.info/table-of-all-keycodes var KeyboardUtil = { keyCodes: { ARROW_DOWN: 40, ARROW_LEFT: 37, ARROW_RIGHT: 39, ARROW_UP: 38, BACKSPACE: 8, CLEAR: 12, END: 35, ENTER: 13, ESC: 27, HOME: 36, PAGE_DOWN: 34, PAGE_UP: 33, SPACE: 32, TAB: 9 }, // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values keys: { ARROW_DOWN: 'ArrowDown', ARROW_LEFT: 'ArrowLeft', ARROW_RIGHT: 'ArrowRight', ARROW_UP: 'ArrowUp', BACKSPACE: 'Backspace', CLEAR: 'Clear', END: 'End', ENTER: 'Enter', ESC: 'Escape', HOME: 'Home', PAGE_DOWN: 'PageDown', PAGE_UP: 'PageUp', SPACE: ' ', TAB: 'Tab' }, getKeyCode: function getKeyCode(e) { return e.which || e.keyCode || 0; } }; var NATIVE_BIND = functionBindNative; var FunctionPrototype$1 = Function.prototype; var apply$6 = FunctionPrototype$1.apply; var call$9 = FunctionPrototype$1.call; // eslint-disable-next-line es/no-reflect -- safe var functionApply = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call$9.bind(apply$6) : function () { return call$9.apply(apply$6, arguments); }); var uncurryThis$m = functionUncurryThis; var toObject$2 = toObject$b; var floor$3 = Math.floor; var charAt$5 = uncurryThis$m(''.charAt); var replace$7 = uncurryThis$m(''.replace); var stringSlice$5 = uncurryThis$m(''.slice); // eslint-disable-next-line redos/no-vulnerable -- safe var SUBSTITUTION_SYMBOLS = /$([$&'`]|\d{1,2}|<[^>]*>)/g; var SUBSTITUTION_SYMBOLS_NO_NAMED = /$([$&'`]|\d{1,2})/g; // `GetSubstitution` abstract operation // https://tc39.es/ecma262/#sec-getsubstitution var getSubstitution$1 = function (matched, str, position, captures, namedCaptures, replacement) { var tailPos = position + matched.length; var m = captures.length; var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; if (namedCaptures !== undefined) { namedCaptures = toObject$2(namedCaptures); symbols = SUBSTITUTION_SYMBOLS; } return replace$7(replacement, symbols, function (match, ch) { var capture; switch (charAt$5(ch, 0)) { case '$': return '$'; case '&': return matched; case '`': return stringSlice$5(str, 0, position); case "'": return stringSlice$5(str, tailPos); case '<': capture = namedCaptures[stringSlice$5(ch, 1, -1)]; break; default: // \d\d? var n = +ch; if (n === 0) return match; if (n > m) { var f = floor$3(n / 10); if (f === 0) return match; if (f <= m) return captures[f - 1] === undefined ? charAt$5(ch, 1) : captures[f - 1] + charAt$5(ch, 1); return match; } capture = captures[n - 1]; } return capture === undefined ? '' : capture; }); }; var apply$5 = functionApply; var call$8 = functionCall; var uncurryThis$l = functionUncurryThis; var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic; var fails$g = fails$I; var anObject$6 = anObject$l; var isCallable$a = isCallable$u; var isNullOrUndefined$4 = isNullOrUndefined$9; var toIntegerOrInfinity$3 = toIntegerOrInfinity$7; var toLength$2 = toLength$5; var toString$8 = toString$i; var requireObjectCoercible$4 = requireObjectCoercible$b; var advanceStringIndex = advanceStringIndex$2; var getMethod = getMethod$5; var getSubstitution = getSubstitution$1; var regExpExec$1 = regexpExecAbstract; var wellKnownSymbol$5 = wellKnownSymbol$o; var REPLACE = wellKnownSymbol$5('replace'); var max$2 = Math.max; var min$3 = Math.min; var concat = uncurryThis$l([].concat); var push$6 = uncurryThis$l([].push); var stringIndexOf = uncurryThis$l(''.indexOf); var stringSlice$4 = uncurryThis$l(''.slice); var maybeToString = function (it) { return it === undefined ? it : String(it); }; // IE <= 11 replaces $0 with the whole match, as if it was $& // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0 var REPLACE_KEEPS_$0 = (function () { // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing return 'a'.replace(/./, '$0') === '$0'; })(); // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = (function () { if (/./[REPLACE]) { return /./[REPLACE]('a', '$0') === ''; } return false; })(); var REPLACE_SUPPORTS_NAMED_GROUPS = !fails$g(function () { var re = /./; re.exec = function () { var result = []; result.groups = { a: '7' }; return result; }; // eslint-disable-next-line regexp/no-useless-dollar-replacements -- false positive return ''.replace(re, '$') !== '7'; }); // @@replace logic fixRegExpWellKnownSymbolLogic('replace', function (_, nativeReplace, maybeCallNative) { var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0'; return [ // `String.prototype.replace` method // https://tc39.es/ecma262/#sec-string.prototype.replace function replace(searchValue, replaceValue) { var O = requireObjectCoercible$4(this); var replacer = isNullOrUndefined$4(searchValue) ? undefined : getMethod(searchValue, REPLACE); return replacer ? call$8(replacer, searchValue, O, replaceValue) : call$8(nativeReplace, toString$8(O), searchValue, replaceValue); }, // `RegExp.prototype[@@replace]` method // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace function (string, replaceValue) { var rx = anObject$6(this); var S = toString$8(string); if ( typeof replaceValue == 'string' && stringIndexOf(replaceValue, UNSAFE_SUBSTITUTE) === -1 && stringIndexOf(replaceValue, '$<') === -1 ) { var res = maybeCallNative(nativeReplace, rx, S, replaceValue); if (res.done) return res.value; } var functionalReplace = isCallable$a(replaceValue); if (!functionalReplace) replaceValue = toString$8(replaceValue); var global = rx.global; if (global) { var fullUnicode = rx.unicode; rx.lastIndex = 0; } var results = []; while (true) { var result = regExpExec$1(rx, S); if (result === null) break; push$6(results, result); if (!global) break; var matchStr = toString$8(result[0]); if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$2(rx.lastIndex), fullUnicode); } var accumulatedResult = ''; var nextSourcePosition = 0; for (var i = 0; i < results.length; i++) { result = results[i]; var matched = toString$8(result[0]); var position = max$2(min$3(toIntegerOrInfinity$3(result.index), S.length), 0); var captures = []; // NOTE: This is equivalent to // captures = result.slice(1).map(maybeToString) // but for some reason `nativeSlice.call(result, 1, result.length)` (called in // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it. for (var j = 1; j < result.length; j++) push$6(captures, maybeToString(result[j])); var namedCaptures = result.groups; if (functionalReplace) { var replacerArgs = concat([matched], captures, position, S); if (namedCaptures !== undefined) push$6(replacerArgs, namedCaptures); var replacement = toString$8(apply$5(replaceValue, undefined, replacerArgs)); } else { replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue); } if (position >= nextSourcePosition) { accumulatedResult += stringSlice$4(S, nextSourcePosition, position) + replacement; nextSourcePosition = position + matched.length; } } return accumulatedResult + stringSlice$4(S, nextSourcePosition); } ]; }, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE); var StringUtil = { /** * Interpolate a string. * @param {string} template - The template string to interpolate, with keys in the format %{key}. * @param {object} data - An object containing the keys and values to replace in the template. * @returns {string} - The interpolated string. */ interpolateString: function interpolateString(template, data) { return template.replace(/%{(\w+)}/g, function (match, key) { if (Object.prototype.hasOwnProperty.call(data, key)) { return data[key]; } // %{key} not found, show a warning in the console and return an empty string // eslint-disable-next-line no-console console.warn("Template error, %{" + key + "} not found:", template); return ''; }); } }; /* eslint-disable es/no-array-prototype-indexof -- required for testing */ var $$B = _export; var uncurryThis$k = functionUncurryThisClause; var $indexOf = arrayIncludes.indexOf; var arrayMethodIsStrict$4 = arrayMethodIsStrict$7; var nativeIndexOf = uncurryThis$k([].indexOf); var NEGATIVE_ZERO$1 = !!nativeIndexOf && 1 / nativeIndexOf([1], 1, -0) < 0; var FORCED$4 = NEGATIVE_ZERO$1 || !arrayMethodIsStrict$4('indexOf'); // `Array.prototype.indexOf` method // https://tc39.es/ecma262/#sec-array.prototype.indexof $$B({ target: 'Array', proto: true, forced: FORCED$4 }, { indexOf: function indexOf(searchElement /* , fromIndex = 0 */) { var fromIndex = arguments.length > 1 ? arguments[1] : undefined; return NEGATIVE_ZERO$1 // convert -0 to +0 ? nativeIndexOf(this, searchElement, fromIndex) || 0 : $indexOf(this, searchElement, fromIndex); } }); var tryToString$2 = tryToString$5; var $TypeError$5 = TypeError; var deletePropertyOrThrow$2 = function (O, P) { if (!delete O[P]) throw $TypeError$5('Cannot delete property ' + tryToString$2(P) + ' of ' + tryToString$2(O)); }; var $$A = _export; var toObject$1 = toObject$b; var toAbsoluteIndex$1 = toAbsoluteIndex$4; var toIntegerOrInfinity$2 = toIntegerOrInfinity$7; var lengthOfArrayLike$4 = lengthOfArrayLike$b; var setArrayLength = arraySetLength; var doesNotExceedSafeInteger = doesNotExceedSafeInteger$3; var arraySpeciesCreate = arraySpeciesCreate$3; var createProperty$1 = createProperty$5; var deletePropertyOrThrow$1 = deletePropertyOrThrow$2; var arrayMethodHasSpeciesSupport$1 = arrayMethodHasSpeciesSupport$5; var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport$1('splice'); var max$1 = Math.max; var min$2 = Math.min; // `Array.prototype.splice` method // https://tc39.es/ecma262/#sec-array.prototype.splice // with adding support of @@species $$A({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT$1 }, { splice: function splice(start, deleteCount /* , ...items */) { var O = toObject$1(this); var len = lengthOfArrayLike$4(O); var actualStart = toAbsoluteIndex$1(start, len); var argumentsLength = arguments.length; var insertCount, actualDeleteCount, A, k, from, to; if (argumentsLength === 0) { insertCount = actualDeleteCount = 0; } else if (argumentsLength === 1) { insertCount = 0; actualDeleteCount = len - actualStart; } else { insertCount = argumentsLength - 2; actualDeleteCount = min$2(max$1(toIntegerOrInfinity$2(deleteCount), 0), len - actualStart); } doesNotExceedSafeInteger(len + insertCount - actualDeleteCount); A = arraySpeciesCreate(O, actualDeleteCount); for (k = 0; k < actualDeleteCount; k++) { from = actualStart + k; if (from in O) createProperty$1(A, k, O[from]); } A.length = actualDeleteCount; if (insertCount < actualDeleteCount) { for (k = actualStart; k < len - actualDeleteCount; k++) { from = k + actualDeleteCount; to = k + insertCount; if (from in O) O[to] = O[from]; else deletePropertyOrThrow$1(O, to); } for (k = len; k > len - actualDeleteCount + insertCount; k--) deletePropertyOrThrow$1(O, k - 1); } else if (insertCount > actualDeleteCount) { for (k = len - actualDeleteCount; k > actualStart; k--) { from = k + actualDeleteCount - 1; to = k + insertCount - 1; if (from in O) O[to] = O[from]; else deletePropertyOrThrow$1(O, to); } } for (k = 0; k < insertCount; k++) { O[k + actualStart] = arguments[k + 2]; } setArrayLength(O, len - actualDeleteCount + insertCount); return A; } }); var EventName$N = { ON_REMOVE: 'onRemove' }; var focusControls = []; /** * Class representing Focus Controls. * Solve for Firefox bug where following on-page anchor links loses focus: * https://bugzilla.mozilla.org/show_bug.cgi?id=308064 * https://bugzilla.mozilla.org/show_bug.cgi?id=277178 */ var FocusControls = /*#__PURE__*/function () { /** * Create a FocusControls instance * @param {Object} opts - The focus control options. * @param {HTMLElement} opts.el - The anchor element node, must have href attribute with fragment identifier. */ function FocusControls(opts) { var _this = this; this.el = opts.el; this.target = document.querySelector(this.el.getAttribute('href')); this.events = [{ el: this.el, type: 'click', handler: function handler(e) { _this.onClick(e); } }]; // Add event handlers. InitializationUtil.addEvents(this.events); focusControls.push(this); } /** * Click event. * @param {Event} e - The event object. */ var _proto = FocusControls.prototype; _proto.onClick = function onClick(e) { e.preventDefault(); // removes focus if target element is already focused (for voiceover on mobile) if (document.activeElement === this.target) { document.activeElement.blur(); } this.target.focus(); this.target.scrollIntoView(); } /** * Remove the focus controls and events. */; _proto.remove = function remove() { // Remove event handlers InitializationUtil.removeEvents(this.events); // Remove this focus controls reference from array of instances var index = focusControls.indexOf(this); focusControls.splice(index, 1); // Create and dispatch custom event this[EventName$N.ON_REMOVE] = new CustomEvent(EventName$N.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$N.ON_REMOVE]); } /** * Get an array of focus controls instances. * @returns {Object[]} Array of focus controls instances. */; FocusControls.getInstances = function getInstances() { return focusControls; }; return FocusControls; }(); var global$g = global$y; var fails$f = fails$I; var uncurryThis$j = functionUncurryThis; var toString$7 = toString$i; var trim = stringTrim.trim; var whitespaces$1 = whitespaces$5; var charAt$4 = uncurryThis$j(''.charAt); var $parseFloat$1 = global$g.parseFloat; var Symbol$1 = global$g.Symbol; var ITERATOR$2 = Symbol$1 && Symbol$1.iterator; var FORCED$3 = 1 / $parseFloat$1(whitespaces$1 + '-0') !== -Infinity // MS Edge 18- broken with boxed symbols || (ITERATOR$2 && !fails$f(function () { $parseFloat$1(Object(ITERATOR$2)); })); // `parseFloat` method // https://tc39.es/ecma262/#sec-parsefloat-string var numberParseFloat = FORCED$3 ? function parseFloat(string) { var trimmedString = trim(toString$7(string)); var result = $parseFloat$1(trimmedString); return result === 0 && charAt$4(trimmedString, 0) == '-' ? -0 : result; } : $parseFloat$1; var $$z = _export; var $parseFloat = numberParseFloat; // `parseFloat` method // https://tc39.es/ecma262/#sec-parsefloat-string $$z({ global: true, forced: parseFloat != $parseFloat }, { parseFloat: $parseFloat }); /* global Bun -- Deno case */ var engineIsBun = typeof Bun == 'function' && Bun && typeof Bun.version == 'string'; var $TypeError$4 = TypeError; var validateArgumentsLength$5 = function (passed, required) { if (passed < required) throw $TypeError$4('Not enough arguments'); return passed; }; var global$f = global$y; var apply$4 = functionApply; var isCallable$9 = isCallable$u; var ENGINE_IS_BUN = engineIsBun; var USER_AGENT = engineUserAgent; var arraySlice$5 = arraySlice$7; var validateArgumentsLength$4 = validateArgumentsLength$5; var Function$2 = global$f.Function; // dirty IE9- and Bun 0.3.0- checks var WRAP = /MSIE .\./.test(USER_AGENT) || ENGINE_IS_BUN && (function () { var version = global$f.Bun.version.split('.'); return version.length < 3 || version[0] == 0 && (version[1] < 3 || version[1] == 3 && version[2] == 0); })(); // IE9- / Bun 0.3.0- setTimeout / setInterval / setImmediate additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers // https://github.com/oven-sh/bun/issues/1633 var schedulersFix$2 = function (scheduler, hasTimeArg) { var firstParamIndex = hasTimeArg ? 2 : 1; return WRAP ? function (handler, timeout /* , ...arguments */) { var boundArgs = validateArgumentsLength$4(arguments.length, 1) > firstParamIndex; var fn = isCallable$9(handler) ? handler : Function$2(handler); var params = boundArgs ? arraySlice$5(arguments, firstParamIndex) : []; var callback = boundArgs ? function () { apply$4(fn, this, params); } : fn; return hasTimeArg ? scheduler(callback, timeout) : scheduler(callback); } : scheduler; }; var $$y = _export; var global$e = global$y; var schedulersFix$1 = schedulersFix$2; var setInterval = schedulersFix$1(global$e.setInterval, true); // Bun / IE9- setInterval additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-setinterval $$y({ global: true, bind: true, forced: global$e.setInterval !== setInterval }, { setInterval: setInterval }); var $$x = _export; var global$d = global$y; var schedulersFix = schedulersFix$2; var setTimeout$1 = schedulersFix(global$d.setTimeout, true); // Bun / IE9- setTimeout additional parameters fix // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout $$x({ global: true, bind: true, forced: global$d.setTimeout !== setTimeout$1 }, { setTimeout: setTimeout$1 }); var TRANSITION_END = 'transitionend'; /** * Gets the transition duration from an element's styles * @param {HTMLElement} element - element * @returns {number} - transition duration in milliseconds */ var getTransitionDurationFromElement = function getTransitionDurationFromElement(element) { var MILLISECONDS_MULTIPLIER = 1000; if (!element) { return 0; } // Get transition-duration of the element var transitionDuration = getComputedStyle(element)['transition-duration']; var transitionDelay = getComputedStyle(element)['transition-delay']; var floatTransitionDuration = parseFloat(transitionDuration); var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found if (!floatTransitionDuration && !floatTransitionDelay) { return 0; } // If multiple durations are defined, take the first transitionDuration = transitionDuration.split(',')[0]; transitionDelay = transitionDelay.split(',')[0]; return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; }; /** * Dispatches a transition-end event. * @param {HTMLElement} element - element on which to dispatch event */ var triggerTransitionEnd = function triggerTransitionEnd(element) { element.dispatchEvent(new Event(TRANSITION_END)); }; /** * Ensures transition-end is triggered on an element. * @param {HTMLElement} element - element on which transition occurs * @param {number} duration - transition duration in milliseconds */ var emulateTransitionEnd = function emulateTransitionEnd(element, duration) { if (duration === void 0) { duration = 0; } var called = false; var durationPadding = 5; var emulatedDuration = duration + durationPadding; function listener() { called = true; element.removeEventListener(TRANSITION_END, listener); } element.addEventListener(TRANSITION_END, listener); setTimeout(function () { if (!called) { triggerTransitionEnd(element); } }, emulatedDuration); }; var TransitionUtil = { TRANSITION_END: TRANSITION_END, getTransitionDurationFromElement: getTransitionDurationFromElement, triggerTransitionEnd: triggerTransitionEnd, emulateTransitionEnd: emulateTransitionEnd }; var Util$1 = Object.assign({}, DetectionUtil, HelpersUtil, InitializationUtil, ColorUtil, KeyboardUtil, StringUtil, { FocusControls: FocusControls }, TransitionUtil); // TODO: Remove from `core-js@4` var $$w = _export; var uncurryThis$i = functionUncurryThis; var $Date = Date; var thisTimeValue$1 = uncurryThis$i($Date.prototype.getTime); // `Date.now` method // https://tc39.es/ecma262/#sec-date.now $$w({ target: 'Date', stat: true }, { now: function now() { return thisTimeValue$1(new $Date()); } }); /* eslint-disable no-undefined,no-param-reassign,no-shadow */ /** * Throttle execution of a function. Especially useful for rate limiting * execution of handlers on events like resize and scroll. * * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) * are most useful. * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, * as-is, to `callback` when the throttled-function is executed. * @param {object} [options] - An object to configure options. * @param {boolean} [options.noTrailing] - Optional, defaults to false. If noTrailing is true, callback will only execute every `delay` milliseconds * while the throttled-function is being called. If noTrailing is false or unspecified, callback will be executed * one final time after the last throttled-function call. (After the throttled-function has not been called for * `delay` milliseconds, the internal counter is reset). * @param {boolean} [options.noLeading] - Optional, defaults to false. If noLeading is false, the first throttled-function call will execute callback * immediately. If noLeading is true, the first the callback execution will be skipped. It should be noted that * callback will never executed if both noLeading = true and noTrailing = true. * @param {boolean} [options.debounceMode] - If `debounceMode` is true (at begin), schedule `clear` to execute after `delay` ms. If `debounceMode` is * false (at end), schedule `callback` to execute after `delay` ms. * * @returns {Function} A new, throttled, function. */ function throttle(delay, callback, options) { var _ref = options || {}, _ref$noTrailing = _ref.noTrailing, noTrailing = _ref$noTrailing === void 0 ? false : _ref$noTrailing, _ref$noLeading = _ref.noLeading, noLeading = _ref$noLeading === void 0 ? false : _ref$noLeading, _ref$debounceMode = _ref.debounceMode, debounceMode = _ref$debounceMode === void 0 ? undefined : _ref$debounceMode; /* * After wrapper has stopped being called, this timeout ensures that * `callback` is executed at the proper times in `throttle` and `end` * debounce modes. */ var timeoutID; var cancelled = false; // Keep track of the last time `callback` was executed. var lastExec = 0; // Function to clear existing timeout function clearExistingTimeout() { if (timeoutID) { clearTimeout(timeoutID); } } // Function to cancel next exec function cancel(options) { var _ref2 = options || {}, _ref2$upcomingOnly = _ref2.upcomingOnly, upcomingOnly = _ref2$upcomingOnly === void 0 ? false : _ref2$upcomingOnly; clearExistingTimeout(); cancelled = !upcomingOnly; } /* * The `wrapper` function encapsulates all of the throttling / debouncing * functionality and when executed will limit the rate at which `callback` * is executed. */ function wrapper() { for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0; _key < _len; _key++) { arguments_[_key] = arguments[_key]; } var self = this; var elapsed = Date.now() - lastExec; if (cancelled) { return; } // Execute `callback` and update the `lastExec` timestamp. function exec() { lastExec = Date.now(); callback.apply(self, arguments_); } /* * If `debounceMode` is true (at begin) this is used to clear the flag * to allow future `callback` executions. */ function clear() { timeoutID = undefined; } if (!noLeading && debounceMode && !timeoutID) { /* * Since `wrapper` is being called for the first time and * `debounceMode` is true (at begin), execute `callback` * and noLeading != true. */ exec(); } clearExistingTimeout(); if (debounceMode === undefined && elapsed > delay) { if (noLeading) { /* * In throttle mode with noLeading, if `delay` time has * been exceeded, update `lastExec` and schedule `callback` * to execute after `delay` ms. */ lastExec = Date.now(); if (!noTrailing) { timeoutID = setTimeout(debounceMode ? clear : exec, delay); } } else { /* * In throttle mode without noLeading, if `delay` time has been exceeded, execute * `callback`. */ exec(); } } else if (noTrailing !== true) { /* * In trailing throttle mode, since `delay` time has not been * exceeded, schedule `callback` to execute `delay` ms after most * recent execution. * * If `debounceMode` is true (at begin), schedule `clear` to execute * after `delay` ms. * * If `debounceMode` is false (at end), schedule `callback` to * execute after `delay` ms. */ timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay); } } wrapper.cancel = cancel; // Return the wrapper function. return wrapper; } /* eslint-disable no-undefined */ /** * Debounce execution of a function. Debouncing, unlike throttling, * guarantees that a function is only executed a single time, either at the * very beginning of a series of calls, or at the very end. * * @param {number} delay - A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful. * @param {Function} callback - A function to be executed after delay milliseconds. The `this` context and all arguments are passed through, as-is, * to `callback` when the debounced-function is executed. * @param {object} [options] - An object to configure options. * @param {boolean} [options.atBegin] - Optional, defaults to false. If atBegin is false or unspecified, callback will only be executed `delay` milliseconds * after the last debounced-function call. If atBegin is true, callback will be executed only at the first debounced-function call. * (After the throttled-function has not been called for `delay` milliseconds, the internal counter is reset). * * @returns {Function} A new, debounced function. */ function debounce(delay, callback, options) { var _ref = options || {}, _ref$atBegin = _ref.atBegin, atBegin = _ref$atBegin === void 0 ? false : _ref$atBegin; return throttle(delay, callback, { debounceMode: atBegin !== false }); } var Selector$N = { MEDIA_CONTROL: 'media-control', M365_VIDEO_CONTROL: 'm365-video__control', PAUSE_GLYPH_CLASS: 'glyph-prepend-pause', PLAY_GLYPH_CLASS: 'glyph-prepend-play-solid', PAUSE_ALT_TEXT_PREFIX: 'data-aria-label-pause-prefix', PLAY_ALT_TEXT_PREFIX: 'data-aria-label-play-prefix', ARIA_LABEL_SUFFIX: 'data-aria-label-suffix', DATA_MOUNT: '[data-mount="m365-video"]', CONTENT_SCROLL_VIEW: 'ContentScrollView' }; /** * Swaps out videos to serve specific video sources for certain min-widths. */ var AdaptiveVideo = /*#__PURE__*/function () { /** * Adds responsiveness to a video by taking different sources specified for min-widths and swapping them out on window resize. * @param {HTMLElement} videoElement Video element to add responsiveness to */ function AdaptiveVideo(videoElement, onViewportChange) { var _this = this; this.resizeTimeout = 100; this.options = { breakpoints: { "default": { src: videoElement.dataset.src } }, onViewportChange: onViewportChange }; this.setVideo(videoElement); // get a list of video switching points and links to the videos themselves videoElement.querySelectorAll('[data-src]').forEach(function (element) { _this.options.breakpoints[element.dataset.minWidth] = { src: element.dataset.src, type: element.getAttribute('type') }; }); videoElement.innerHTML = ''; // we clean up so that there is nothing superfluous // run the handler and track the change in screen width this.responseVideo(this.options, videoElement.autoplay); this.resizer(); this.onViewportChange(); } /** * Changes the video element this object applies viewport changes to. * @param {HTMLElement} videoElement Video element to assign to this class */ var _proto = AdaptiveVideo.prototype; _proto.setVideo = function setVideo(videoElement) { this.options.videoElement = videoElement; } /** * Binds a function to be called when the video is changed due to a viewport change. * @param {Function} callback Function to call on video viewport change */; _proto.bindViewportChange = function bindViewportChange(callback) { this.options.onViewportChange = callback; } /** * Event for when the video changes due to viewport changes */; _proto.onViewportChange = function onViewportChange() { this.options.onViewportChange(this.options.videoElement); } /** Function runs on resize */; _proto.resizer = function resizer() { window.addEventListener('resize', throttle(this.resizeTimeout, this.responseVideo.bind(this, this.options))); } /** * Tests a value to see if it is NaN. * @param {Number} number value to test * @returns True if NaN or null, false otherwise. */; _proto.numberIsNaN = function numberIsNaN(number) { return !number || isNaN(number) || !isFinite(number); } /** * Gets the last recorded min width used for the video * @param {HTMLElement} videoElement Video element * @returns The last recorded min width for the video */; _proto.getWidthNow = function getWidthNow(videoElement) { var ret = videoElement.dataset.widthNow; var numberValue = parseInt(ret, 10); if (!this.numberIsNaN(numberValue)) { ret = numberValue; } else if (ret !== 'default') { ret = null; } return ret; }; _proto.onCanPlayThrough = function onCanPlayThrough(time, videoElement, playOnLoad, paused, ended) { if (!this.numberIsNaN(time)) { videoElement.currentTime = time; // set the time on the video to the current time of the last video } // play or pause the video based on the state of the old video element if (!playOnLoad) { if (!paused && !ended) { videoElement.play(); } else { videoElement.pause(); } } } /** * Change src value of video link to fit screen width * * @param {Object} options object with options */; _proto.responseVideo = function responseVideo(options, playOnLoad) { var _this2 = this; if (playOnLoad === void 0) { playOnLoad = false; } var videoElement = options.videoElement, breakpoints = options.breakpoints; // get options var currentTime = videoElement.currentTime, paused = videoElement.paused, ended = videoElement.ended, parentElement = videoElement.parentElement; // get video info var videoElementClone = videoElement.cloneNode(true); // create new video element for viewport var videoSource = document.createElement('source'); var widthNow = this.getWidthNow(videoElement); // get the last video min width var minBreakpoint = Math.max.apply(null, Object.keys(breakpoints).filter(function (key) { return Number(key) <= document.body.clientWidth; })); // find maximum width from breakpoints that doesn't go over the width of the window var nowBreakpoint = this.numberIsNaN(minBreakpoint) ? 'default' : minBreakpoint; // choose either the maximum value, if not, then the default // call back for function needed as a const so that it can be removed later. var canPlayThroughCallback = function canPlayThroughCallback() { _this2.onCanPlayThrough(currentTime, videoElementClone, playOnLoad, paused, ended); videoElementClone.removeEventListener('canplaythrough', canPlayThroughCallback); }; if (widthNow && widthNow === nowBreakpoint) { return; } // check if the video needs to be changed videoElementClone.innerHTML = ''; // we clean up so that there is nothing superfluous videoElementClone.dataset.widthNow = nowBreakpoint; // flag the new viewport videoElementClone.addEventListener('canplaythrough', canPlayThroughCallback); // add callback to seek video to previous time once loaded to that point videoSource.src = breakpoints[nowBreakpoint].src; // set the source for the new viewport video videoSource.type = breakpoints[nowBreakpoint].type; videoElementClone.append(videoSource); // add the source to the new video element parentElement.append(videoElementClone); // append the new video element videoElement.remove(); // remove the old video element this.setVideo(videoElementClone); // save new video element this.onViewportChange(); // inform other objects of the new video element }; return AdaptiveVideo; }(); /** * Used to determine when a video is visible and ready to be loaded. */ var VideoLazyLoader = /*#__PURE__*/function () { /** * Constructor * @param {Object} opts Options for the lazy loader */ function VideoLazyLoader(opts) { var _window$top$document; this.scrollTimeout = 100; this.shown = false; var video = opts.video, onShown = opts.onShown; this.video = video; this.onShown = onShown; this.contentScrollViewEle = (_window$top$document = window.top.document) == null ? void 0 : _window$top$document.getElementById(Selector$N.CONTENT_SCROLL_VIEW); this.viewportThreshold = this.video.dataset.videoInviewport ? 0.5 : 0; if (this.isScrolledIntoView(this.viewportThreshold)) { this.onShown(); } else { this.bindEvents(); } } /** * Determines if video is scrolled into view * @param {Number} options number with options, threshold value is between 0 and 1. * @returns true if visible */ var _proto2 = VideoLazyLoader.prototype; _proto2.isScrolledIntoView = function isScrolledIntoView(viewportThreshold) { if (viewportThreshold === void 0) { viewportThreshold = 0; } var _this$video$getBoundi = this.video.getBoundingClientRect(), top = _this$video$getBoundi.top, height = _this$video$getBoundi.height; var browserHeight = window.innerHeight; // If the window's document is not the root of the HTML (usually in edit/preview mode), then // window.innerHeight will not contain the necessary scroll element // and the ContentScrollView needs to be used instead. if (window !== window.top && this.contentScrollViewEle) { // ContentScrollView's client height is the equivalent to the window.innerHeight browserHeight = this.contentScrollViewEle.clientHeight; // ContentScrollView's scrollTop is the equivalent to the amount scrolled browserHeight += this.contentScrollViewEle.scrollTop; } return viewportThreshold ? top + height * viewportThreshold <= browserHeight : top <= browserHeight; } /** * Determines if the video is visible. If it is, it fires the onShown event * videoInViewport determines fires the onShown event when the half of video visible in viewport. */; _proto2.scrollThrottleFunction = function scrollThrottleFunction() { if (!this.shown && this.isScrolledIntoView(this.viewportThreshold)) { this.shown = true; this.onShown(); } } /** * Binds the window events needed to determine if video should be loaded */; _proto2.bindEvents = function bindEvents() { var scrolledThrottleFunction = throttle(this.scrollTimeout, this.scrollThrottleFunction.bind(this)); // If the window's document is not the root of the HTML (usually in edit/preview mode), then // window will not contain any elements that actually scroll, so // the scroll event listener is attached to the document's element that actually scrolls if (window !== window.top && this.contentScrollViewEle) { this.contentScrollViewEle.addEventListener('scroll', scrolledThrottleFunction); } else { window.addEventListener('scroll', scrolledThrottleFunction); } window.addEventListener('resize', scrolledThrottleFunction); }; return VideoLazyLoader; }(); var VideoExtension = /*#__PURE__*/function () { var _proto3 = VideoExtension.prototype; _proto3._playVideo = function _playVideo() { if (this.video.paused) { this._toggleMediaControlGlyph('pause'); this._setAriaLabelPrefix('pause'); this.video.play(); // reset video timer if it has ended if (this.isEnded(this.video)) { this.video.currentTime = 0; } } }; _proto3._pauseVideo = function _pauseVideo() { if (!this.video.paused) { this._toggleMediaControlGlyph('play'); this._setAriaLabelPrefix('play'); this.video.pause(); } }; _proto3._setAriaLabelPrefix = function _setAriaLabelPrefix(controlType) { if (this.mediaControlEl) { var ariaLabelSuffix = this.mediaControlEl.getAttribute(Selector$N.ARIA_LABEL_SUFFIX); var ariaLabelPrefix = controlType === 'pause' ? this.mediaControlEl.getAttribute(Selector$N.PAUSE_ALT_TEXT_PREFIX) : this.mediaControlEl.getAttribute(Selector$N.PLAY_ALT_TEXT_PREFIX); this.mediaControlEl.setAttribute('aria-label', "" + (ariaLabelPrefix != null ? ariaLabelPrefix : '') + (ariaLabelSuffix != null ? ariaLabelSuffix : '')); } } /** * Toggles the video button from play to pause or visa versa */; _proto3._toggleVideoButton = function _toggleVideoButton() { if (this.video.paused) { this._playVideo(); } else { this._pauseVideo(); } }; _proto3._toggleMediaControlGlyph = function _toggleMediaControlGlyph(setGlyph) { if (this.mediaControlSpanEl) { var pauseGlyphClass = this.mediaControlEl.dataset.pauseGlyphClass || Selector$N.PAUSE_GLYPH_CLASS; var playGlyphClass = this.mediaControlEl.dataset.playGlyphClass || Selector$N.PLAY_GLYPH_CLASS; if (setGlyph === 'play') { this.mediaControlSpanEl.classList.remove(pauseGlyphClass); this.mediaControlSpanEl.classList.add(playGlyphClass); } else { this.mediaControlSpanEl.classList.remove(playGlyphClass); this.mediaControlSpanEl.classList.add(pauseGlyphClass); } } } /** * Determines if a video is done playing * @param {HTMLElement} video Video to test * @returns True if the video is ended or has reached the end of its duration */; _proto3.isEnded = function isEnded(video) { return video.isEnded || video.currentTime === video.duration; } /** * Attaches needed events */; _proto3.attachEventsToVideo = function attachEventsToVideo() { var _this3 = this; // On video ended, update play/pause glyph this.video.addEventListener('ended', function () { if (_this3.isEnded(_this3.video)) { _this3._toggleMediaControlGlyph('play'); _this3._setAriaLabelPrefix('play'); } }); } /** * Loads video */; _proto3.loadVideo = function loadVideo() { var _this4 = this; this.video.preload = 'auto'; this.video.autoplay = this.video.dataset.autoplay; this.responser = new AdaptiveVideo(this.video, function (videoElement) { _this4.video = videoElement; _this4.attachEventsToVideo(); // If auto playing, change play glyph to pause glyph if (_this4.video.autoplay && _this4.video.paused) { _this4._toggleMediaControlGlyph('pause'); _this4._setAriaLabelPrefix('pause'); } }); }; function VideoExtension(opts) { var el = opts.el, mediaControlSpanEl = opts.mediaControlSpanEl, toggleVideoButton = opts.toggleVideoButton; this.video = el.querySelector('video'); this.mediaControlEl = el.querySelector("." + Selector$N.M365_VIDEO_CONTROL) || el.querySelector("." + Selector$N.MEDIA_CONTROL); this.events = []; if (this.mediaControlEl) { this.mediaControlSpanEl = mediaControlSpanEl || this.mediaControlEl.querySelector("span"); this.toggleVideoButton = toggleVideoButton || this._toggleVideoButton.bind(this); this.events.push({ el: this.mediaControlEl, type: 'click', handler: this.toggleVideoButton.bind(this) }); // initially set aria-label for media control button this._setAriaLabelPrefix('play'); } if (this.video.dataset.lazyload) { this.lazyLoader = new VideoLazyLoader({ video: this.video, onShown: this.loadVideo.bind(this) }); } else { this.loadVideo(); } if (this.events.length > 0) { Util$1.addEvents(this.events); } } return VideoExtension; }(); var $$v = _export; var $find = arrayIteration.find; var addToUnscopables$1 = addToUnscopables$4; var FIND = 'find'; var SKIPS_HOLES$1 = true; // Shouldn't skip holes // eslint-disable-next-line es/no-array-prototype-find -- testing if (FIND in []) Array(1)[FIND](function () { SKIPS_HOLES$1 = false; }); // `Array.prototype.find` method // https://tc39.es/ecma262/#sec-array.prototype.find $$v({ target: 'Array', proto: true, forced: SKIPS_HOLES$1 }, { find: function find(callbackfn /* , that = undefined */) { return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables addToUnscopables$1(FIND); var $$u = _export; var uncurryThis$h = functionUncurryThisClause; var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f; var toLength$1 = toLength$5; var toString$6 = toString$i; var notARegExp = notARegexp; var requireObjectCoercible$3 = requireObjectCoercible$b; var correctIsRegExpLogic = correctIsRegexpLogic; // eslint-disable-next-line es/no-string-prototype-startswith -- safe var nativeStartsWith = uncurryThis$h(''.startsWith); var stringSlice$3 = uncurryThis$h(''.slice); var min$1 = Math.min; var CORRECT_IS_REGEXP_LOGIC = correctIsRegExpLogic('startsWith'); // https://github.com/zloirock/core-js/pull/702 var MDN_POLYFILL_BUG = !CORRECT_IS_REGEXP_LOGIC && !!function () { var descriptor = getOwnPropertyDescriptor$2(String.prototype, 'startsWith'); return descriptor && !descriptor.writable; }(); // `String.prototype.startsWith` method // https://tc39.es/ecma262/#sec-string.prototype.startswith $$u({ target: 'String', proto: true, forced: !MDN_POLYFILL_BUG && !CORRECT_IS_REGEXP_LOGIC }, { startsWith: function startsWith(searchString /* , position = 0 */) { var that = toString$6(requireObjectCoercible$3(this)); notARegExp(searchString); var index = toLength$1(min$1(arguments.length > 1 ? arguments[1] : undefined, that.length)); var search = toString$6(searchString); return nativeStartsWith ? nativeStartsWith(that, search, index) : stringSlice$3(that, index, index + search.length) === search; } }); var biDirectional = Util$1.isBiDirectional(); var ClassName$u = { SHOW: 'show', FADE: 'fade', FADING_OUT: 'fading-out', ACTIVE: 'active', FLYOUT: 'flyout' }; var Default$5 = { START: biDirectional ? 'right' : 'left', END: biDirectional ? 'left' : 'right', ALIGNMENT: 'start' }; var DefaultReflow = { left: ['left', 'bottom', 'top', 'right'], right: ['right', 'bottom', 'top', 'left'], top: ['top', 'right', 'bottom', 'left'], bottom: ['bottom', 'right', 'top', 'left'] }; /** * Private functions */ function _hasReflow(node) { if (node.hasAttribute('data-disable-reflow') && node.getAttribute('data-disable-reflow') !== 'false') { return false; } return true; } /** * Get the placement of a flyout. * @param {string?} str - The string to parse. * @param {string} [defaultValue=start] - The default value to fallback to. * @returns {string} The placement of the flyout. */ function _getPlacement(str, defaultValue) { if (defaultValue === void 0) { defaultValue = Default$5.END; } switch (str) { case 'top': case 'bottom': return str; case 'left': case 'start': return Default$5.START; case 'right': case 'end': return Default$5.END; default: return defaultValue; } } /** * Get the alignment of a flyout. * @param {string?} str - The string to parse. * @param {string} [defaultValue=start] - The default value to fallback to. * @returns {string} The alignment enum of the flyout. */ function _getAlignment(str, defaultValue) { if (defaultValue === void 0) { defaultValue = Default$5.ALIGNMENT; } switch (str) { case 'center': case 'start': case 'end': return str; default: return defaultValue; } } /** * Get the related menu for an element. * @param {HTMLElement} node - The element to find a related menu for, typically the flyout instance target. * @returns {HTMLElement?} The menu element. */ function _getRelatedMenu(node) { if (node.attributes['aria-controls']) { return document.querySelector("#" + node.attributes['aria-controls'].value); } } /** * Get the X distance for menu positioning. * @param {string} textAlignment - The text alignment of the flyout's parent. Affects the left/right CSS positioning, therefore changes the translate coordinates. * @param {string} placement - Menu's placement in relation to the flyout trigger: 'left', 'right', 'top', or 'bottom'. * @param {string} alignment - Menu's alignment with the flyout trigger, correlates to read order: 'center', 'start', 'end'. * @returns {number} The X distance to translate the menu. * @this Flyout */ function _getTranslateX(textAlignment, placement, alignment) { var translateX = 0; var overflowOffset = 0; /* eslint-disable no-lonely-if */ // If text is aligned left if (textAlignment === 'left') { if (placement === 'right') { // Place menu right of trigger translateX += this.boundingRect.el.width + this.offset; } else if (placement === 'left') { // Place menu left of trigger translateX -= this.boundingRect.menu.width + this.offset; } else { // Adjust alignment for top and bottom menus if (alignment === 'center') { translateX -= (this.boundingRect.menu.width - this.boundingRect.el.width) / 2; } else if (alignment === 'end' && !biDirectional || alignment === 'start' && biDirectional) { translateX -= this.boundingRect.menu.width - this.boundingRect.el.width; // Shift menu left if needed to fit menu in tiny window sizes, record offset for future use overflowOffset = _shiftLeftToFitWindow.call(this, translateX); translateX += overflowOffset; } else { // Shift menu right if needed to fit menu in tiny window sizes, record offset for future use overflowOffset = _shiftRightToFitWindow.call(this, translateX); translateX += overflowOffset; } } // If text is aligned right } else { if (placement === 'right') { translateX += this.boundingRect.menu.width + this.offset; } else if (placement === 'left') { translateX -= this.boundingRect.el.width + this.offset; } else { if (alignment === 'center') { translateX += (this.boundingRect.menu.width - this.boundingRect.el.width) / 2; } else if (alignment === 'start' && !biDirectional || alignment === 'end' && biDirectional) { translateX += this.boundingRect.menu.width - this.boundingRect.el.width; // Shift menu right if needed to fit menu in tiny window sizes, record offset for future use overflowOffset = _shiftRightToFitWindow.call(this, translateX); translateX += overflowOffset; } else { // Shift menu left if needed to fit menu in tiny window sizes, record offset for future use overflowOffset = _shiftLeftToFitWindow.call(this, translateX); translateX += overflowOffset; } } } /* eslint-enable no-lonely-if */ // Save any overflowOffset (rounded) to the instance for later use this.overflowOffset = Math.round(overflowOffset); return translateX; } /** * Returns distance in pixels needed to prevent overflow on the right side of the window. * @returns {number} The distance in pixels to shift the menu left. */ function _shiftLeftToFitWindow() { var xOverflow = this.boundingRect.window.width - (this.boundingRect.el.x + this.boundingRect.el.width) + this.boundingRect.menu.width; return xOverflow > this.boundingRect.window.width ? xOverflow - this.boundingRect.window.width : 0; } /** * Returns distance in pixels needed to prevent overflow on the left side of the window. * @returns {number} The distance in pixels to shift the menu right. */ function _shiftRightToFitWindow() { var xOverflow = this.boundingRect.el.x + this.boundingRect.menu.width; return xOverflow > this.boundingRect.window.width ? -(xOverflow - this.boundingRect.window.width) : 0; } /** * Get the Y distance for menu positioning. * @param {string} placement - Menu's placement in relation to the flyout trigger: 'left', 'right', 'top', or 'bottom'. * @param {string} alignment - Menu's alignment with the flyout trigger, correlates to read order: 'center', 'start', 'end'. * @returns {number} The Y distance to translate the menu. * @this Flyout */ function _getTranslateY(placement, alignment) { var translateY = 0; // Place menu above trigger if (placement === 'top') { translateY -= this.boundingRect.menu.height + this.offset; // Place menu below trigger } else if (placement === 'bottom') { translateY += this.boundingRect.el.height + this.offset; } else { // Adjust alignment for left and right menus /* eslint-disable no-lonely-if */ if (alignment === 'center') { translateY -= (this.boundingRect.menu.height - this.boundingRect.el.height) / 2; } else if (alignment === 'end') { translateY -= this.boundingRect.menu.height - this.boundingRect.el.height; } /* eslint-enable no-lonely-if */ } return translateY; } var Flyout = /*#__PURE__*/function () { /** * Create a Flyout instance * @param {Object} opts - The flyout options * @param {HTMLElement} opts.el - The element that toggles the flyout * @param {HTMLElement} [opts.menu] - The element that defines the flyout menu * @param {string} [opts.placement=right] - A string that defines the placement of the menu * @param {string} [opts.alignment=start] - A string that defines the alignment of the menu * @param {number} [opts.offset=0] - The number of pixels the menu should be offset from the trigger * @param {boolean} [opts.enableReflow=true] - Whether the menu should reflow to fit within the window as best as possible * @param {boolean} [opts.enableFade=true] - Whether the menu should fade in and out */ function Flyout(opts) { this.el = opts.el; // the toggle this.menu = opts.menu || _getRelatedMenu(this.el); // the flyout menu this.parent = this.el.offsetParent || this.el.parentElement; this.placement = _getPlacement(opts.placement || this.el.getAttribute('data-placement')); this.alignment = _getAlignment(opts.alignment || this.el.getAttribute('data-alignment')); this.offset = opts.offset ? parseInt(opts.offset, 10) : 0; this.translateX = 0; this.translateY = 0; this.overflowOffset = 0; this.enableReflow = typeof opts.enableReflow === 'boolean' ? opts.enableReflow : _hasReflow(this.el); this.enableFade = typeof opts.enableFade === 'boolean' ? opts.enableFade : this.menu.classList.contains(ClassName$u.FADE); this.shown = false; // Ensure position is set on parent element, needed for absolute positioning of menu var parentPositionProperty = window.getComputedStyle(this.parent).position; if (parentPositionProperty !== 'relative' && parentPositionProperty !== 'absolute') { this.parent.style.position = 'relative'; } // Setup fade animation based on options supplied if (opts.enableFade === true) { this.menu.classList.add(ClassName$u.FADE); } else if (opts.enableFade === false) { this.menu.classList.remove(ClassName$u.FADE); } if (!this.menu.hasAttribute('tabindex')) { this.menu.setAttribute('tabindex', '-1'); } } /** * Get the current position of the menu based on enableReflow setting * @returns {object} The instance's position object */ var _proto = Flyout.prototype; /** * Calculates and sets the reflow position value (placement and alignment) */ _proto.calcReflowPosition = function calcReflowPosition() { // Calculate the distance of the trigger from each side of the window var distFrom = { top: this.boundingRect.el.top, bottom: window.innerHeight - this.boundingRect.el.bottom, left: this.boundingRect.el.left, right: document.body.clientWidth - this.boundingRect.el.right }; // Add the menu offset spacing to the width and height of the menu var menuWidth = this.boundingRect.menu.width + this.offset; var menuHeight = this.boundingRect.menu.height + this.offset; var placements = DefaultReflow[this.placement].slice(); // Calculate the distance needed for the menu to fit inside the window var distX = menuWidth - this.boundingRect.el.width; var distY = menuHeight - this.boundingRect.el.height; if (this.alignment === 'center') { distX /= 2; distY /= 2; } // Copy values so we don't override original instance property var placement = this.placement, alignment = this.alignment; // Eliminate the placements that won't fit if (distFrom.left < menuWidth) { placements.splice(placements.indexOf('left'), 1); } if (distFrom.right < menuWidth) { placements.splice(placements.indexOf('right'), 1); } if (distFrom.top < menuHeight) { placements.splice(placements.indexOf('top'), 1); } if (distFrom.bottom < menuHeight) { placements.splice(placements.indexOf('bottom'), 1); } placement = placements.length ? placements.shift() : 'bottom'; // fallback placement is always bottom // Adjust the alignment of the chosen placement // NOTE: Keep this logic as is for readability and sanity if (placement === 'bottom' || placement === 'top') { // If neither side is ideal if (distFrom.left < distX && distFrom.right < distX) { // Align to the Read order alignment = 'start'; // LTR: If distFrom.left < distX } else if (distFrom[Default$5.START] < distX) { alignment = 'start'; } else if (distFrom[Default$5.END] <= distX) { alignment = 'end'; } } else { // If placement is 'left' or 'right' // If neither above nor below is ideal /* eslint-disable no-lonely-if */ if (distFrom.top < distY && distFrom.bottom < distY) { // Force the beginning of the menu content to be in view, // which should force window to grow, enabling user to scroll to view entire menu alignment = 'start'; } else if (distFrom.top < distY) { alignment = 'start'; } else if (distFrom.bottom <= distY) { alignment = 'end'; } /* eslint-enable no-lonely-if */ } this.reflowPosition = { placement: placement, alignment: alignment }; } /** * Position the flyout menu */; _proto.positionMenu = function positionMenu() { if (this.enableReflow) { this.calcReflowPosition(); } var position = this.currentPosition; // Get the direction of text flow (affected by cascade of text-align css property and/or RTL) var textAlignProperty = window.getComputedStyle(this.parent).textAlign; var textAlignment = Default$5.START; if (textAlignProperty === 'left' || textAlignProperty === 'right') { textAlignment = textAlignProperty; } else if (textAlignProperty === 'end') { textAlignment = Default$5.END; } // Set the transformation's "origin" based on text alignment this.menu.style.top = Math.round(this.boundingRect.el.top - this.boundingRect.parent.top) + 'px'; if (textAlignment === 'left') { this.menu.style.left = Math.round(this.boundingRect.el.left - this.boundingRect.parent.left) + 'px'; this.menu.style.right = 'auto'; } else { this.menu.style.left = 'auto'; this.menu.style.right = -Math.round(this.boundingRect.el.right - this.boundingRect.parent.right) + 'px'; } // Allow the menu to define its own width according to the needed width of its contents this.menu.style.minWidth = Math.round(this.boundingRect.menu.width) + 'px'; // Calculate the x and y distances needed to push the menu to the correct position. this.translateX = Math.round(_getTranslateX.call(this, textAlignment, position.placement, position.alignment)); this.translateY = Math.round(_getTranslateY.call(this, position.placement, position.alignment)); // Set the transform style this.menu.style.transform = "translate(" + this.translateX + "px, " + this.translateY + "px)"; // Reset menu classes associated with position this.menu.classList.remove(ClassName$u.FLYOUT + "-left", ClassName$u.FLYOUT + "-right", ClassName$u.FLYOUT + "-top", ClassName$u.FLYOUT + "-bottom", ClassName$u.FLYOUT + "-align-start", ClassName$u.FLYOUT + "-align-end", ClassName$u.FLYOUT + "-align-center"); // Set the menu classes associated with position this.menu.classList.add(ClassName$u.FLYOUT + "-" + position.placement, ClassName$u.FLYOUT + "-align-" + position.alignment); } /** * Show the menu */; _proto.show = function show() { // Record window width prior to showing the menu, // otherwise the menu will effect the window width var windowWidth = window.innerWidth; this.shown = true; this.el.classList.add(ClassName$u.ACTIVE); this.menu.classList.add(ClassName$u.SHOW); // Store the coordinates of the associated elements for ease of reuse now that the menu has layout this.boundingRect = { el: this.el.getBoundingClientRect(), menu: this.menu.getBoundingClientRect(), parent: this.parent.getBoundingClientRect(), window: { width: windowWidth } }; this.positionMenu(); } /** * Hide the menu * @param {Object} [opts={}] - Options for hiding the menu * @param {boolean} [opts.setFocus=true] - Whether or not the focus should be set on the toggling element; defaults to true */; _proto.hide = function hide(opts) { var _this = this; if (opts === void 0) { opts = {}; } // Default behavior should be to set focus on toggling element var setFocus = typeof opts.setFocus === 'boolean' ? opts.setFocus : true; this.shown = false; this.el.classList.remove(ClassName$u.ACTIVE); this.menu.classList.remove(ClassName$u.SHOW); // 1. Add a class that triggers a CSS animation // 2. Create an event listener that removes the class once it's animation is complete if (this.enableFade) { this.menu.addEventListener('animationend', function () { _this.menu.classList.remove(ClassName$u.FADING_OUT); }, { once: true }); // 2. this.menu.classList.add(ClassName$u.FADING_OUT); // 1. } if (setFocus) { // Set focus on the toggle this.el.focus(); } } /** * Toggle the menu state */; _proto.toggle = function toggle() { if (this.shown) { this.hide(); } else { this.show(); } } /** * Update the flyout instance * @param {Object} [opts={}] - Options for updating the flyout instance */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } // Change the placement of the menu if (opts.placement) { this.placement = _getPlacement(opts.placement); } // Change the alignment of the menu if (opts.alignment) { this.alignment = _getAlignment(opts.alignment); } // Change the offset of the menu if (typeof opts.offset !== 'undefined') { var offset = parseInt(opts.offset, 10); if (!isNaN(offset)) { this.offset = offset; } } // Change whether the menu should reflow if (typeof opts.enableReflow === 'boolean') { this.enableReflow = opts.enableReflow; } // Change whether the menu should enable a fade animation if (typeof opts.enableFade === 'boolean' && opts.enableFade !== this.enableFade) { this.enableFade = opts.enableFade; this.menu.classList.toggle(ClassName$u.FADE); } // Update the menu position if its open if (this.shown) { this.positionMenu(); } }; _createClass(Flyout, [{ key: "currentPosition", get: function get() { var position = { placement: this.placement, alignment: this.alignment }; if (this.enableReflow) { return this.reflowPosition || position; // fallback to original position, if undefined } return position; } }]); return Flyout; }(); var EventName$M = { ON_HIDE: 'onHide', ON_SHOW: 'onShow', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove' }; var ClassName$t = { SHOW: 'show', ACTIVE: 'active', BOTTOM: 'dropdown', TOP: 'dropup', RIGHT: 'dropright', LEFT: 'dropleft', MENU_RIGHT: 'dropdown-menu-right', MENU_LEFT: 'dropdown-menu-left' }; var Default$4 = Object.assign({}, Default$5, { PLACEMENT: 'bottom' }); var dropdowns = []; /** * The event handler for when the target element is clicked. * @param {MouseEvent} event - The event object. */ function _elOnClick(event) { // Prevent page from trying to scroll to a page anchor. event.preventDefault(); this.toggle(); } /** * The event handler for when a key is pressed on the target element. * @param {KeyboardEvent} event - The event object. */ function _elOnKeydown(event) { // Override keyboard functionality if element is an anchor. if (event.keyCode === Util$1.keyCodes.SPACE || event.keyCode === Util$1.keyCodes.ENTER) { // Trigger the same event as a click for consistency. event.preventDefault(); _elOnClick.bind(this)(event); } // Events for when the menu is open. if (this.shown) { // Menu should close with the Esc key. if (event.keyCode === Util$1.keyCodes.ESC) { event.stopPropagation(); this.hide(); } if (this.arrowableItems && event.keyCode === Util$1.keyCodes.ARROW_DOWN) { // Prevent scrolling page on down arrow. event.preventDefault(); // Set focus to first focusable element in menu. this.arrowableItems[0].focus(); } } } /** * The event handler for when a key is pressed on the menu * @param {KeyboardEvent} event - The event object */ function _menuOnKeydown$1(event) { if (event.keyCode === Util$1.keyCodes.ESC) { this.hide(); } if (this.arrowableItems && (event.keyCode === Util$1.keyCodes.ARROW_DOWN || event.keyCode === Util$1.keyCodes.ARROW_UP)) { // Prevent scrolling page on down arrow. event.preventDefault(); if (event.keyCode === Util$1.keyCodes.ARROW_DOWN && document.activeElement !== this.arrowableItems[this.arrowableItems.length - 1]) { // If the down key is pressed and its NOT on the last item in the list this.arrowableItems[this.arrowableItems.indexOf(document.activeElement) + 1].focus(); } else if (event.keyCode === Util$1.keyCodes.ARROW_UP && document.activeElement !== this.arrowableItems[0]) { // If the up key is pressed and its NOT on the first item in the list this.arrowableItems[this.arrowableItems.indexOf(document.activeElement) - 1].focus(); } else { this.hide(); } } } /** * The event handler for when mousedown is triggered on the document. * Happens before mouseup, click, and focusin to control closing of the menu without conflicting with other events. * @param {Event} event - The event object */ function _documentOnMousedown(event) { if (this.shown && !this.menu.contains(event.target) && !this.el.contains(event.target)) { this.hide({ setFocus: false }); } } /** * The event handler for when the document receives focus * @param {Event} event - The event object */ function _documentOnFocusin(event) { if (this.shown && !this.menu.contains(event.target)) { this.hide(); } } /** * Get the placement of a dropdown from the parent node class * @param {HTMLElement} node - The element to check for a placement class * @returns {string?} The placement of the dropdown */ function _getPlacementFromClass(node) { for (var i = 0; i < node.classList.length; i++) { switch (node.classList[i]) { case ClassName$t.BOTTOM: return 'bottom'; case ClassName$t.TOP: return 'top'; case ClassName$t.LEFT: return 'start'; case ClassName$t.RIGHT: return 'end'; } } } /** * Apply the correct `drop{direction}` class according to the placement * @param {HTMLElement} node - The element to apply the class to */ function _updatePlacementClass(node, placement) { var className = ClassName$t[placement.toUpperCase()]; node.classList.remove(ClassName$t.BOTTOM, ClassName$t.TOP, ClassName$t.RIGHT, ClassName$t.LEFT); node.classList.add(className); } var Dropdown = /*#__PURE__*/function (_Flyout) { _inheritsLoose(Dropdown, _Flyout); /** * Create a Dropdown instance (inheriting Flyout) * @param {Object} opts - The flyout options * @param {HTMLElement} opts.el - The element that toggles the flyout * @param {HTMLElement} [opts.menu] - The element that defines the flyout menu * @param {string} [opts.placement=bottom] - A string that defines the placement of the menu * @param {string} [opts.alignment=start] - A string that defines the alignment of the menu * @param {number} [opts.offset=0] - The number of pixels the menu should be offset from the trigger * @param {boolean} [opts.enableReflow=true] - Whether the menu should reflow to fit within the window as best as possible */ function Dropdown(opts) { var _this; // Set super options var flyoutOpts = Object.assign({}, opts); var parent = flyoutOpts.el.offsetParent || flyoutOpts.el.parentElement; var placementFromClass = _getPlacementFromClass(parent); flyoutOpts.placement = opts.placement || placementFromClass || flyoutOpts.el.getAttribute('data-placement') || Default$4.PLACEMENT; flyoutOpts.enableFade = false; _this = _Flyout.call(this, flyoutOpts) || this; // Dropdown-specific setup // Ensure `drop` class matches the placement of the menu // Invert var invertedPlacement = _getPlacement(_this.placement, Default$4.PLACEMENT); _updatePlacementClass(_this.parent, invertedPlacement); if (_this.menu.nodeName.toLowerCase() === 'ul' || _this.menu.nodeName.toLowerCase() === 'ol') { _this.arrowableItems = Util$1.getTabbableElements(_this.menu); } // Add event handlers. _this.events = [{ el: _this.el, type: 'click', handler: _elOnClick.bind(_assertThisInitialized(_this)) }, { el: _this.el, type: 'keydown', handler: _elOnKeydown.bind(_assertThisInitialized(_this)) }, { el: _this.menu, type: 'keydown', handler: _menuOnKeydown$1.bind(_assertThisInitialized(_this)) }, { el: document, type: 'mousedown', handler: _documentOnMousedown.bind(_assertThisInitialized(_this)) }, { el: document, type: 'focusin', handler: _documentOnFocusin.bind(_assertThisInitialized(_this)) }]; Util$1.addEvents(_this.events); // Add mutation observers. _this.menuObserver = new MutationObserver(_this.update.bind(_assertThisInitialized(_this))); _this.menuObserver.observe(_this.menu, { childList: true, subtree: true }); dropdowns.push(_assertThisInitialized(_this)); return _this; } /** * Show the menu */ var _proto = Dropdown.prototype; _proto.show = function show() { // Create and dispatch custom event this[EventName$M.ON_SHOW] = new CustomEvent(EventName$M.ON_SHOW, { bubbles: true, cancelable: true }); this.el.dispatchEvent(this[EventName$M.ON_SHOW]); if (this[EventName$M.ON_SHOW].defaultPrevented) { return; } _Flyout.prototype.show.call(this); this.el.setAttribute('aria-expanded', this.shown); } /** * Hide the menu * @param {Object} [opts={}] - Options for hiding the menu * @param {boolean} [opts.setFocus=true] - Whether or not the focus should be set on the toggling element; defaults to true */; _proto.hide = function hide(opts) { if (opts === void 0) { opts = {}; } // Create and dispatch custom event this[EventName$M.ON_HIDE] = new CustomEvent(EventName$M.ON_HIDE, { bubbles: true, cancelable: true }); this.el.dispatchEvent(this[EventName$M.ON_HIDE]); if (this[EventName$M.ON_HIDE].defaultPrevented) { return; } _Flyout.prototype.hide.call(this, opts); this.el.setAttribute('aria-expanded', this.shown); } /** * Update the dropdown instance * @param {Object} [opts={}] - Options for updating the instance */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } var flyoutOpts = Object.assign({}, opts); flyoutOpts.enableFade = false; // disable flyout fade feature if (typeof this.arrowableItems !== 'undefined') { // Update the list of known focusable items within the menu. this.arrowableItems = Util$1.getTabbableElements(this.menu); } if (opts.placement) { flyoutOpts.placement = _getPlacement(opts.placement, Default$4.PLACEMENT); } _Flyout.prototype.update.call(this, flyoutOpts); // Invert dropleft/dropright classes that switch orientation in RTL var invertedPlacement = _getPlacement(this.placement, Default$4.PLACEMENT); _updatePlacementClass(this.parent, invertedPlacement); // Create and dispatch custom event this[EventName$M.ON_UPDATE] = new CustomEvent(EventName$M.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$M.ON_UPDATE]); } /** * Remove the dropdown instance */; _proto.remove = function remove() { // Remove event handlers, observers, etc. Util$1.removeEvents(this.events); // Remove this reference from the array of instances var index = dropdowns.indexOf(this); dropdowns.splice(index, 1); // Create and dispatch custom event this[EventName$M.ON_REMOVE] = new CustomEvent(EventName$M.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$M.ON_REMOVE]); } /** * Get an array of dropdown instances * @returns {Object[]} Array of dropdown instances */; Dropdown.getInstances = function getInstances() { return dropdowns; }; return Dropdown; }(Flyout); var $$t = _export; var DESCRIPTORS$b = descriptors; var defineProperty$5 = objectDefineProperty.f; // `Object.defineProperty` method // https://tc39.es/ecma262/#sec-object.defineproperty // eslint-disable-next-line es/no-object-defineproperty -- safe $$t({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty$5, sham: !DESCRIPTORS$b }, { defineProperty: defineProperty$5 }); var internalMetadata = {exports: {}}; var objectGetOwnPropertyNamesExternal = {}; var toAbsoluteIndex = toAbsoluteIndex$4; var lengthOfArrayLike$3 = lengthOfArrayLike$b; var createProperty = createProperty$5; var $Array = Array; var max = Math.max; var arraySliceSimple = function (O, start, end) { var length = lengthOfArrayLike$3(O); var k = toAbsoluteIndex(start, length); var fin = toAbsoluteIndex(end === undefined ? length : end, length); var result = $Array(max(fin - k, 0)); for (var n = 0; k < fin; k++, n++) createProperty(result, n, O[k]); result.length = n; return result; }; /* eslint-disable es/no-object-getownpropertynames -- safe */ var classof$4 = classofRaw$2; var toIndexedObject$2 = toIndexedObject$a; var $getOwnPropertyNames = objectGetOwnPropertyNames.f; var arraySlice$4 = arraySliceSimple; var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : []; var getWindowNames = function (it) { try { return $getOwnPropertyNames(it); } catch (error) { return arraySlice$4(windowNames); } }; // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window objectGetOwnPropertyNamesExternal.f = function getOwnPropertyNames(it) { return windowNames && classof$4(it) == 'Window' ? getWindowNames(it) : $getOwnPropertyNames(toIndexedObject$2(it)); }; // FF26- bug: ArrayBuffers are non-extensible, but Object.isExtensible does not report it var fails$e = fails$I; var arrayBufferNonExtensible = fails$e(function () { if (typeof ArrayBuffer == 'function') { var buffer = new ArrayBuffer(8); // eslint-disable-next-line es/no-object-isextensible, es/no-object-defineproperty -- safe if (Object.isExtensible(buffer)) Object.defineProperty(buffer, 'a', { value: 8 }); } }); var fails$d = fails$I; var isObject$8 = isObject$l; var classof$3 = classofRaw$2; var ARRAY_BUFFER_NON_EXTENSIBLE = arrayBufferNonExtensible; // eslint-disable-next-line es/no-object-isextensible -- safe var $isExtensible = Object.isExtensible; var FAILS_ON_PRIMITIVES = fails$d(function () { $isExtensible(1); }); // `Object.isExtensible` method // https://tc39.es/ecma262/#sec-object.isextensible var objectIsExtensible = (FAILS_ON_PRIMITIVES || ARRAY_BUFFER_NON_EXTENSIBLE) ? function isExtensible(it) { if (!isObject$8(it)) return false; if (ARRAY_BUFFER_NON_EXTENSIBLE && classof$3(it) == 'ArrayBuffer') return false; return $isExtensible ? $isExtensible(it) : true; } : $isExtensible; var fails$c = fails$I; var freezing = !fails$c(function () { // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing return Object.isExtensible(Object.preventExtensions({})); }); var $$s = _export; var uncurryThis$g = functionUncurryThis; var hiddenKeys = hiddenKeys$5; var isObject$7 = isObject$l; var hasOwn$9 = hasOwnProperty_1; var defineProperty$4 = objectDefineProperty.f; var getOwnPropertyNamesModule = objectGetOwnPropertyNames; var getOwnPropertyNamesExternalModule = objectGetOwnPropertyNamesExternal; var isExtensible$1 = objectIsExtensible; var uid = uid$3; var FREEZING$1 = freezing; var REQUIRED = false; var METADATA = uid('meta'); var id$1 = 0; var setMetadata = function (it) { defineProperty$4(it, METADATA, { value: { objectID: 'O' + id$1++, // object ID weakData: {} // weak collections IDs } }); }; var fastKey$1 = function (it, create) { // return a primitive with prefix if (!isObject$7(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; if (!hasOwn$9(it, METADATA)) { // can't set metadata to uncaught frozen object if (!isExtensible$1(it)) return 'F'; // not necessary to add metadata if (!create) return 'E'; // add missing metadata setMetadata(it); // return object ID } return it[METADATA].objectID; }; var getWeakData$1 = function (it, create) { if (!hasOwn$9(it, METADATA)) { // can't set metadata to uncaught frozen object if (!isExtensible$1(it)) return true; // not necessary to add metadata if (!create) return false; // add missing metadata setMetadata(it); // return the store of weak collections IDs } return it[METADATA].weakData; }; // add metadata on freeze-family methods calling var onFreeze = function (it) { if (FREEZING$1 && REQUIRED && isExtensible$1(it) && !hasOwn$9(it, METADATA)) setMetadata(it); return it; }; var enable = function () { meta.enable = function () { /* empty */ }; REQUIRED = true; var getOwnPropertyNames = getOwnPropertyNamesModule.f; var splice = uncurryThis$g([].splice); var test = {}; test[METADATA] = 1; // prevent exposing of metadata key if (getOwnPropertyNames(test).length) { getOwnPropertyNamesModule.f = function (it) { var result = getOwnPropertyNames(it); for (var i = 0, length = result.length; i < length; i++) { if (result[i] === METADATA) { splice(result, i, 1); break; } } return result; }; $$s({ target: 'Object', stat: true, forced: true }, { getOwnPropertyNames: getOwnPropertyNamesExternalModule.f }); } }; var meta = internalMetadata.exports = { enable: enable, fastKey: fastKey$1, getWeakData: getWeakData$1, onFreeze: onFreeze }; hiddenKeys[METADATA] = true; var internalMetadataExports = internalMetadata.exports; var bind$6 = functionBindContext; var call$7 = functionCall; var anObject$5 = anObject$l; var tryToString$1 = tryToString$5; var isArrayIteratorMethod = isArrayIteratorMethod$2; var lengthOfArrayLike$2 = lengthOfArrayLike$b; var isPrototypeOf$2 = objectIsPrototypeOf; var getIterator$1 = getIterator$3; var getIteratorMethod$1 = getIteratorMethod$4; var iteratorClose = iteratorClose$2; var $TypeError$3 = TypeError; var Result = function (stopped, result) { this.stopped = stopped; this.result = result; }; var ResultPrototype = Result.prototype; var iterate$5 = function (iterable, unboundFunction, options) { var that = options && options.that; var AS_ENTRIES = !!(options && options.AS_ENTRIES); var IS_RECORD = !!(options && options.IS_RECORD); var IS_ITERATOR = !!(options && options.IS_ITERATOR); var INTERRUPTED = !!(options && options.INTERRUPTED); var fn = bind$6(unboundFunction, that); var iterator, iterFn, index, length, result, next, step; var stop = function (condition) { if (iterator) iteratorClose(iterator, 'normal', condition); return new Result(true, condition); }; var callFn = function (value) { if (AS_ENTRIES) { anObject$5(value); return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); } return INTERRUPTED ? fn(value, stop) : fn(value); }; if (IS_RECORD) { iterator = iterable.iterator; } else if (IS_ITERATOR) { iterator = iterable; } else { iterFn = getIteratorMethod$1(iterable); if (!iterFn) throw $TypeError$3(tryToString$1(iterable) + ' is not iterable'); // optimisation for array iterators if (isArrayIteratorMethod(iterFn)) { for (index = 0, length = lengthOfArrayLike$2(iterable); length > index; index++) { result = callFn(iterable[index]); if (result && isPrototypeOf$2(ResultPrototype, result)) return result; } return new Result(false); } iterator = getIterator$1(iterable, iterFn); } next = IS_RECORD ? iterable.next : iterator.next; while (!(step = call$7(next, iterator)).done) { try { result = callFn(step.value); } catch (error) { iteratorClose(iterator, 'throw', error); } if (typeof result == 'object' && result && isPrototypeOf$2(ResultPrototype, result)) return result; } return new Result(false); }; var isPrototypeOf$1 = objectIsPrototypeOf; var $TypeError$2 = TypeError; var anInstance$8 = function (it, Prototype) { if (isPrototypeOf$1(Prototype, it)) return it; throw $TypeError$2('Incorrect invocation'); }; var $$r = _export; var global$c = global$y; var uncurryThis$f = functionUncurryThis; var isForced$1 = isForced_1; var defineBuiltIn$7 = defineBuiltIn$g; var InternalMetadataModule$1 = internalMetadataExports; var iterate$4 = iterate$5; var anInstance$7 = anInstance$8; var isCallable$8 = isCallable$u; var isNullOrUndefined$3 = isNullOrUndefined$9; var isObject$6 = isObject$l; var fails$b = fails$I; var checkCorrectnessOfIteration$1 = checkCorrectnessOfIteration$3; var setToStringTag$4 = setToStringTag$7; var inheritIfRequired$2 = inheritIfRequired$4; var collection$3 = function (CONSTRUCTOR_NAME, wrapper, common) { var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1; var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1; var ADDER = IS_MAP ? 'set' : 'add'; var NativeConstructor = global$c[CONSTRUCTOR_NAME]; var NativePrototype = NativeConstructor && NativeConstructor.prototype; var Constructor = NativeConstructor; var exported = {}; var fixMethod = function (KEY) { var uncurriedNativeMethod = uncurryThis$f(NativePrototype[KEY]); defineBuiltIn$7(NativePrototype, KEY, KEY == 'add' ? function add(value) { uncurriedNativeMethod(this, value === 0 ? 0 : value); return this; } : KEY == 'delete' ? function (key) { return IS_WEAK && !isObject$6(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); } : KEY == 'get' ? function get(key) { return IS_WEAK && !isObject$6(key) ? undefined : uncurriedNativeMethod(this, key === 0 ? 0 : key); } : KEY == 'has' ? function has(key) { return IS_WEAK && !isObject$6(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); } : function set(key, value) { uncurriedNativeMethod(this, key === 0 ? 0 : key, value); return this; } ); }; var REPLACE = isForced$1( CONSTRUCTOR_NAME, !isCallable$8(NativeConstructor) || !(IS_WEAK || NativePrototype.forEach && !fails$b(function () { new NativeConstructor().entries().next(); })) ); if (REPLACE) { // create collection constructor Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); InternalMetadataModule$1.enable(); } else if (isForced$1(CONSTRUCTOR_NAME, true)) { var instance = new Constructor(); // early implementations not supports chaining var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance; // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false var THROWS_ON_PRIMITIVES = fails$b(function () { instance.has(1); }); // most early implementations doesn't supports iterables, most modern - not close it correctly // eslint-disable-next-line no-new -- required for testing var ACCEPT_ITERABLES = checkCorrectnessOfIteration$1(function (iterable) { new NativeConstructor(iterable); }); // for early implementations -0 and +0 not the same var BUGGY_ZERO = !IS_WEAK && fails$b(function () { // V8 ~ Chromium 42- fails only with 5+ elements var $instance = new NativeConstructor(); var index = 5; while (index--) $instance[ADDER](index, index); return !$instance.has(-0); }); if (!ACCEPT_ITERABLES) { Constructor = wrapper(function (dummy, iterable) { anInstance$7(dummy, NativePrototype); var that = inheritIfRequired$2(new NativeConstructor(), dummy, Constructor); if (!isNullOrUndefined$3(iterable)) iterate$4(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); return that; }); Constructor.prototype = NativePrototype; NativePrototype.constructor = Constructor; } if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { fixMethod('delete'); fixMethod('has'); IS_MAP && fixMethod('get'); } if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); // weak collections should not contains .clear method if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear; } exported[CONSTRUCTOR_NAME] = Constructor; $$r({ global: true, constructor: true, forced: Constructor != NativeConstructor }, exported); setToStringTag$4(Constructor, CONSTRUCTOR_NAME); if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP); return Constructor; }; var makeBuiltIn = makeBuiltInExports; var defineProperty$3 = objectDefineProperty; var defineBuiltInAccessor$6 = function (target, name, descriptor) { if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true }); if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true }); return defineProperty$3.f(target, name, descriptor); }; var defineBuiltIn$6 = defineBuiltIn$g; var defineBuiltIns$4 = function (target, src, options) { for (var key in src) defineBuiltIn$6(target, key, src[key], options); return target; }; var getBuiltIn$9 = getBuiltIn$e; var defineBuiltInAccessor$5 = defineBuiltInAccessor$6; var wellKnownSymbol$4 = wellKnownSymbol$o; var DESCRIPTORS$a = descriptors; var SPECIES$2 = wellKnownSymbol$4('species'); var setSpecies$2 = function (CONSTRUCTOR_NAME) { var Constructor = getBuiltIn$9(CONSTRUCTOR_NAME); if (DESCRIPTORS$a && Constructor && !Constructor[SPECIES$2]) { defineBuiltInAccessor$5(Constructor, SPECIES$2, { configurable: true, get: function () { return this; } }); } }; var create$3 = objectCreate; var defineBuiltInAccessor$4 = defineBuiltInAccessor$6; var defineBuiltIns$3 = defineBuiltIns$4; var bind$5 = functionBindContext; var anInstance$6 = anInstance$8; var isNullOrUndefined$2 = isNullOrUndefined$9; var iterate$3 = iterate$5; var defineIterator = iteratorDefine; var createIterResultObject = createIterResultObject$3; var setSpecies$1 = setSpecies$2; var DESCRIPTORS$9 = descriptors; var fastKey = internalMetadataExports.fastKey; var InternalStateModule$5 = internalState; var setInternalState$5 = InternalStateModule$5.set; var internalStateGetterFor$1 = InternalStateModule$5.getterFor; var collectionStrong$2 = { getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { var Constructor = wrapper(function (that, iterable) { anInstance$6(that, Prototype); setInternalState$5(that, { type: CONSTRUCTOR_NAME, index: create$3(null), first: undefined, last: undefined, size: 0 }); if (!DESCRIPTORS$9) that.size = 0; if (!isNullOrUndefined$2(iterable)) iterate$3(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); }); var Prototype = Constructor.prototype; var getInternalState = internalStateGetterFor$1(CONSTRUCTOR_NAME); var define = function (that, key, value) { var state = getInternalState(that); var entry = getEntry(that, key); var previous, index; // change existing entry if (entry) { entry.value = value; // create new entry } else { state.last = entry = { index: index = fastKey(key, true), key: key, value: value, previous: previous = state.last, next: undefined, removed: false }; if (!state.first) state.first = entry; if (previous) previous.next = entry; if (DESCRIPTORS$9) state.size++; else that.size++; // add to index if (index !== 'F') state.index[index] = entry; } return that; }; var getEntry = function (that, key) { var state = getInternalState(that); // fast case var index = fastKey(key); var entry; if (index !== 'F') return state.index[index]; // frozen object case for (entry = state.first; entry; entry = entry.next) { if (entry.key == key) return entry; } }; defineBuiltIns$3(Prototype, { // `{ Map, Set }.prototype.clear()` methods // https://tc39.es/ecma262/#sec-map.prototype.clear // https://tc39.es/ecma262/#sec-set.prototype.clear clear: function clear() { var that = this; var state = getInternalState(that); var data = state.index; var entry = state.first; while (entry) { entry.removed = true; if (entry.previous) entry.previous = entry.previous.next = undefined; delete data[entry.index]; entry = entry.next; } state.first = state.last = undefined; if (DESCRIPTORS$9) state.size = 0; else that.size = 0; }, // `{ Map, Set }.prototype.delete(key)` methods // https://tc39.es/ecma262/#sec-map.prototype.delete // https://tc39.es/ecma262/#sec-set.prototype.delete 'delete': function (key) { var that = this; var state = getInternalState(that); var entry = getEntry(that, key); if (entry) { var next = entry.next; var prev = entry.previous; delete state.index[entry.index]; entry.removed = true; if (prev) prev.next = next; if (next) next.previous = prev; if (state.first == entry) state.first = next; if (state.last == entry) state.last = prev; if (DESCRIPTORS$9) state.size--; else that.size--; } return !!entry; }, // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods // https://tc39.es/ecma262/#sec-map.prototype.foreach // https://tc39.es/ecma262/#sec-set.prototype.foreach forEach: function forEach(callbackfn /* , that = undefined */) { var state = getInternalState(this); var boundFunction = bind$5(callbackfn, arguments.length > 1 ? arguments[1] : undefined); var entry; while (entry = entry ? entry.next : state.first) { boundFunction(entry.value, entry.key, this); // revert to the last existing entry while (entry && entry.removed) entry = entry.previous; } }, // `{ Map, Set}.prototype.has(key)` methods // https://tc39.es/ecma262/#sec-map.prototype.has // https://tc39.es/ecma262/#sec-set.prototype.has has: function has(key) { return !!getEntry(this, key); } }); defineBuiltIns$3(Prototype, IS_MAP ? { // `Map.prototype.get(key)` method // https://tc39.es/ecma262/#sec-map.prototype.get get: function get(key) { var entry = getEntry(this, key); return entry && entry.value; }, // `Map.prototype.set(key, value)` method // https://tc39.es/ecma262/#sec-map.prototype.set set: function set(key, value) { return define(this, key === 0 ? 0 : key, value); } } : { // `Set.prototype.add(value)` method // https://tc39.es/ecma262/#sec-set.prototype.add add: function add(value) { return define(this, value = value === 0 ? 0 : value, value); } }); if (DESCRIPTORS$9) defineBuiltInAccessor$4(Prototype, 'size', { configurable: true, get: function () { return getInternalState(this).size; } }); return Constructor; }, setStrong: function (Constructor, CONSTRUCTOR_NAME, IS_MAP) { var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator'; var getInternalCollectionState = internalStateGetterFor$1(CONSTRUCTOR_NAME); var getInternalIteratorState = internalStateGetterFor$1(ITERATOR_NAME); // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods // https://tc39.es/ecma262/#sec-map.prototype.entries // https://tc39.es/ecma262/#sec-map.prototype.keys // https://tc39.es/ecma262/#sec-map.prototype.values // https://tc39.es/ecma262/#sec-map.prototype-@@iterator // https://tc39.es/ecma262/#sec-set.prototype.entries // https://tc39.es/ecma262/#sec-set.prototype.keys // https://tc39.es/ecma262/#sec-set.prototype.values // https://tc39.es/ecma262/#sec-set.prototype-@@iterator defineIterator(Constructor, CONSTRUCTOR_NAME, function (iterated, kind) { setInternalState$5(this, { type: ITERATOR_NAME, target: iterated, state: getInternalCollectionState(iterated), kind: kind, last: undefined }); }, function () { var state = getInternalIteratorState(this); var kind = state.kind; var entry = state.last; // revert to the last existing entry while (entry && entry.removed) entry = entry.previous; // get next entry if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) { // or finish the iteration state.target = undefined; return createIterResultObject(undefined, true); } // return step by kind if (kind == 'keys') return createIterResultObject(entry.key, false); if (kind == 'values') return createIterResultObject(entry.value, false); return createIterResultObject([entry.key, entry.value], false); }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); // `{ Map, Set }.prototype[@@species]` accessors // https://tc39.es/ecma262/#sec-get-map-@@species // https://tc39.es/ecma262/#sec-get-set-@@species setSpecies$1(CONSTRUCTOR_NAME); } }; var collection$2 = collection$3; var collectionStrong$1 = collectionStrong$2; // `Map` constructor // https://tc39.es/ecma262/#sec-map-objects collection$2('Map', function (init) { return function Map() { return init(this, arguments.length ? arguments[0] : undefined); }; }, collectionStrong$1); var arraySlice$3 = arraySliceSimple; var floor$2 = Math.floor; var mergeSort = function (array, comparefn) { var length = array.length; var middle = floor$2(length / 2); return length < 8 ? insertionSort(array, comparefn) : merge( array, mergeSort(arraySlice$3(array, 0, middle), comparefn), mergeSort(arraySlice$3(array, middle), comparefn), comparefn ); }; var insertionSort = function (array, comparefn) { var length = array.length; var i = 1; var element, j; while (i < length) { j = i; element = array[i]; while (j && comparefn(array[j - 1], element) > 0) { array[j] = array[--j]; } if (j !== i++) array[j] = element; } return array; }; var merge = function (array, left, right, comparefn) { var llength = left.length; var rlength = right.length; var lindex = 0; var rindex = 0; while (lindex < llength || rindex < rlength) { array[lindex + rindex] = (lindex < llength && rindex < rlength) ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++] : lindex < llength ? left[lindex++] : right[rindex++]; } return array; }; var arraySort$1 = mergeSort; var userAgent$5 = engineUserAgent; var firefox = userAgent$5.match(/firefox\/(\d+)/i); var engineFfVersion = !!firefox && +firefox[1]; var UA = engineUserAgent; var engineIsIeOrEdge = /MSIE|Trident/.test(UA); var userAgent$4 = engineUserAgent; var webkit = userAgent$4.match(/AppleWebKit\/(\d+)\./); var engineWebkitVersion = !!webkit && +webkit[1]; var $$q = _export; var uncurryThis$e = functionUncurryThis; var aCallable$4 = aCallable$a; var toObject = toObject$b; var lengthOfArrayLike$1 = lengthOfArrayLike$b; var deletePropertyOrThrow = deletePropertyOrThrow$2; var toString$5 = toString$i; var fails$a = fails$I; var internalSort = arraySort$1; var arrayMethodIsStrict$3 = arrayMethodIsStrict$7; var FF = engineFfVersion; var IE_OR_EDGE = engineIsIeOrEdge; var V8 = engineV8Version; var WEBKIT = engineWebkitVersion; var test = []; var nativeSort = uncurryThis$e(test.sort); var push$5 = uncurryThis$e(test.push); // IE8- var FAILS_ON_UNDEFINED = fails$a(function () { test.sort(undefined); }); // V8 bug var FAILS_ON_NULL = fails$a(function () { test.sort(null); }); // Old WebKit var STRICT_METHOD$3 = arrayMethodIsStrict$3('sort'); var STABLE_SORT = !fails$a(function () { // feature detection can be too slow, so check engines versions if (V8) return V8 < 70; if (FF && FF > 3) return; if (IE_OR_EDGE) return true; if (WEBKIT) return WEBKIT < 603; var result = ''; var code, chr, value, index; // generate an array with more 512 elements (Chakra and old V8 fails only in this case) for (code = 65; code < 76; code++) { chr = String.fromCharCode(code); switch (code) { case 66: case 69: case 70: case 72: value = 3; break; case 68: case 71: value = 4; break; default: value = 2; } for (index = 0; index < 47; index++) { test.push({ k: chr + index, v: value }); } } test.sort(function (a, b) { return b.v - a.v; }); for (index = 0; index < test.length; index++) { chr = test[index].k.charAt(0); if (result.charAt(result.length - 1) !== chr) result += chr; } return result !== 'DGBEFHACIJK'; }); var FORCED$2 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD$3 || !STABLE_SORT; var getSortCompare = function (comparefn) { return function (x, y) { if (y === undefined) return -1; if (x === undefined) return 1; if (comparefn !== undefined) return +comparefn(x, y) || 0; return toString$5(x) > toString$5(y) ? 1 : -1; }; }; // `Array.prototype.sort` method // https://tc39.es/ecma262/#sec-array.prototype.sort $$q({ target: 'Array', proto: true, forced: FORCED$2 }, { sort: function sort(comparefn) { if (comparefn !== undefined) aCallable$4(comparefn); var array = toObject(this); if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn); var items = []; var arrayLength = lengthOfArrayLike$1(array); var itemsLength, index; for (index = 0; index < arrayLength; index++) { if (index in array) push$5(items, array[index]); } internalSort(items, getSortCompare(comparefn)); itemsLength = lengthOfArrayLike$1(items); index = 0; while (index < itemsLength) array[index] = items[index++]; while (index < arrayLength) deletePropertyOrThrow(array, index++); return array; } }); var $$p = _export; var $map = arrayIteration.map; var arrayMethodHasSpeciesSupport = arrayMethodHasSpeciesSupport$5; var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('map'); // `Array.prototype.map` method // https://tc39.es/ecma262/#sec-array.prototype.map // with adding support of @@species $$p({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, { map: function map(callbackfn /* , thisArg */) { return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); var uncurryThis$d = functionUncurryThis; var isArray$1 = isArray$7; var isCallable$7 = isCallable$u; var classof$2 = classofRaw$2; var toString$4 = toString$i; var push$4 = uncurryThis$d([].push); var getJsonReplacerFunction = function (replacer) { if (isCallable$7(replacer)) return replacer; if (!isArray$1(replacer)) return; var rawLength = replacer.length; var keys = []; for (var i = 0; i < rawLength; i++) { var element = replacer[i]; if (typeof element == 'string') push$4(keys, element); else if (typeof element == 'number' || classof$2(element) == 'Number' || classof$2(element) == 'String') push$4(keys, toString$4(element)); } var keysLength = keys.length; var root = true; return function (key, value) { if (root) { root = false; return value; } if (isArray$1(this)) return value; for (var j = 0; j < keysLength; j++) if (keys[j] === key) return value; }; }; var $$o = _export; var getBuiltIn$8 = getBuiltIn$e; var apply$3 = functionApply; var call$6 = functionCall; var uncurryThis$c = functionUncurryThis; var fails$9 = fails$I; var isCallable$6 = isCallable$u; var isSymbol = isSymbol$4; var arraySlice$2 = arraySlice$7; var getReplacerFunction = getJsonReplacerFunction; var NATIVE_SYMBOL = symbolConstructorDetection; var $String = String; var $stringify = getBuiltIn$8('JSON', 'stringify'); var exec$3 = uncurryThis$c(/./.exec); var charAt$3 = uncurryThis$c(''.charAt); var charCodeAt$1 = uncurryThis$c(''.charCodeAt); var replace$6 = uncurryThis$c(''.replace); var numberToString$1 = uncurryThis$c(1.0.toString); var tester = /[\uD800-\uDFFF]/g; var low = /^[\uD800-\uDBFF]$/; var hi = /^[\uDC00-\uDFFF]$/; var WRONG_SYMBOLS_CONVERSION = !NATIVE_SYMBOL || fails$9(function () { var symbol = getBuiltIn$8('Symbol')(); // MS Edge converts symbol values to JSON as {} return $stringify([symbol]) != '[null]' // WebKit converts symbol values to JSON as null || $stringify({ a: symbol }) != '{}' // V8 throws on boxed symbols || $stringify(Object(symbol)) != '{}'; }); // https://github.com/tc39/proposal-well-formed-stringify var ILL_FORMED_UNICODE = fails$9(function () { return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' || $stringify('\uDEAD') !== '"\\udead"'; }); var stringifyWithSymbolsFix = function (it, replacer) { var args = arraySlice$2(arguments); var $replacer = getReplacerFunction(replacer); if (!isCallable$6($replacer) && (it === undefined || isSymbol(it))) return; // IE8 returns string on undefined args[1] = function (key, value) { // some old implementations (like WebKit) could pass numbers as keys if (isCallable$6($replacer)) value = call$6($replacer, this, $String(key), value); if (!isSymbol(value)) return value; }; return apply$3($stringify, null, args); }; var fixIllFormed = function (match, offset, string) { var prev = charAt$3(string, offset - 1); var next = charAt$3(string, offset + 1); if ((exec$3(low, match) && !exec$3(hi, next)) || (exec$3(hi, match) && !exec$3(low, prev))) { return '\\u' + numberToString$1(charCodeAt$1(match, 0), 16); } return match; }; if ($stringify) { // `JSON.stringify` method // https://tc39.es/ecma262/#sec-json.stringify $$o({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE }, { // eslint-disable-next-line no-unused-vars -- required for `.length` stringify: function stringify(it, replacer, space) { var args = arraySlice$2(arguments); var result = apply$3(WRONG_SYMBOLS_CONVERSION ? stringifyWithSymbolsFix : $stringify, null, args); return ILL_FORMED_UNICODE && typeof result == 'string' ? replace$6(result, tester, fixIllFormed) : result; } }); } var DESCRIPTORS$8 = descriptors; var uncurryThis$b = functionUncurryThis; var objectKeys = objectKeys$3; var toIndexedObject$1 = toIndexedObject$a; var $propertyIsEnumerable = objectPropertyIsEnumerable.f; var propertyIsEnumerable = uncurryThis$b($propertyIsEnumerable); var push$3 = uncurryThis$b([].push); // `Object.{ entries, values }` methods implementation var createMethod$1 = function (TO_ENTRIES) { return function (it) { var O = toIndexedObject$1(it); var keys = objectKeys(O); var length = keys.length; var i = 0; var result = []; var key; while (length > i) { key = keys[i++]; if (!DESCRIPTORS$8 || propertyIsEnumerable(O, key)) { push$3(result, TO_ENTRIES ? [key, O[key]] : O[key]); } } return result; }; }; var objectToArray = { // `Object.entries` method // https://tc39.es/ecma262/#sec-object.entries entries: createMethod$1(true), // `Object.values` method // https://tc39.es/ecma262/#sec-object.values values: createMethod$1(false) }; var $$n = _export; var $values = objectToArray.values; // `Object.values` method // https://tc39.es/ecma262/#sec-object.values $$n({ target: 'Object', stat: true }, { values: function values(O) { return $values(O); } }); var Selector$M = { DATA_MOUNT: '[data-mount="sticky"]', SHOW_STUCK: '.sticky-show-stuck', HIDE_STUCK: '.sticky-hide-stuck' }; var ClassName$s = { STICKY: 'sticky', STUCK: 'stuck', GET_HEIGHT: 'get-height', STICKY_TOP: 'sticky-direction-top', STICKY_BOTTOM: 'sticky-direction-bottom' }; var Direction$4 = { TOP: 'top', BOTTOM: 'bottom' }; var EventName$L = { ON_STUCK: 'onSticky', ON_UNSTUCK: 'onStatic', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove', RESIZE: 'resize' }; var Default$3 = { DIRECTION: 'top', EXTRA_SCROLL_PADDING: 12 }; /** * @enum {string} */ var ObserverBehavior$2 = { ALWAYS: 'always', OFF: 'off', SIZE_AWARE: 'size-aware' }; var stickies$2 = []; /** * Private functions. */ /** * Get the direction of the sticky. * @param {string} str - The string to parse. * @param {string} [defaultValue="top"] - The default value to fallback to. * @returns {string} The direction of the sticky. */ function _getDirection$2(str, defaultValue) { if (defaultValue === void 0) { defaultValue = Default$3.DIRECTION; } switch (str) { case 'top': case 'bottom': return str; default: return defaultValue; } } /** * Class representing a Sticky element. */ var _init$1 = /*#__PURE__*/_classPrivateFieldLooseKey("init"); var _setUp = /*#__PURE__*/_classPrivateFieldLooseKey("setUp"); var _getObserverBehavior$2 = /*#__PURE__*/_classPrivateFieldLooseKey("getObserverBehavior"); var _setDirectionalProps$2 = /*#__PURE__*/_classPrivateFieldLooseKey("setDirectionalProps"); var _calculateHeights$2 = /*#__PURE__*/_classPrivateFieldLooseKey("calculateHeights"); var _calculateLooseWidth = /*#__PURE__*/_classPrivateFieldLooseKey("calculateLooseWidth"); var _onStickyChange$2 = /*#__PURE__*/_classPrivateFieldLooseKey("onStickyChange"); var _createObserver$3 = /*#__PURE__*/_classPrivateFieldLooseKey("createObserver"); var _setStickyHeight = /*#__PURE__*/_classPrivateFieldLooseKey("setStickyHeight"); var _setVw = /*#__PURE__*/_classPrivateFieldLooseKey("setVw"); var _setIsStuck = /*#__PURE__*/_classPrivateFieldLooseKey("setIsStuck"); var _onResize$1 = /*#__PURE__*/_classPrivateFieldLooseKey("onResize"); var _updateScrollPadding$2 = /*#__PURE__*/_classPrivateFieldLooseKey("updateScrollPadding"); var _stickyExceedsAcceptedHeight$2 = /*#__PURE__*/_classPrivateFieldLooseKey("stickyExceedsAcceptedHeight"); var _setObserverStatus = /*#__PURE__*/_classPrivateFieldLooseKey("setObserverStatus"); var Sticky = /*#__PURE__*/function () { /** * Create a Sticky instance * @param {Object} opts - The Sticky element options. * @param {HTMLElement} opts.el - The Sticky element DOM node. * @param {string} [opts.direction] - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will attempt to read `data-direction` attribute, then defaults TOP * @param {ObserverBehavior} opts.observerBehavior - the behavior of the intersection observer to toggle stuck/unstuck states * @param {number} [opts.extraScrollPaddingPx] - Extra scroll padding to reduce crowding into sticky bars, defaults to 12px, same as minimal gutters */ function Sticky(opts) { var _this = this; /** * Set the status (enabled/disabled) of the intersection observer and update the isStuck property * @param {boolean} status The status to set */ Object.defineProperty(this, _setObserverStatus, { value: _setObserverStatus2 }); /** * Calculate whether the height of the sticky has exceeded 33% of the viewport height based on height of the sticky's hidden elements and the height of the sticky's visible elements. * @returns {boolean} Whether the height of the sticky has exceeded 33% of the viewport height. */ Object.defineProperty(this, _stickyExceedsAcceptedHeight$2, { value: _stickyExceedsAcceptedHeight2 }); /** * Updates scroll padding CSS property on HTML element */ Object.defineProperty(this, _updateScrollPadding$2, { value: _updateScrollPadding2 }); /** * Handler for resize event */ Object.defineProperty(this, _onResize$1, { value: _onResize2 }); /** * Checks if Sticky is stuck and if it is sets isStuck property to true */ Object.defineProperty(this, _setIsStuck, { value: _setIsStuck2 }); /** * Set document clientWidth in CSS variable */ Object.defineProperty(this, _setVw, { value: _setVw2 }); /** * Set height of Sticky element to the stuck height and apply the difference to margin-top * @param {boolean} [removeStyles=false] - Whether to set Sticky element height and margin-top to null */ Object.defineProperty(this, _setStickyHeight, { value: _setStickyHeight2 }); /** * Create a new observer instance member, disconnecting the old one if present. */ Object.defineProperty(this, _createObserver$3, { value: _createObserver2 }); /** * Handle intersection observer */ Object.defineProperty(this, _onStickyChange$2, { value: _onStickyChange2 }); /** * Calculate width with not stuck. * @returns {number} - Width of el when not stuck */ Object.defineProperty(this, _calculateLooseWidth, { value: _calculateLooseWidth2 }); /** * Calculate and set heights. * @returns {boolean} Whether the height of the Sticky el has changed. */ Object.defineProperty(this, _calculateHeights$2, { value: _calculateHeights2 }); /** * Set value of instances members and DOM node properties depending on the direction instance member */ Object.defineProperty(this, _setDirectionalProps$2, { value: _setDirectionalProps2 }); /** * Validate observer behavior or fall back to default * @param {string} [option] - configuration for observerBehavior * @returns {ObserverBehavior} */ Object.defineProperty(this, _getObserverBehavior$2, { value: _getObserverBehavior2 }); /** * Set styles and configure observer * @param {boolean} keepObserverStatus - maintain current observer status. */ Object.defineProperty(this, _setUp, { value: _setUp2 }); Object.defineProperty(this, _init$1, { value: _init2$1 }); this.el = opts.el; this.direction = _getDirection$2(opts.direction || this.el.dataset.direction); this.extraScrollPaddingPx = typeof opts.extraScrollPaddingPx === 'number' ? opts.extraScrollPaddingPx : Default$3.EXTRA_SCROLL_PADDING; this.enableObserver = true; this.observerBehavior = _classPrivateFieldLooseBase(this, _getObserverBehavior$2)[_getObserverBehavior$2](opts.observerBehavior); this.isStuck = false; this.observer = null; this.windowScrollY = window.scrollY; // remove in v3 - deprecated as of v2.1.0 this.observedWindowDimensions = { width: window.innerWidth, height: window.innerHeight }; this.looseWidth = _classPrivateFieldLooseBase(this, _calculateLooseWidth)[_calculateLooseWidth](); // Add "sticky" class only while initialized to attach style and functionality provided by CSS // Set prior to all height calculations so that styles are applied first this.el.classList.add(ClassName$s.STICKY); _classPrivateFieldLooseBase(this, _setVw)[_setVw](); this.resizeObserver = new ResizeObserver(function () { requestAnimationFrame(function () { var windowDimensions = { width: window.innerWidth, height: window.innerHeight }; _this.looseWidth = _classPrivateFieldLooseBase(_this, _calculateLooseWidth)[_calculateLooseWidth](); // Sticky should maintain "sticky-ness" (observer status) if resize change is not from the window changing size _classPrivateFieldLooseBase(_this, _setUp)[_setUp](JSON.stringify(windowDimensions) === JSON.stringify(_this.observedWindowDimensions)); _this.observedWindowDimensions = windowDimensions; }); }); Array.from(this.el.children).forEach(function (child) { _this.resizeObserver.observe(child); }); _classPrivateFieldLooseBase(this, _init$1)[_init$1](); stickies$2.push(this); } var _proto = Sticky.prototype; /** * Set the status of the sticky observer, * dependent on configuration and/or height condition */ _proto.setObserver = function setObserver() { switch (this.observerBehavior) { case ObserverBehavior$2.OFF: _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](false); break; case ObserverBehavior$2.ALWAYS: _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](true); break; default: if (_classPrivateFieldLooseBase(this, _stickyExceedsAcceptedHeight$2)[_stickyExceedsAcceptedHeight$2]()) { _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](false); } else { _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](true); } } }; /** * Get the height of the sticky element when stuck * @returns {number} Stuck height in pixels */ _proto.getStuckHeight = function getStuckHeight() { return this.stuckHeight; } /** * Updates key aspects the instance * @param {Object} opts - The Sticky options. * @param {string} [opts.direction] - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will maintain current setting * @param {number} [opts.extraScrollPaddingPx] - Extra scroll padding to reduce crowding into sticky bars. If not define, will maintain current setting * @param {ObserverBehavior} [opts.observerBehavior] - the behavior of the intersection observer to toggle stuck/unstuck states */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } Util$1.removeEvents(this.events); if (opts.direction) { this.direction = _getDirection$2(opts.direction); } if (opts.extraScrollPaddingPx && typeof opts.extraScrollPaddingPx === 'number') { this.extraScrollPaddingPx = opts.extraScrollPaddingPx; } if (opts.observerBehavior) { this.observerBehavior = _classPrivateFieldLooseBase(this, _getObserverBehavior$2)[_getObserverBehavior$2](opts.observerBehavior); } _classPrivateFieldLooseBase(this, _init$1)[_init$1](); // Create and dispatch custom event this[EventName$L.ON_UPDATE] = new CustomEvent(EventName$L.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$L.ON_UPDATE]); } /** * Remove the sticky. */; _proto.remove = function remove() { Util$1.removeEvents(this.events); this.resizeObserver.disconnect(); // remove the attribute from the element this.el.classList.remove(ClassName$s.STICKY); _classPrivateFieldLooseBase(this, _updateScrollPadding$2)[_updateScrollPadding$2](true); _classPrivateFieldLooseBase(this, _setStickyHeight)[_setStickyHeight](true); // disconnect observer this.observer.disconnect(); // remove this sticky reference from array of instances var index = stickies$2.indexOf(this); stickies$2.splice(index, 1); // Create and dispatch custom event this[EventName$L.ON_REMOVE] = new CustomEvent(EventName$L.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$L.ON_REMOVE]); } /** * Get an array of sticky instances. * @returns {Object[]} Array of sticky instances. */; Sticky.getInstances = function getInstances() { return stickies$2; }; return Sticky; }(); function _init2$1() { _classPrivateFieldLooseBase(this, _setDirectionalProps$2)[_setDirectionalProps$2](); _classPrivateFieldLooseBase(this, _setUp)[_setUp](); // Add event handlers this.events = [{ el: window, type: EventName$L.RESIZE, handler: throttle(200, _classPrivateFieldLooseBase(this, _onResize$1)[_onResize$1].bind(this)) }]; Util$1.addEvents(this.events); } function _setUp2(keepObserverStatus) { var hasHeightChange = _classPrivateFieldLooseBase(this, _calculateHeights$2)[_calculateHeights$2](); // A change in Sticky height requires a new IntersectionObserver // Otherwise, only check IntersectionObserver status and update if needed if (hasHeightChange) { _classPrivateFieldLooseBase(this, _createObserver$3)[_createObserver$3](); if (keepObserverStatus) { _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](this.enableObserver); } else { this.setObserver(); } } else if (keepObserverStatus) { _classPrivateFieldLooseBase(this, _setObserverStatus)[_setObserverStatus](this.enableObserver); } else { this.setObserver(); } } function _getObserverBehavior2(option) { var isValid = function isValid(behavior) { return Object.values(ObserverBehavior$2).includes(behavior); }; if (option && isValid(option)) { return option; } if (isValid(this.el.dataset.observerBehavior)) { return this.el.dataset.observerBehavior; } return ObserverBehavior$2.SIZE_AWARE; } function _setDirectionalProps2() { if (this.direction === Direction$4.BOTTOM) { this.el.classList.add(ClassName$s.STICKY_BOTTOM); this.el.classList.remove(ClassName$s.STICKY_TOP); } else { // Assume direction is Direction.TOP this.el.classList.add(ClassName$s.STICKY_TOP); this.el.classList.remove(ClassName$s.STICKY_BOTTOM); } } function _calculateHeights2() { var currentStuckHeight = this.stuckHeight; var currentLooseHeight = this.looseHeight; var heightOps = { cssSelectors: ['margin'] }; _classPrivateFieldLooseBase(this, _setStickyHeight)[_setStickyHeight](true); if (this.el.classList.contains(ClassName$s.STUCK)) { this.stuckHeight = Util$1.getElementOuterHeight(this.el, heightOps); this.el.classList.remove(ClassName$s.STUCK); this.looseHeight = Util$1.getElementOuterHeight(this.el, heightOps); this.el.classList.add(ClassName$s.STUCK); } else { this.looseHeight = Util$1.getElementOuterHeight(this.el, heightOps); this.el.classList.add(ClassName$s.GET_HEIGHT); this.el.classList.add(ClassName$s.STUCK); this.stuckHeight = Util$1.getElementOuterHeight(this.el, heightOps); this.el.classList.remove(ClassName$s.STUCK); this.el.classList.remove(ClassName$s.GET_HEIGHT); } this.heightDif = this.looseHeight - this.stuckHeight; _classPrivateFieldLooseBase(this, _setStickyHeight)[_setStickyHeight](); return currentStuckHeight !== this.stuckHeight || currentLooseHeight !== this.looseHeight; } function _calculateLooseWidth2() { var elWidth = this.el.getBoundingClientRect().width; if (this.el.classList.contains(ClassName$s.STUCK)) { this.el.classList.remove(ClassName$s.STUCK); elWidth = this.el.getBoundingClientRect().width; this.el.classList.add(ClassName$s.STUCK); } return elWidth; } function _onStickyChange2() { this.el.classList.toggle(ClassName$s.STUCK, this.isStuck); _classPrivateFieldLooseBase(this, _updateScrollPadding$2)[_updateScrollPadding$2](); } function _createObserver2() { var _this2 = this; if (this.observer) { this.observer.disconnect(); } var rootMarginX = (document.documentElement.clientWidth - this.looseWidth) / 2; var rootMarginY = -1; /* We need to check for the presence of a sibling because of how position: sticky works in the browser. Position: sticky automatically defines the element's immediate parent as its sticky container. The item can't get out of its sticky container. https://elad.medium.com/css-position-sticky-how-it-really-works-54cd01dc2d46 When the sticky element has a previous sibling (or next sibling if it is at the bottom), we use a common trick to detect when it becomes sticky by setting the top and bottom root margin to -1 pixel and waiting for that 1 pixel of the sticky element to leave the viewport. Because there is an element before (or after) it, the sticky element can move within its sticky container to meet this criteria. However, if the sticky element doesn't have a sibling, the browser may cause it to become sticky without it moving 1 pixel outside of the viewport (for example, when moving around the page by tabbing). The top (or bottom) of the sticky element is the exact same as the top (or bottom) of the sticky container. Because of this, we can modify the trick we used before by instead checking for when the 1 pixel of the sticky moves to the edge of its sticky container. */ var hasSibling = this.direction === Direction$4.BOTTOM ? this.el.nextElementSibling : this.el.previousElementSibling; var root = hasSibling ? document : this.el.parentElement; var observerOptions = { root: root, rootMargin: rootMarginY + "px " + rootMarginX + "px " + rootMarginY + "px " + rootMarginX + "px", threshold: [1] }; this.observer = new IntersectionObserver(function (_ref) { var entry = _ref[0]; if (_this2.enableObserver) { var prevState = _this2.isStuck; if (root === document) { var isIntersecting = entry.intersectionRect.top === -rootMarginY; if (_this2.direction === Direction$4.BOTTOM) { isIntersecting = entry.intersectionRect.bottom === document.documentElement.clientHeight + rootMarginY; } _this2.isStuck = entry.intersectionRatio < 1 && isIntersecting; } else { _this2.isStuck = entry.isIntersecting; } if (typeof prevState !== 'undefined' && prevState !== _this2.isStuck) { _classPrivateFieldLooseBase(_this2, _onStickyChange$2)[_onStickyChange$2](); if (_this2.isStuck) { _this2[EventName$L.ON_STUCK] = new CustomEvent(EventName$L.ON_STUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$L.ON_STUCK]); } else { _this2[EventName$L.ON_UNSTUCK] = new CustomEvent(EventName$L.ON_UNSTUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$L.ON_UNSTUCK]); } } } }, observerOptions); this.observer.observe(this.el); } function _setStickyHeight2(removeStyles) { if (removeStyles === void 0) { removeStyles = false; } var height = null; var marginTop = null; this.el.style.setProperty('margin-top', marginTop); // clear any margin-top styles previously set if (!removeStyles) { height = this.stuckHeight + "px"; var _getComputedStyle = getComputedStyle(this.el), defaultMarginTop = _getComputedStyle.marginTop; marginTop = this.heightDif + parseInt(defaultMarginTop, 10) + "px"; } this.el.style.setProperty('height', height); if (marginTop) { this.el.style.setProperty('margin-top', marginTop); } } function _setVw2() { var vw = document.documentElement.clientWidth; this.el.style.setProperty('--vw', vw + "px"); } function _setIsStuck2() { if (this.enableObserver) { var stuckBottom = this.direction === Direction$4.BOTTOM && this.el.getBoundingClientRect().bottom === window.innerHeight; var stuckTop = this.direction === Direction$4.TOP && this.el.getBoundingClientRect().top === 0; if (stuckBottom || stuckTop) { this.isStuck = true; } } } function _onResize2() { _classPrivateFieldLooseBase(this, _setVw)[_setVw](); // Only update Sticky if window height changes, resize observer handles width change if (window.innerHeight !== this.observedWindowDimensions.height) { _classPrivateFieldLooseBase(this, _setUp)[_setUp](); } } function _updateScrollPadding2(removeScrollPadding) { var htmlElement = document.querySelector('html'); this.currentHeight = this.el.getBoundingClientRect().height; if (removeScrollPadding) { htmlElement.style.scrollPaddingTop = 0; htmlElement.style.scrollPaddingBottom = 0; } if (this.direction === Direction$4.TOP) { htmlElement.style.scrollPaddingTop = this.currentHeight + this.extraScrollPaddingPx + 'px'; } else if (this.direction === Direction$4.BOTTOM) { htmlElement.style.scrollPaddingBottom = this.currentHeight + this.extraScrollPaddingPx + 'px'; } } function _stickyExceedsAcceptedHeight2() { return this.stuckHeight > window.innerHeight / 3; } function _setObserverStatus2(status) { this.enableObserver = status; var position = null; if (!status) { position = 'initial'; this.isStuck = false; } this.el.style.setProperty('position', position); _classPrivateFieldLooseBase(this, _setIsStuck)[_setIsStuck](); _classPrivateFieldLooseBase(this, _onStickyChange$2)[_onStickyChange$2](); } var $$m = _export; var $every = arrayIteration.every; var arrayMethodIsStrict$2 = arrayMethodIsStrict$7; var STRICT_METHOD$2 = arrayMethodIsStrict$2('every'); // `Array.prototype.every` method // https://tc39.es/ecma262/#sec-array.prototype.every $$m({ target: 'Array', proto: true, forced: !STRICT_METHOD$2 }, { every: function every(callbackfn /* , thisArg */) { return $every(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); var Selector$L = { DATA_MOUNT: '[data-mount="combobox-select"]', ROLE_COMBOBOX: '[role=combobox]', ROLE_LISTBOX: '[role=listbox]', ROLE_OPTION: '[role=option]' }; var EventName$K = { BLUR: 'blur', CLICK: 'click', KEYDOWN: 'keydown', MOUSEDOWN: 'mousedown', ON_CHANGE: 'onChange', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; var ClassName$r = { ITEM: 'combobox-item', CURRENT_ITEM: 'current-item' }; // option count for PageUp/PageDown keys var PAGE_SIZE = 10; // duration to reset type search timeout var TIMEOUT_MS = 500; /** * Save a list of named combobox actions for readability * @enum {number} */ var SelectAction = { Close: 0, CloseSelect: 1, First: 2, Last: 3, Next: 4, Open: 5, PageDown: 6, PageUp: 7, Previous: 8, // Select: 9, Type: 10 }; var _Util$keys$1 = Util$1.keys, ARROW_DOWN$1 = _Util$keys$1.ARROW_DOWN, ARROW_UP$1 = _Util$keys$1.ARROW_UP, BACKSPACE = _Util$keys$1.BACKSPACE, CLEAR = _Util$keys$1.CLEAR, ENTER = _Util$keys$1.ENTER, END = _Util$keys$1.END, ESC$1 = _Util$keys$1.ESC, HOME = _Util$keys$1.HOME, PAGE_DOWN = _Util$keys$1.PAGE_DOWN, PAGE_UP = _Util$keys$1.PAGE_UP, SPACE = _Util$keys$1.SPACE; var instances$D = []; /** * Get filtered array of options given an input string * @param {string} filter - string against which to compare options * @param {string[]} options - array of options to filter * @param {string[]} exclude - array of options to exclude from filter/search * @returns {string[]} - array of options that begin with the filter string, case-independent */ function getFilteredOptions(filter, options, exclude) { if (options === void 0) { options = []; } if (exclude === void 0) { exclude = []; } return options.filter(function (option) { var matches = option.toLowerCase().indexOf(filter.toLowerCase()) === 0; return matches && exclude.indexOf(option) < 0; }); } /** * Map a key press to an action * @param {KeyboardEvent} event - the key press event * @param {boolean} menuOpen – whether the listbox menu is open * @returns {SelectAction} */ // eslint-disable-next-line complexity function getActionFromKey(event, menuOpen) { var key = event.key, altKey = event.altKey, ctrlKey = event.ctrlKey, metaKey = event.metaKey; var openKeys = [ARROW_DOWN$1, ARROW_UP$1, ENTER, SPACE]; // keys that perform "Open" action switch (true) { // handle opening when closed case !menuOpen && openKeys.includes(key): return SelectAction.Open; // home and end move the selected option when open or closed case key === HOME: return SelectAction.First; case key === END: return SelectAction.Last; // handle typing characters when open or closed case key === BACKSPACE: case key === CLEAR: case key.length === 1 && key !== SPACE && !altKey && !ctrlKey && !metaKey: return SelectAction.Type; default: // handle keys when open if (menuOpen) { switch (true) { case key === ARROW_UP$1 && altKey: return SelectAction.CloseSelect; case key === ARROW_DOWN$1 && !altKey: return SelectAction.Next; case key === ARROW_UP$1: return SelectAction.Previous; case key === PAGE_UP: return SelectAction.PageUp; case key === PAGE_DOWN: return SelectAction.PageDown; case key === ESC$1: return SelectAction.Close; case key === ENTER: case key === SPACE: return SelectAction.CloseSelect; } } } } /** * Get the index of an option from an array of options, based on a search string. * If the filter is multiple iterations of the same letter (e.g "aaa"), cycle through first-letter matches * @param {string[]} options - list of menu options (text content) * @param {string} filter - typed key input * @param {number} [startIndex=0] * @returns {number} option index */ function getIndexByLetter(options, filter, startIndex) { if (startIndex === void 0) { startIndex = 0; } var orderedOptions = [].concat(options.slice(startIndex), options.slice(0, startIndex)); var firstMatch = getFilteredOptions(filter, orderedOptions)[0]; var allSameLetter = function allSameLetter(array) { return array.every(function (letter) { return letter === array[0]; }); }; // eslint-disable-line unicorn/consistent-function-scoping // first check if there is an exact match for the typed string if (firstMatch) { return options.indexOf(firstMatch); } // if the same letter is being repeated, cycle through first-letter matches if (allSameLetter(filter.split(''))) { var matches = getFilteredOptions(filter[0], orderedOptions); return options.indexOf(matches[0]); } // if no matches, return -1 return -1; } /** * Get an updated option index after performing an action * @param {number} currentIndex * @param {number} maxIndex - index to set max range to change key input * @param {SelectAction} action - a SelectAction * @returns {number} new option index */ function getUpdatedIndex(currentIndex, maxIndex, action) { switch (action) { case SelectAction.First: return 0; case SelectAction.Last: return maxIndex; case SelectAction.Previous: return Math.max(0, currentIndex - 1); case SelectAction.Next: return Math.min(maxIndex, currentIndex + 1); case SelectAction.PageUp: return Math.max(0, currentIndex - PAGE_SIZE); case SelectAction.PageDown: return Math.min(maxIndex, currentIndex + PAGE_SIZE); default: return currentIndex; } } /** * Check if element is visible in browser view port * @param {HTMLElement} element - given element * @returns {boolean} */ function isElementInView(element) { var bounding = element.getBoundingClientRect(); return bounding.top >= 0 && bounding.left >= 0 && bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && bounding.right <= (window.innerWidth || document.documentElement.clientWidth); } /** * Check if an element is currently scrollable (vertically overflowing) * @param {HTMLElement} element - given element * @returns {boolean} */ function isScrollable(element) { return element && element.clientHeight < element.scrollHeight; } /** * Ensure a given child element is within the parent's visible scroll area * If the child is not visible, scroll the parent * @param {HTMLElement} activeElement - current element * @param {HTMLElement} scrollParent - element's parent */ function maintainScrollVisibility(activeElement, scrollParent) { var offsetHeight = activeElement.offsetHeight, offsetTop = activeElement.offsetTop; var parentOffsetHeight = scrollParent.offsetHeight, scrollTop = scrollParent.scrollTop; var isAbove = offsetTop < scrollTop; var isBelow = offsetTop + offsetHeight > scrollTop + parentOffsetHeight; if (isAbove) { scrollParent.scrollTo(0, offsetTop); } else if (isBelow) { scrollParent.scrollTo(0, offsetTop - parentOffsetHeight + offsetHeight); } } var _init = /*#__PURE__*/_classPrivateFieldLooseKey("init"); var _setupOption = /*#__PURE__*/_classPrivateFieldLooseKey("setupOption"); var _getSearchString = /*#__PURE__*/_classPrivateFieldLooseKey("getSearchString"); var _onComboBlur = /*#__PURE__*/_classPrivateFieldLooseKey("onComboBlur"); var _onComboClick = /*#__PURE__*/_classPrivateFieldLooseKey("onComboClick"); var _onComboKeyDown = /*#__PURE__*/_classPrivateFieldLooseKey("onComboKeyDown"); var _onComboType = /*#__PURE__*/_classPrivateFieldLooseKey("onComboType"); var _onOptionChange = /*#__PURE__*/_classPrivateFieldLooseKey("onOptionChange"); var _onOptionClick = /*#__PURE__*/_classPrivateFieldLooseKey("onOptionClick"); var _onOptionMouseDown = /*#__PURE__*/_classPrivateFieldLooseKey("onOptionMouseDown"); var _updateMenuState = /*#__PURE__*/_classPrivateFieldLooseKey("updateMenuState"); var ComboboxSelect = /*#__PURE__*/function () { /** * Create a ComboboxSelect instance * @param {Object} opts - the ComboboxSelect options * @param {HTMLElement} opts.el - the ComboboxSelect container element * @param {Boolean} [opts.manageFocusOnClick=true] - whether to send focus back to the Combobox on click */ function ComboboxSelect(_ref) { var _this$comboEl; var el = _ref.el, _ref$manageFocusOnCli = _ref.manageFocusOnClick, manageFocusOnClick = _ref$manageFocusOnCli === void 0 ? true : _ref$manageFocusOnCli; /** * Change state of the listbox menu * @param {boolean} open – whether the menu is open * @param {boolean} callFocus – whether to return focus to the combobox */ Object.defineProperty(this, _updateMenuState, { value: _updateMenuState2 }); /** * Handler for option mousedown event */ Object.defineProperty(this, _onOptionMouseDown, { value: _onOptionMouseDown2 }); /** * Handler for option click * @param {number} index - the index of the clicked option */ Object.defineProperty(this, _onOptionClick, { value: _onOptionClick2 }); /** * Handler for option change * @param {number} index – the index of the option to select */ Object.defineProperty(this, _onOptionChange, { value: _onOptionChange2 }); /** * Handler for combobox typing action * @param {string} letter - single letter */ Object.defineProperty(this, _onComboType, { value: _onComboType2 }); /** * Handler for combobox keydown event * @param {KeyboardEvent} event */ Object.defineProperty(this, _onComboKeyDown, { value: _onComboKeyDown2 }); /** * Handler for combobox click event */ Object.defineProperty(this, _onComboClick, { value: _onComboClick2 }); /** * Handler for combobox blur event */ Object.defineProperty(this, _onComboBlur, { value: _onComboBlur2 }); /** * Get string per typed keystroke, and handle timeout * @param {string} character - typed character * @returns {string} - the string to search options */ Object.defineProperty(this, _getSearchString, { value: _getSearchString2 }); /** * Setup event handlers and ensure HTML attributes for listbox options * @param {Element} option - the option element * @param {number} index - the index of this option */ Object.defineProperty(this, _setupOption, { value: _setupOption2 }); /** * Initialize JS for combobox event handlers and listbox options */ Object.defineProperty(this, _init, { value: _init2 }); // element refs this.el = el; this.manageFocusOnClick = manageFocusOnClick; this.comboEl = el.querySelector(Selector$L.ROLE_COMBOBOX); this.listboxEl = el.querySelector(Selector$L.ROLE_LISTBOX); this.optionEls = el.querySelectorAll(Selector$L.ROLE_OPTION); // data this.idBase = ((_this$comboEl = this.comboEl) == null ? void 0 : _this$comboEl.id) || "combobox_" + Util$1.getUid(); // state this.activeIndex = 0; this.open = false; this.searchString = ''; this.searchTimeout = null; this.events = []; // init if (el && this.comboEl && this.listboxEl && Boolean(this.optionEls.length)) { _classPrivateFieldLooseBase(this, _init)[_init](); } instances$D.push(this); } ComboboxSelect.getInstances = function getInstances() { return instances$D; } /** * Perform an option selection * @param {number} index – the index of the option to select */; var _proto = ComboboxSelect.prototype; _proto.selectOption = function selectOption(index, event) { // update state this.activeIndex = index; // update displayed value var selected = this.optionEls[index]; this.comboEl.innerHTML = selected.textContent; // update aria-selected Array.from(this.optionEls).forEach(function (optionEl, i) { optionEl.setAttribute('aria-selected', "" + (i === index)); }); // create and dispatch custom event on selection/change this[EventName$K.ON_CHANGE] = new CustomEvent(EventName$K.ON_CHANGE, { bubbles: true, detail: { value: selected.textContent, event: event } }); this.comboEl.dispatchEvent(this[EventName$K.ON_CHANGE]); } /** * Re-initialize the instance to update DOM elements and handlers * @param {Object} [opts] - The Combobox options * @param {Boolean} [opts.manageFocusOnClick] - whether to send focus back to the Combobox on click */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } this.comboEl = this.el.querySelector(Selector$L.ROLE_COMBOBOX); this.listboxEl = this.el.querySelector(Selector$L.ROLE_LISTBOX); this.optionEls = this.el.querySelectorAll(Selector$L.ROLE_OPTION); if (typeof opts.manageFocusOnClick === 'boolean') { this.manageFocusOnClick = opts.manageFocusOnClick; } if (this.el && this.comboEl && this.listboxEl && Boolean(this.optionEls.length)) { // reset event handlers in case element refs have changed Util$1.removeEvents(this.events); _classPrivateFieldLooseBase(this, _init)[_init](); } this[EventName$K.ON_UPDATE] = new CustomEvent(EventName$K.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$K.ON_UPDATE]); } /** * Remove the ComboboxSelect instance */; _proto.remove = function remove() { Util$1.removeEvents(this.events); var index = instances$D.indexOf(this); instances$D.splice(index, 1); this[EventName$K.ON_REMOVE] = new CustomEvent(EventName$K.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$K.ON_REMOVE]); }; return ComboboxSelect; }(); function _init2() { var _this$events; // display first option by default this.comboEl.innerHTML = this.optionEls[0].textContent; // add combobox event listeners var comboboxEventHandlers = [{ el: this.comboEl, type: EventName$K.BLUR, handler: _classPrivateFieldLooseBase(this, _onComboBlur)[_onComboBlur].bind(this) }, { el: this.comboEl, type: EventName$K.CLICK, handler: _classPrivateFieldLooseBase(this, _onComboClick)[_onComboClick].bind(this) }, { el: this.comboEl, type: EventName$K.KEYDOWN, handler: _classPrivateFieldLooseBase(this, _onComboKeyDown)[_onComboKeyDown].bind(this) }]; (_this$events = this.events).push.apply(_this$events, comboboxEventHandlers); Util$1.addEvents(comboboxEventHandlers); Array.from(this.optionEls).forEach(_classPrivateFieldLooseBase(this, _setupOption)[_setupOption].bind(this)); } function _setupOption2(option, index) { var _this = this, _this$events2; // ensuring proper HTML attributes option.setAttribute('aria-selected', "" + (index === 0)); if (index === 0) { option.classList.add(ClassName$r.CURRENT_ITEM); } else { option.classList.remove(ClassName$r.CURRENT_ITEM); } option.id = this.idBase + "-" + index; // add option event listeners var optionEventHandlers = [{ el: option, type: EventName$K.CLICK, handler: function handler(event) { event.stopPropagation(); _classPrivateFieldLooseBase(_this, _onOptionClick)[_onOptionClick](index); } }, { el: option, type: EventName$K.MOUSEDOWN, handler: _classPrivateFieldLooseBase(this, _onOptionMouseDown)[_onOptionMouseDown].bind(this) }]; (_this$events2 = this.events).push.apply(_this$events2, optionEventHandlers); Util$1.addEvents(optionEventHandlers); } function _getSearchString2(character) { var _this2 = this; // reset typing timeout and start new timeout // this allows multiple-letter matches, like a native element. * @param {Array} opts.tagButtons - The tag buttons. * @param {HTMLElement} opts.submitButton - The submit button. */ function AISearchForm(_ref) { var el = _ref.el, searchInputWrapper = _ref.searchInputWrapper, searchInput = _ref.searchInput, tagButtons = _ref.tagButtons, submitButton = _ref.submitButton; /** * Add event handlers. */ Object.defineProperty(this, _addEventHandlers$1, { value: _addEventHandlers2$1 }); this.el = el; this.searchInputWrapper = searchInputWrapper || this.el.querySelector(Selector$k.SEARCH_INPUT_WRAPPPER); this.searchInput = searchInput || this.el.querySelector(Selector$k.SEARCH_INPUT); this.tagButtons = tagButtons || this.el.querySelectorAll(Selector$k.TAG_BUTTON); this.submitButton = submitButton || this.el.querySelector(Selector$k.SUBMIT_BUTTON); this.submitButton.disabled = !this.searchInput.value; _classPrivateFieldLooseBase(this, _addEventHandlers$1)[_addEventHandlers$1](); aiSearchForms.push(this); } var _proto = AISearchForm.prototype; /** * Handle input event on the search input. Disable submit button if search input is empty. * @param {InputEvent} event Input event on the search input */ _proto.onInput = function onInput(event) { this.submitButton.disabled = !event.target.value; } /** * Handle submit event on the search form. Fire custom event with search input value. * @param {SubmitEvent} event Submit event on the search form */; _proto.onSubmit = function onSubmit(event) { event.preventDefault(); if (!this.searchInput || !this.searchInput.value) { return; } // Create and dispatch custom event this[EventName$l.ON_AI_SEARCH_FORM_SUBMIT] = new CustomEvent(EventName$l.ON_AI_SEARCH_FORM_SUBMIT, { bubbles: true, detail: { value: this.searchInput.value } }); this.el.dispatchEvent(this[EventName$l.ON_AI_SEARCH_FORM_SUBMIT]); } /** * Handle click on tag button. Submit the text content of the tag button. * @param {PointerEvent} event Click event on the buttton */; _proto.onClickTagButton = function onClickTagButton(event) { event.preventDefault(); if (!this.searchInput || !event.target.textContent) { return; } this.searchInput.value = event.target.textContent.trim(); this.el.dispatchEvent(new Event(EventName$l.SUBMIT)); } /** * Disable/enable search form elements. * @param {Boolean} isDisabled - Whether to disable or enable web chat elements */; _proto.toggleDisabled = function toggleDisabled(isDisabled) { this.submitButton.disabled = isDisabled ? true : !this.searchInput.value; this.tagButtons.forEach(function (tagButton) { tagButton.disabled = isDisabled; }); } /** * Remove event handlers. * @this AISearchForm */; _proto.remove = function remove() { Util$1.removeEvents(this.events); // remove this reference from array of instances var index = aiSearchForms.indexOf(this); aiSearchForms.splice(index, 1); // Create and dispatch custom event this[EventName$l.ON_REMOVE] = new CustomEvent(EventName$l.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$l.ON_REMOVE]); } /** * Get instances. * @returns {Object} A object instance */; AISearchForm.getInstances = function getInstances() { return aiSearchForms; }; return AISearchForm; }(); function _addEventHandlers2$1() { var _this = this; this.events = []; this.events.push({ el: this.el, handler: this.onSubmit.bind(this), type: EventName$l.SUBMIT }, { el: this.searchInput, handler: this.onInput.bind(this), type: EventName$l.INPUT }); this.tagButtons.forEach(function (tagButton) { _this.events.push({ el: tagButton, handler: _this.onClickTagButton.bind(_this), type: EventName$l.CLICK }); }); Util$1.addEvents(this.events); } /** * Private variables */ var aiChatDrawers = []; var uhfHeaderMarginBottomVal = 2; var azureWebsitesDomain = '.azurewebsites.net'; var aemCloudDomain = '.adobeaemcloud.com'; var isRunningLocally = window.location.port === '9002' || window.location.port === '4502' || window.location.port === '4503'; var isAzureWebsites = window.location.hostname.includes(azureWebsitesDomain); var isAemCloud = window.location.hostname.includes(aemCloudDomain); var livePersonApiRequestTypes = ['GetClock', 'cqm.SubscribeExConversations', 'cqm.UnsubscribeExConversations', 'ms.PublishEvent', 'cm.ConsumerRequestConversation', 'ms.SubscribeMessagingEvents', 'InitConnection', 'cm.UpdateConversationField']; var livePersonChatStateTypes = { DEFAULT: 0, ACTIVE: 'ACTIVE', INACTIVE: 'INACTIVE', GONE: 'GONE', COMPOSING: 'COMPOSING', PAUSE: 'PAUSE' }; var livePersonUserComposingDelay = 3000; // User starts composing again after 3 seconds of inactivity var livePersonUserPauseDelay = 3000; // User state will be set to PAUSE after 3 seconds of inactivity var livePersonResponseTimeout = 5000; // Wait 5 seconds before retrying a request to LP // Wait a second before user can click a chat link again to avoid chat with sales button/link spamming var debouncedChatActionTypeLinkClickDelay = 1000; // JsonPollock script source for LivePerson post-chat survey rendering var jsonPollockScriptSrc = 'https://www.microsoft.com/msonecloudapi/assets/json-pollock.bundle.min.js'; /** * Private functions */ /** * Get the domain for the cookie. * @returns {string} The domain for the cookie. */ function getCookieDomain() { // If on localhost or your IP, or on extensions PROD, or on Azure Websites or AEM Cloud, use the hostname. if (isRunningLocally || isAzureWebsites || isAemCloud) { return window.location.hostname; } // PROD return '.microsoft.com'; } /** * Get the base endpoint for the data connector for communicating with Microsoft OneCloud API. * This is only used for LivePerson at the moment. * @param {string} protocol The protocol to use for the endpoint. Examples: 'https:' or 'wss:' * @returns {string} The base endpoint for the data connector. */ function getDataConnectorBaseEndpoint(protocol) { if (isRunningLocally) { return protocol + "//webassistant-dev.microsoft.com"; // Dev endpoint } if (isAzureWebsites) { return protocol + "//webassistant-ppe.microsoft.com"; // PPE endpoint } return protocol + "//webassistant-prod.microsoft.com"; // PROD endpoint } /** * LivePerson private functions */ function withSubscriptionID(subscriptionID) { return function (notif) { return notif.body.subscriptionId === subscriptionID; }; } function withType(type) { return function (notif) { return notif.type.includes(type); }; } /** * Selectors */ var Selector$j = { DATA_MOUNT: '[data-mount="ai-chat-drawer"]', AI_CHAT_BUTTON: '.ai-chat-button', AI_CHAT_BUTTON_TEXT: '.ai-chat-button__text', AI_CHAT_BUTTON_HEADER_TEXT: '.ai-chat-button .ai-chat-button__text span', AI_CHAT_BUTTON_ANCHOR: '.ai-chat-button a', AI_CHAT_BUTTON_DATA_MOUNT: '[data-mount="ai-chat-button"]', ARTICLE: 'article', BLOCK_FEATURE_TITLE: '.block-feature__title', CHAT_ACTION_TYPE_LINK: '[data-oc-chat]', CLOSE_BUTTON: '.ai-chat-drawer__close', DEFLECTION_FLOW_ELEMENT: '[id^="deflection-"]', FEEDBACK_BUTTON: '.action--ai-feedback', FOCUSABLE_ELEMENTS: 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]', TAG_BUTTON: 'button.ai-chat-message--tag', WEB_CHAT_CONTAINER: '.ai-chat-drawer__body__content__messages', WEB_CHAT_SEND_BOX: '.webchat__send-box', WEB_CHAT_SEND_BUTTON: '.webchat__send-button', WEB_CHAT_ACTION_SET_BUTTONS: '.ac-actionSet button', WEB_CHAT_TRANSCRIPT: '.webchat__basic-transcript', WEB_CHAT_BUBBLE: '.webchat__bubble', WEB_CHAT_BUBBLE_FROM_BOT: '.webchat__bubble:not(.webchat__bubble--from-user)', WEB_CHAT_BUBBLE_FROM_USER: '.webchat__bubble--from-user', WEB_CHAT_BUBBLE_CONTENT: '.webchat__bubble__content', WEB_CHAT_STATUS: '.webchat__activity-status', WEB_CHAT_TRANSCRIPT_TRANSCRIPT: '.webchat__basic-transcript__transcript', UHF_HEADER: 'header', UHF_HEADER_CONTAINER: '.universalheader, #headerArea', UHF_MENU_NAV_EXPAND_ELEM: '#uhfCatLogoButton', UHF_FOOTER: '.universalfooter, #footerArea', SEND_TRANSCRIPT_CHECKBOX_CONTAINER: '[id^="sendTranscript"]', STICKY_NAV: '#sticky-nav', STICKY: '.sticky', SURVEY_RESPONSE_STAR_SVG: '.survey-response-button-star', POST_SURVEY_JSON_POLLOCK_BUTTON: 'div.lp-json-pollock-element-button button', HEADER_CONTROLS: '.ai-chat-drawer__header__control' }; /** * Event names */ var EventName$k = { CHANGE: 'change', CLICK: 'click', CLOSE: 'close', INPUT: 'input', KEYDOWN: 'keydown', SCROLL: 'scroll', SUBMIT: 'submit', RESIZE: 'resize', TRANSITION_END: 'transitionend', WEBCHAT_CONNECT_INITIATED: 'webchatconnectinitiated', WEBCHAT_CONNECT_FULFILLED: 'webchatconnectfulfilled', WEBCHAT_MESSAGE_RECEIVED: 'webchatmessagereceived', START_CONVERSATION_FULFILLED: 'startconversationfulfilled', FEEDBACK_SENT: 'feedbackRequestSent', LIVEPERSON_CHAT_START: 'startLPChat', LIVEPERSON_MESSAGE_RENDERED: 'livePersonMessageRendered', LIVEPERSON_SAVE_IDS: 'saveLPIDs', GENERATE_REIMAGINE_UMP: 'generateReimagineUMP', INSTANTIATED_BY_PROACTIVE_CHAT: 'instantiatedByProactiveChatEvent' }; /** * CSS classes */ var ClassName$d = { AI_DISCLAIMER: 'ai-chat-drawer__disclaimer', DISABLED: 'disabled', DISPLAY_NONE: 'd-none', FEEDBACK_BUTTON: 'action--ai-feedback', GET_HEIGHT: 'get-height', LP_SURVEY_QUESTIONNAIRE: 'lp-pcs-questionnaire', LP_SURVEY_RICH_CONTENT: 'lp-pcs-richContent', OVERFLOW_HIDDEN: 'overflow-hidden', RETURN_TO_AI_CHAT: 'return-to-ai-chat', SCREEN_READER_ONLY: 'sr-only', SHOW: 'show', STUCK: 'stuck', SURVEY_RESPONSE_BUTTON_STAR: 'survey-response-button-star', WEBCHAT_BUBBLE_CONTENT_FOLLOW_UP: 'webchat__bubble__content--follow-up', WEBCHAT_BUBBLE_LP_SYSTEM_MESSAGE: 'webchat__bubble--lp-system-message' }; /** * Custom Attributes */ var Attributes$a = { AI_CHAT_ACTION_TYPE_LINK: 'data-oc-ai-chat', CHAT_ACTION_TYPE_LINK: 'data-oc-chat', IS_HIDDEN: 'data-is-hidden' }; /** * Style options for WebChat */ var AIChatDrawerStyleOptions = { // Basic styling backgroundColor: 'var(--theme-background-neutral-fade)', fontSizeSmall: '0.75rem', monospaceFont: 'SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace', primaryFont: 'inherit', transitionDuration: '.3s', // Bubble bubbleBorderRadius: 'var(--root-radii-s)', bubbleBorderWidth: 0, bubbleFromUserBackground: 'var(--root-color-brilliant-blue-100)', bubbleFromUserBorderRadius: 'var(--root-radii-s)', bubbleFromUserBorderWidth: 0, bubbleFromUserTextColor: 'var(--root-color-dark-slate-900)', bubbleTextColor: 'var(--theme-foreground-base-subtle)', // Send box hideUploadButton: true, sendBoxBackground: 'var(--theme-background-card-normal);', sendBoxButtonColor: 'var(--theme-foreground-accent-subtle-normal)', sendBoxButtonShadeColorOnActive: 'transparent', sendBoxButtonKeyboardFocusIndicatorBorderColor: 'currentColor', sendBoxButtonKeyboardFocusIndicatorBorderRadius: '0.5rem', sendBoxButtonKeyboardFocusIndicatorBorderStyle: 'dotted', sendBoxButtonKeyboardFocusIndicatorBorderWidth: '0.1875rem', sendBoxButtonKeyboardFocusIndicatorInset: '0.375rem', sendBoxDisabledTextColor: '#d2d2d2', sendBoxButtonColorOnDisabled: '#d2d2d2', sendBoxButtonShadeColorOnDisabled: 'transparent', sendBoxHeight: 64, sendBoxMaxHeight: 72, sendBoxTextColor: 'Black', sendBoxPlaceholderColor: 'var(--theme-foreground-base-subtle)', sendBoxTextWrap: true, // Timestamp timestampColor: 'var(--root-color-dark-slate-400)' }; /** * Keys for cookies */ var StorageKeys = { cookieName: 'ocrAIChat', token: 'ocrAIChatToken', tokenCreated: 'ocrAIChatTokenCreated', tuid: 'tuid', chatDrawerState: 'ocrAIChatDrawerState', sourceSite: 'ocrAIChatDrawerSourceSite', lpJWT: 'lpJWT', lpOpenConvs: 'lpOpenConvs', startLPChatActivityIds: 'startLPChatActivityIds', lpSession: 'lpEngagementSession' }; /** * Constants for cookies */ var CookieConstants = { domain: getCookieDomain(), expiryDays: -1, // Session cookie secure: !isRunningLocally, sameSite: 'Strict', path: '/' }; /** * Feedback icon SVG constants */ var FEEDBACK_ICON_SVGS = { POSITIVE_FILLED: "data:image/svg+xml,%3Csvg class='image is-down is-filled ___12fm75w f1w7gpdv fez10in fg4l7m0' fill='%230067b8' aria-hidden='true' width='16' height='16' viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M9.58 1.05c-.75-.2-1.34.35-1.55.87-.24.6-.45 1.02-.7 1.53-.16.3-.33.65-.53 1.09-.48 1-.95 1.65-1.3 2.04a4.06 4.06 0 0 1-.5.49h-.02L3.11 8.19a2 2 0 0 0-.86 2.43l.52 1.38a2 2 0 0 0 1.28 1.2l5.35 1.69a2.5 2.5 0 0 0 3.15-1.68l1.36-4.65A2 2 0 0 0 12 6h-1.38l.2-.74c.13-.56.24-1.2.23-1.74-.01-.5-.06-1.02-.27-1.46-.22-.48-.6-.83-1.19-1Zm-4.6 6.03Z' %3E%3C/path%3E%3C/svg%3E", NEGATIVE_FILLED: "data:image/svg+xml,%3Csvg class='image is-down is-filled ___12fm75w f1w7gpdv fez10in fg4l7m0' fill='%230067b8' aria-hidden='true' width='16' height='16' viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M13.1 4.62a3.5 3.5 0 0 0-4.38-2.73L3.77 3.27a2 2 0 0 0-1.43 1.56l-.23 1.2c-.16.87.46 1.64 1.16 1.93.25.1.55.25.85.46a8.22 8.22 0 0 1 3.02 3.92l.28.7c.14.38.28.73.41 1 .11.23.25.46.42.63.19.19.44.33.75.33.36 0 .67-.12.91-.34.24-.2.4-.48.5-.76.22-.55.29-1.25.3-1.9a14.73 14.73 0 0 0-.13-2h.51a2.5 2.5 0 0 0 2.46-2.96l-.46-2.42Z' %3E%3C/path%3E%3C/svg%3E", FILLED_STAR_SVG: "data:image/svg+xml,%3Csvg class='image star-rating' width='24' height='24' viewBox='0 0 24 24' fill='%230078D4' stroke='%230078D4' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .587l3.668 7.57 8.332 1.228-6.038 5.938 1.425 8.283L12 18.617l-7.387 4.012 1.425-8.283-6.038-5.938 8.332-1.228z'/%3E%3C/svg%3E", UNFILLED_STAR_SVG: "data:image/svg+xml,%3Csvg class='image star-rating' width='24' height='24' viewBox='0 0 24 24' fill='white' stroke='%230078D4' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .587l3.668 7.57 8.332 1.228-6.038 5.938 1.425 8.283L12 18.617l-7.387 4.012 1.425-8.283-6.038-5.938 8.332-1.228z'/%3E%3C/svg%3E" }; /** * BotFramework-WebChat notification levels */ var NotificationLevel = { ERROR: 'error', WARN: 'warn', INFO: 'info', SUCCESS: 'success' }; /** * Gets all set cookie values, if available. * @returns {Record | null} All cookie values. */ var getAllCookies = function getAllCookies() { /** @type {Record} */ var cookies = {}; document.cookie.split('; ').forEach(function (pair) { var separatorIndex = pair.indexOf('='); if (separatorIndex !== -1) { var key = pair.slice(0, separatorIndex); var value; try { value = decodeURIComponent(pair.slice(separatorIndex + 1)); } catch (error) { console.error("Error decoding cookie value: " + error); return; } cookies[key] = value; } }); if (Object.keys(cookies).length > 0) { return cookies; } return null; }; /** * Gets a set cookie value for the key provided, if available. * @param {string} key Cookie key. * @returns {string | null} Cookie value, or null. */ var getCookie = function getCookie(key) { var cookies; try { cookies = getAllCookies(); } catch (error) { console.error("Error getting all cookies: " + error); return null; } if (cookies && typeof cookies === 'object') { var value = cookies[key]; if (value !== undefined) { return value; } } return null; }; /** * Sets a cookie with the provided key and value. * @param {string} key Cookie key. * @param {string} value Cookie value. * @param {number} [expiryDays] Number of days before the cookie expires. * @param {string} [domain] Domain for the cookie. * @param {boolean} [secure] Whether the cookie is secure. * @param {boolean} [httpOnly] Whether the cookie is HTTP only. * @param {string} [sameSite] SameSite attribute for the cookie. */ var setCookie = function setCookie(key, value, expiryDays, domain, secure, httpOnly, sameSite, path) { if (secure === void 0) { secure = CookieConstants.secure; } if (httpOnly === void 0) { httpOnly = false; } if (sameSite === void 0) { sameSite = CookieConstants.sameSite; } if (path === void 0) { path = CookieConstants.path; } if (typeof key !== 'string' || typeof value !== 'string' || typeof expiryDays !== 'number' || domain && typeof domain !== 'string') { throw new Error('Error setting cookie: Invalid parameters.'); } var expiryDate = null; if (expiryDays > -1) { expiryDate = new Date(); expiryDate.setTime(expiryDate.getTime() + expiryDays * 24 * 60 * 60 * 1000); } var cookieValue = key + "=" + encodeURIComponent(value); var expiryString = expiryDate ? ";expires=" + expiryDate.toUTCString() : ''; var domainString = domain ? ";domain=" + domain : ''; var secureString = secure ? ';secure' : ''; var httpOnlyString = httpOnly ? ';httponly' : ''; var sameSiteString = ";samesite=" + sameSite; var pathString = ";path=" + path; // eslint-disable-next-line unicorn/no-document-cookie document.cookie = cookieValue + expiryString + domainString + secureString + httpOnlyString + sameSiteString + pathString; }; /** * AI Chat Drawer */ var _UMP_HTML_TEMPLATE = /*#__PURE__*/_classPrivateFieldLooseKey("UMP_HTML_TEMPLATE"); var _setDefaultValuesInMarkup = /*#__PURE__*/_classPrivateFieldLooseKey("setDefaultValuesInMarkup"); var _setDefaultValuesAiChatButton = /*#__PURE__*/_classPrivateFieldLooseKey("setDefaultValuesAiChatButton"); var _addEventHandlers = /*#__PURE__*/_classPrivateFieldLooseKey("addEventHandlers"); var _initUhfIntersectionObserver = /*#__PURE__*/_classPrivateFieldLooseKey("initUhfIntersectionObserver"); var _initStickyNavMutationObserver = /*#__PURE__*/_classPrivateFieldLooseKey("initStickyNavMutationObserver"); var _initWebChatTranscriptObserver = /*#__PURE__*/_classPrivateFieldLooseKey("initWebChatTranscriptObserver"); var _positionAiChatButton = /*#__PURE__*/_classPrivateFieldLooseKey("positionAiChatButton"); var _positionAiChatDrawer = /*#__PURE__*/_classPrivateFieldLooseKey("positionAiChatDrawer"); var _getAISearchFormInstance = /*#__PURE__*/_classPrivateFieldLooseKey("getAISearchFormInstance"); var _resetSourceSiteUpdatePromise = /*#__PURE__*/_classPrivateFieldLooseKey("resetSourceSiteUpdatePromise"); var _regenerateAIChatDrawerToken = /*#__PURE__*/_classPrivateFieldLooseKey("regenerateAIChatDrawerToken"); var _generateDirectLineToken = /*#__PURE__*/_classPrivateFieldLooseKey("generateDirectLineToken"); var _refreshDirectLineToken = /*#__PURE__*/_classPrivateFieldLooseKey("refreshDirectLineToken"); var _setRefreshTimer = /*#__PURE__*/_classPrivateFieldLooseKey("setRefreshTimer"); var _getLocale = /*#__PURE__*/_classPrivateFieldLooseKey("getLocale"); var _initializeJsonPollock = /*#__PURE__*/_classPrivateFieldLooseKey("initializeJsonPollock"); var _handlePageOpenState = /*#__PURE__*/_classPrivateFieldLooseKey("handlePageOpenState"); var _getSourceSite = /*#__PURE__*/_classPrivateFieldLooseKey("getSourceSite"); var _getLPEndpoint = /*#__PURE__*/_classPrivateFieldLooseKey("getLPEndpoint"); var _getLivePersonIdFromJWT = /*#__PURE__*/_classPrivateFieldLooseKey("getLivePersonIdFromJWT"); var AIChatDrawer = /*#__PURE__*/function () { /** * Create an AIChatDrawer instance * @param {Object} opts - The AI Chat Drawer options. * @param {HTMLElement} opts.el - The chat drawer element. */ function AIChatDrawer(_ref) { var _this = this, _this$aiChatButton, _this$getAIChatDrawer, _this$getAIChatDrawer2, _this$getAIChatDrawer3, _this$getAIChatDrawer4; var _el = _ref.el, styleOptions = _ref.styleOptions; /** * Get LivePerson Id from JWT * * @returns {string | null} The LivePerson Id */ Object.defineProperty(this, _getLivePersonIdFromJWT, { value: _getLivePersonIdFromJWT2 }); /** * Get the endpoint URL for the LivePerson API. * * @param {string} baseEndpoint The base endpoint URL. * @param {string} path The path to append to the base endpoint URL. * * @returns {string} The full endpoint URL with path and query string if needed for CORS bypass. */ Object.defineProperty(this, _getLPEndpoint, { value: _getLPEndpoint2 }); /** * Get the source site based on the current URL. Falls back to 'azure'. * @returns {string} The source site. */ Object.defineProperty(this, _getSourceSite, { value: _getSourceSite2 }); /** * Check lastState in cookies and open chat drawer if lastState is open. * @returns {void} */ Object.defineProperty(this, _handlePageOpenState, { value: _handlePageOpenState2 }); /** * Load JsonPollock script and initialize it. */ Object.defineProperty(this, _initializeJsonPollock, { value: _initializeJsonPollock2 }); /** * Gets the user's locale. For now, hardcode to 'en-US', as we are only supporting en-US. * @returns {string} The user's locale (i.e. 'en-US', 'fr-FR', etc.) For now, hardcode to 'en-US'. */ Object.defineProperty(this, _getLocale, { value: _getLocale2 }); /** * Set a timeout to refresh the token x mins before it expires. * @param {number} expiration Token expiration in seconds */ Object.defineProperty(this, _setRefreshTimer, { value: _setRefreshTimer2 }); /** * Refresh the Direct Line token. */ Object.defineProperty(this, _refreshDirectLineToken, { value: _refreshDirectLineToken2 }); /** * Generate a Direct Line token. * @returns {Promise} The Direct Line token. */ Object.defineProperty(this, _generateDirectLineToken, { value: _generateDirectLineToken2 }); /* * Deletes the Chat Drawer Cookie and calls the generate Direct Line token to * Re-establish the cookie. Used when a cookie needs to be force-refreshed. */ Object.defineProperty(this, _regenerateAIChatDrawerToken, { value: _regenerateAIChatDrawerToken2 }); /** * Reset the AI Chat Drawer's source site update promise. */ Object.defineProperty(this, _resetSourceSiteUpdatePromise, { value: _resetSourceSiteUpdatePromise2 }); /** * Gets the first instance of the AI Search Form component. * @returns {AISearchForm} The first instance of the AI Search Form component. */ Object.defineProperty(this, _getAISearchFormInstance, { value: _getAISearchFormInstance2 }); /** * Position the AI Chat Drawer. If the UHF footer is found, insert the AI Chat Drawer before it. Otherwise, insert * the AI Chat Drawer before the closing body tag. Hide the AI Chat Drawer initially. */ Object.defineProperty(this, _positionAiChatDrawer, { value: _positionAiChatDrawer2 }); /** * Position the AI Chat Button. Insert the AI Chat Button before the UHF footer or before the closing body tag. */ Object.defineProperty(this, _positionAiChatButton, { value: _positionAiChatButton2 }); /** * Initialize a MutationObserver to detect when the Web Chat transcript changes. */ Object.defineProperty(this, _initWebChatTranscriptObserver, { value: _initWebChatTranscriptObserver2 }); /** * Initialize a MutationObserver to detect when the sticky nav is stuck/unstuck. */ Object.defineProperty(this, _initStickyNavMutationObserver, { value: _initStickyNavMutationObserver2 }); /** * Initialize an IntersectionObserver to detect when the UHF header intersects with the viewport. */ Object.defineProperty(this, _initUhfIntersectionObserver, { value: _initUhfIntersectionObserver2 }); /** * Add event handlers. */ Object.defineProperty(this, _addEventHandlers, { value: _addEventHandlers2 }); /** * Sets the default values in the click group in case the CF values fail to load or do not exist. */ Object.defineProperty(this, _setDefaultValuesAiChatButton, { value: _setDefaultValuesAiChatButton2 }); /** * Sets the default values in the markup in case the CF values fail to load or do not exist. */ Object.defineProperty(this, _setDefaultValuesInMarkup, { value: _setDefaultValuesInMarkup2 }); /** * Universal Media Player Template */ Object.defineProperty(this, _UMP_HTML_TEMPLATE, { writable: true, value: "
\n \n \n
" }); /** * Replaces the button content with an SVG star icon. * * @param {HTMLElement} el - The element containing the button to replace. */ this.replaceButtonContentWithStarSvg = function (el) { var button = el.querySelector('button'); if (!button) return; el.classList.add(ClassName$d.SURVEY_RESPONSE_BUTTON_STAR); button.innerHTML = ''; var img = document.createElement('img'); img.src = FEEDBACK_ICON_SVGS.UNFILLED_STAR_SVG; img.alt = 'Star'; button.append(img); button.addEventListener(EventName$k.CLICK, _this.handleStarClick); }; /** * Click event handler for star buttons in the survey. * * @param {Event} event - The click event object. */ this.handleStarClick = function (event) { event.preventDefault(); // Get all star buttons within the closest WEB_CHAT_BUBBLE_CONTENT parent var parent = event.currentTarget.closest(Selector$j.WEB_CHAT_BUBBLE_CONTENT); if (!parent) return; var starDivs = Array.from(parent.querySelectorAll(Selector$j.SURVEY_RESPONSE_STAR_SVG)); // Get the index of the clicked star var clickedStar = event.currentTarget.closest(Selector$j.SURVEY_RESPONSE_STAR_SVG); var clickedIndex = starDivs.indexOf(clickedStar); // Update the star ratings visually starDivs.forEach(function (div, index) { var btn = div.querySelector('button'); var img = btn.querySelector('img'); if (img) { img.src = index <= clickedIndex ? FEEDBACK_ICON_SVGS.FILLED_STAR_SVG : FEEDBACK_ICON_SVGS.UNFILLED_STAR_SVG; } }); }; /* * Adds the text content of the parent bubble to the button for telemetry purposes. * Adds content name and id telemetry attributes to the button. * @param {HTMLElement} el - The element containing the button to add telemetry to. */ this.tryAddSurveyButtonTelemetry = function (el, attempts, forStarButtons) { if (attempts === void 0) { attempts = 0; } if (forStarButtons === void 0) { forStarButtons = false; } var button = el.querySelector('button'); var parentBubble = el.closest(Selector$j.WEB_CHAT_BUBBLE_CONTENT); var text = parentBubble == null ? void 0 : parentBubble.querySelector('.webchat__text-content p'); if (text && button) { var buttonValue = button.getAttribute('title'); button.setAttribute('data-bi-hn', text.textContent); button.setAttribute('data-bi-cN', forStarButtons ? buttonValue + " star rating button" : "" + buttonValue); button.setAttribute('data-bi-id', 'ai-chat-drawer'); } else if (attempts < 3) { setTimeout(function () { return _this.tryAddSurveyButtonTelemetry(el, attempts + 1, forStarButtons); }, 100); } }; /** * Attempts to replace a button with an SVG star icon. If the parent element is not found, * it retries up to a maximum number of attempts with a delay. * * @param {HTMLElement} el - The element containing the button to replace. * @param {number} [attempts=0] - The current retry attempt count. */ this.tryReplaceButtonwithStarSVG = function (el, attempts) { if (attempts === void 0) { attempts = 0; } var parent = el.closest(Selector$j.WEB_CHAT_BUBBLE_CONTENT); if (parent) { var requiresStarReplacement = parent.dataset.requiresStarReplacement === 'true'; if (requiresStarReplacement) { _this.replaceButtonContentWithStarSvg(el); _this.tryAddSurveyButtonTelemetry(el, 0, true); } } else if (attempts < 3) { setTimeout(function () { return _this.tryReplaceButtonwithStarSVG(el, attempts + 1); }, 100); } }; /** * Handler function called after an element is rendered. * Processes buttons for post-survey functionality. * * @param {HTMLElement} element - The rendered DOM element. * @param {Object} template - The template object used by JsonPollock. * @returns {HTMLElement} The processed DOM element. */ this.onAfterElementRenderedHandler = function (element, template) { // If the element is a button and post-survey is enabled, process it if (template.type === window.JsonPollock.TEMPLATE_TYPES.BUTTON && _this.isPostSurveyEnabled) { _this.tryAddSurveyButtonTelemetry(element, 0, false); _this.tryReplaceButtonwithStarSVG(element); } return element; }; this.el = _el; this.styleOptions = styleOptions || AIChatDrawerStyleOptions; this.closeButton = this.el.querySelector(Selector$j.CLOSE_BUTTON); this.webChatContainer = this.el.querySelector(Selector$j.WEB_CHAT_CONTAINER); this.aiSearchFormComponent = _classPrivateFieldLooseBase(this, _getAISearchFormInstance)[_getAISearchFormInstance](); this.aiChatButton = document.querySelector(Selector$j.AI_CHAT_BUTTON); this.aiChatButtonHeader = document.querySelector(Selector$j.AI_CHAT_BUTTON_HEADER_TEXT); this.aiChatButtonAnchor = document.querySelector(Selector$j.AI_CHAT_BUTTON_ANCHOR); this.aiChatButtonDataMount = (_this$aiChatButton = this.aiChatButton) == null ? void 0 : _this$aiChatButton.querySelector(Selector$j.AI_CHAT_BUTTON_DATA_MOUNT); this.headerControls = this.el.querySelector(Selector$j.HEADER_CONTROLS); this.aiDisclaimerDiv = null; this.previouslyFocusedElem = null; this.firstFocusableElem = this.closeButton; this.lastFocusableElem = null; this.webChatTextAreaHadFocus = false; this.chatInitialized = false; this.refreshBefore = 120; // Refresh 2 minutes before token expires this.refreshAfter = 3480; // Refresh if token is older than 58 minutes this.tokenEndpoint = this.el.dataset.tokenEndpoint; this.tokenEndpointV2 = this.el.dataset.tokenEndpointV2; this.botEnvironmentParameter = this.el.dataset.botEnvironmentParameter; this.v2PagePaths = (this.el.dataset.v2PagePaths || '').split(',').map(function (s) { return s.trim(); }).filter(Boolean); this.refreshTokenUrl = this.el.dataset.refreshTokenUrl; this.sourceSite = _classPrivateFieldLooseBase(this, _getSourceSite)[_getSourceSite](); this.tuid = null; this.initialChatTextDelay = 2000; // 2 seconds this.messageWaitTimeout = null; this.messageWaitTimeoutDuration = 100000; // 100 seconds // Promise that will be resolved when the sourceSite update is detected this.resolveSourceSiteUpdate = null; this.sourceSiteUpdatePromise = null; _classPrivateFieldLooseBase(this, _resetSourceSiteUpdatePromise)[_resetSourceSiteUpdatePromise](); this.textInputPlaceholder = this.el.dataset.textInputPlaceholder || 'Ask a work question or make a request...'; this.isChatPersistEnabled = this.el.dataset.isChatPersistEnabled === 'true'; this.isInstantiatedByProactiveChat = false; this.drawerTitleText = this.el.querySelector(Selector$j.BLOCK_FEATURE_TITLE).textContent || 'AI-powered assistant'; this.drawerLivePersonTitleText = this.el.dataset.drawerLivePersonTitleText || '[Live Agent] AI-powered assistant'; this.buttonTitleText = this.aiChatButton.querySelector(Selector$j.AI_CHAT_BUTTON_TEXT + " span").textContent || 'AI-powered assistant'; // button and drawer currently have same text, including for flexibility. this.buttonLivePersonTitleText = this.el.dataset.buttonLivePersonTitleText || '[Live Agent] AI-powered assistant'; this.connectivityStatusAltFatalString = this.el.dataset.connectivityStatusAltFatal || 'Please refresh the page.'; this.livePersonInQueueText = this.el.dataset.livePersonInQueueText || 'Connecting you to a live agent. Please wait.'; this.livePersonUserClosedConversationText = this.el.dataset.livePersonUserClosedConversationText || 'Conversation closed by you'; this.livePersonAgentClosedConversationText = this.el.dataset.livePersonAgentClosedConversationText || 'Conversation closed by agent'; this.livePersonSystemClosedConversationText = this.el.dataset.livePersonSystemClosedConversationText || 'Conversation closed by idle system'; this.livePersonDisclaimerText = this.el.dataset.livePersonDisclaimerText || 'You are now chatting with a live agent.'; this.livePersonGenericErrorText = this.el.dataset.livePersonGenericErrorText || 'An error occurred. Please try again later.'; this.surveyBotDisclaimerText = this.el.dataset.surveyBotDisclaimerText || 'You are now chatting with a survey bot.'; this.livePersonNoAgentsText = this.el.dataset.noAgentsText || 'No agents are available to chat.'; this.livePersonSurveyCloseMessage = this.el.dataset.livePersonSurveyCloseMessage || 'Thank you for your time'; this.livePersonReadText = this.el.dataset.readText || 'Read'; this.returnToAiChatText = this.el.dataset.returnToAiChatText || 'End live chat'; this.livePersonDisconnectedReconnectingText = this.el.dataset.livePersonDisconnectedReconnectingText || 'You have been disconnected from live agent. Attempting to reconnect...'; this.livePersonReconnectedText = this.el.dataset.livePersonReconnectedText || 'Reconnected to live agent. You can continue your conversation.'; this.livePersonSendingMessageText = this.el.dataset.livePersonSendingMessageText || 'Sending'; this.livePersonSendFailedText = this.el.dataset.livePersonSendFailedText || 'Send failed.'; this.retryButtonText = this.el.dataset.retryButtonText || 'Retry'; this.transcriptIntroText = this.el.dataset.livePersonTranscriptIntroText || '**FULL CONVERSATION TRANSCRIPT:**'; this.transcriptContinuedText = this.el.dataset.livePersonTranscriptContinuedText || '**FULL CONVERSATION TRANSCRIPT (CONTINUED):**'; this.transcriptFromUserText = this.el.dataset.livePersonTranscriptFromUserText || '**User:**'; this.transcriptFromAssistantText = this.el.dataset.livePersonTranscriptFromAssistantText || '**Assistant:**'; this.aiDisclaimerText = this.el.dataset.aiDisclaimer || 'AI-generated content may be incorrect'; this.closeButtonAriaLabel = this.headerControls ? this.headerControls.getAttribute('aria-label') : 'Close Dialog'; this.chatDrawerAriaLabel = this.el.getAttribute('aria-label') || 'Chatbot Window'; this.livePersonMessageCharLimit = 8000; // LivePerson message character limit this.store = null; this.webChatInstance = null; this.webChatSendBox = null; this.webChatForm = null; this.webChatTextarea = null; this.webChatSendButton = null; this.webChatMaximumCharacters = 250; // Maximum number of chars user can type in web chat this.uhfHeaderElem = document.querySelector(Selector$j.UHF_HEADER); this.uhfNavMenuExpandElem = document.querySelector(Selector$j.UHF_MENU_NAV_EXPAND_ELEM); this.uhfHeaderIntersectionObserver = null; this.uhfHeaderIsVisible = true; // Flag to check if the UHF header is visible this.hideChatBelowHeight = 349.9; // Hide chat below 350px height this.mediaQueryListChatHidden = window.matchMedia("(max-height: " + this.hideChatBelowHeight + "px)"); this.modalDialogBelowWidth = 599.9; // Chat drawer becomes modal dialog below this width this.mediaQueryListModalDialog = window.matchMedia("(max-width: " + this.modalDialogBelowWidth + "px)"); this.uhfFooterElem = document.querySelector(Selector$j.UHF_FOOTER); this.uhfFooterOriginalPadding = this.uhfFooterElem ? window.getComputedStyle(this.uhfFooterElem, null).getPropertyValue('padding-bottom') : ''; this.debouncedResizeDelay = 250; this.stickyNavElem = document.querySelector(Selector$j.STICKY_NAV); this.stickyNavMutationObserver = null; this.botGeneratingResponseText = this.el.dataset.botGeneratingResponseText || 'Generating a response'; this.botFeedbackPositiveAriaLabel = this.el.dataset.botFeedbackPositiveAriaLabel || 'Thumbs up'; this.botFeedbackNegativeAriaLabel = this.el.dataset.botFeedbackNegativeAriaLabel || 'Thumbs down'; this.chatActionTypeLinks = document.querySelectorAll(Selector$j.CHAT_ACTION_TYPE_LINK); this.chatActionTypeLinkText = this.el.dataset.chatActionTypeLinkText || 'Chat with sales'; // LivePerson this.dataConnectorBaseEndpoint = getDataConnectorBaseEndpoint('https:'); this.accountId = null; this.skillId = null; this.isSendTranscript = false; this.corsBypassQueryStringObj = null; // Only applies to local and preview environments this.lpJWT = null; this.lpSession = null; this.lpMessages = {}; this.startLPChatActivityIds = (_this$getAIChatDrawer = (_this$getAIChatDrawer2 = this.getAIChatDrawerCookieObject()) == null ? void 0 : _this$getAIChatDrawer2[StorageKeys.startLPChatActivityIds]) != null ? _this$getAIChatDrawer : []; this.lpOpenConvs = (_this$getAIChatDrawer3 = (_this$getAIChatDrawer4 = this.getAIChatDrawerCookieObject()) == null ? void 0 : _this$getAIChatDrawer4[StorageKeys.lpOpenConvs]) != null ? _this$getAIChatDrawer3 : {}; this.lpSubscriptionId = null; this.lpSubscribedToMessagingEvents = false; // Flag to check if subscribed to messaging events this.curLpChangeSequence = 0; // Keep track of the current change sequence this.lpWebsocket = null; this.isLivePersonChatActive = false; this.isLivePersonAgentAssigned = false; this.isSurveyTextActionPublished = false; this.isPostSurveyEnabled = false; this.isLivePersonChatFeatureEnabled = this.el.dataset.isLPEnabled || false; this.lpSurveyForcedClosed = false; this.debouncedChatStateToComposing = debounce(livePersonUserComposingDelay, this.chatStateToComposing.bind(this), { atBegin: true }); this.debouncedChatStateToPause = debounce(livePersonUserPauseDelay, this.chatStateToPause.bind(this)); this.handleLpUserInput = this.handleLpUserInput.bind(this); this.debouncedOnChatActionTypeLinkClick = debounce(debouncedChatActionTypeLinkClickDelay, this.onChatActionTypeLinkClick.bind(this), { atBegin: true }); _classPrivateFieldLooseBase(this, _addEventHandlers)[_addEventHandlers](); _classPrivateFieldLooseBase(this, _initUhfIntersectionObserver)[_initUhfIntersectionObserver](); _classPrivateFieldLooseBase(this, _initStickyNavMutationObserver)[_initStickyNavMutationObserver](); _classPrivateFieldLooseBase(this, _positionAiChatButton)[_positionAiChatButton](); _classPrivateFieldLooseBase(this, _positionAiChatDrawer)[_positionAiChatDrawer](); this.onMediaQueryListChatHiddenChange(this.mediaQueryListChatHidden); this.onMediaQueryListModalDialogChange(this.mediaQueryListModalDialog); _classPrivateFieldLooseBase(this, _handlePageOpenState)[_handlePageOpenState](); // These text areas will have their text content adjusted during Live Person connection/disconnection events. During these events, we already // push screen-reader accessible messages, so we want to turn off the aria-live regions for these two elements to avoid "double speaking". this.aiChatButton.querySelector(Selector$j.AI_CHAT_BUTTON_TEXT + " span").setAttribute('aria-live', 'off'); this.el.querySelector(Selector$j.BLOCK_FEATURE_TITLE).setAttribute('aria-live', 'off'); aiChatDrawers.push(this); _classPrivateFieldLooseBase(this, _setDefaultValuesInMarkup)[_setDefaultValuesInMarkup](); } var _proto = AIChatDrawer.prototype; /** * Pushes click handlers to events array for each chat action type link. This is used to add event handlers * to the chat action type links in the markup. Returns the added events list. * * @returns {Array.<{ * el: Element | Document | Window, * handler: Function, * type: String, * options?: Object * }>} The events added to events array of the component. */ _proto.addChatActionTypeLinkEvents = function addChatActionTypeLinkEvents() { var _this2 = this; var eventsToAdd = []; this.chatActionTypeLinks.forEach(function (element) { var _this2$events; // Clone the element so legacy event handlers are not bound to it var newNode = element.cloneNode(true); // remove data-oc-chat which is used by legacy chat script newNode.removeAttribute(Attributes$a.CHAT_ACTION_TYPE_LINK); // add data-oc-ai-chat to identify this as an AI chat button newNode.setAttribute(Attributes$a.AI_CHAT_ACTION_TYPE_LINK, ''); newNode.setAttribute('aria-controls', 'ai-chat-drawer'); // legacy chat script sets style display none until chat is initialized if (newNode.style.display === 'none') { newNode.style.removeProperty('display'); } eventsToAdd.push({ el: newNode, handler: _this2.debouncedOnChatActionTypeLinkClick, type: EventName$k.CLICK }); if (newNode.tagName !== 'BUTTON') { eventsToAdd.push({ el: newNode, handler: _this2.debouncedOnChatActionTypeLinkClick, type: EventName$k.KEYDOWN }); } (_this2$events = _this2.events).push.apply(_this2$events, eventsToAdd); element.replaceWith(newNode); }); return eventsToAdd; } /** Check if the Direct Line token is valid. * @returns {boolean} Whether the Direct Line token is valid. */; _proto.hasValidToken = function hasValidToken() { var cookieObj = this.getAIChatDrawerCookieObject(); if (typeof cookieObj !== 'object' || cookieObj === null) { return false; } var token = cookieObj[StorageKeys.token]; var tokenCreated = cookieObj[StorageKeys.tokenCreated]; var currentTime = Date.now() / 1000; if (isNaN(tokenCreated)) { return false; } // I used OR logic here to check for bad cases, but it could be easily flipped to AND logic. return !(!token || token === 'undefined' || currentTime - tokenCreated > this.refreshAfter); }; /** * Handle submit event on the AI Search Form. Disable and clear the AI Search Form input, and open the chat drawer. * @param {CustomEvent} event 'onAISearchSubmit' event of the AI Search Form */ _proto.onAiSearchFormSubmit = function onAiSearchFormSubmit(event) { var _event$detail; var searchInputValue = (_event$detail = event.detail) == null ? void 0 : _event$detail.value; if (!searchInputValue) { return; } // Disable the elements in AI Search Form this.aiSearchFormComponent.toggleDisabled(true); this.chatOpenOrInit(searchInputValue); // Clear the search input this.aiSearchFormComponent.searchInput.value = ''; } /** * Handle click on AI Chat Button * @param {Event} event Click or keydown event on AI Chat Button */; _proto.onAiChatButtonClick = function onAiChatButtonClick(event) { // return if event type is keydown and key is not enter or space bar if (event.type === EventName$k.KEYDOWN && Util$1.getKeyCode(event) !== Util$1.keyCodes.ENTER && Util$1.getKeyCode(event) !== Util$1.keyCodes.SPACE) { return; } event.preventDefault(); event.stopPropagation(); this.chatOpenOrInit(); } /** * Handle keydown event on the AI Chat Drawer. If the tab key is pressed, loop focus between the first and last focusable * elements in the drawer. Note this will not work for mobile screen readers, a different approach will be needed. * @param {KeyboardEvent} event Keydown event on the AI Chat Drawer * @returns {void} */; _proto.onKeyDown = function onKeyDown(event) { if (!this.el.contains(document.activeElement) || Util$1.getKeyCode(event) !== Util$1.keyCodes.TAB) { return; } if ((document.activeElement === this.firstFocusableElem || document.activeElement === this.el) && event.shiftKey) { event.preventDefault(); this.lastFocusableElem.focus(); return; } if (document.activeElement === this.lastFocusableElem && !event.shiftKey) { event.preventDefault(); this.firstFocusableElem.focus(); } } /** * Handles the keydown event on the document. * If the key combination is Ctrl + F6 and the element is not hidden, it performs the necessary focus actions. * If the active element is within the component, it focuses on the search input or the first focusable element in the main content. * If the active element is outside the component, it restores the previously focused element. * @param {KeyboardEvent} event The keydown event on the document */; _proto.onDocumentKeyDown = function onDocumentKeyDown(event) { if (!(event.ctrlKey && event.key === 'F6') || this.el.hidden) { return; } if (this.el.contains(document.activeElement)) { var _this$previouslyFocus; if (this.previouslyFocusedElem === document.body || ((_this$previouslyFocus = this.previouslyFocusedElem) == null ? void 0 : _this$previouslyFocus.offsetParent) === null) { if (this.aiSearchFormComponent) { this.aiSearchFormComponent.searchInput.focus(); } else { var main = document.querySelector(Selector$j.MAIN_CONTENT); var firstFocusableElemInMain = main.querySelector(Selector$j.FOCUSABLE_ELEMENTS); firstFocusableElemInMain == null ? void 0 : firstFocusableElemInMain.focus(); } } else { this.previouslyFocusedElem.focus(); } } else { this.previouslyFocusedElem = document.activeElement; this.webChatTextarea.focus(); } } /** * Handles the click event on a chat action type link. * Prevents the default action and initializes or opens the chat based on its current state. * If the event type is 'keydown', it only proceeds if the key pressed is 'Enter' or 'Space'. * * @param {Event} event - The event object representing the click or keydown event. */; _proto.onChatActionTypeLinkClick = function onChatActionTypeLinkClick(event) { // return if event type is keydown and key is not enter or space bar if (event.type === EventName$k.KEYDOWN && Util$1.getKeyCode(event) !== Util$1.keyCodes.ENTER && Util$1.getKeyCode(event) !== Util$1.keyCodes.SPACE) { return; } event.preventDefault(); this.chatOpenOrInit(this.chatActionTypeLinkText); } /** * Render the BotFramework Web Chat. */; _proto.renderWebChat = function renderWebChat() { window.WebChat.renderWebChat({ locale: _classPrivateFieldLooseBase(this, _getLocale)[_getLocale](), directLine: this.directLine, sendTypingIndicator: true, store: this.store, styleOptions: this.styleOptions, overrideLocalizedStrings: { TEXT_INPUT_PLACEHOLDER: this.textInputPlaceholder, CONNECTIVITY_STATUS_ALT_FATAL: this.connectivityStatusAltFatalString } }, this.webChatContainer); } /** * Display or update a toast style notification at the top of the chat drawer. * Documentation for BotFramework-WebChat notifications: * https://github.com/microsoft/BotFramework-WebChat/blob/main/docs/NOTIFICATION.md * * @param {string} messageText The text to display in the notification * @param {string} notificationLevel The level of the notification (error, warn, info, success. Default is 'info') * @param {string} notificationId The ID of the notification (optional) * @param {string} altText The alternative text for the notification (optional. Use if the message contains HTML) * * @returns {string} The notification ID */; _proto.setNotification = function setNotification(messageText, notificationLevel, notificationId, altText) { if (notificationLevel === void 0) { notificationLevel = NotificationLevel.INFO; } if (notificationId === void 0) { notificationId = ''; } if (altText === void 0) { altText = ''; } if (!this.store) { console.error('Unable to display notification. BotFramework-WebChat store not found.'); return; } notificationId = notificationId || window.crypto.randomUUID(); var notificationObj = { type: 'WEB_CHAT/SET_NOTIFICATION', payload: { id: notificationId, level: notificationLevel, message: messageText } }; if (altText) { notificationObj.payload.alt = altText; } this.store.dispatch(notificationObj); return notificationId; } /** * Dismisses a notification by its ID. * * This method dispatches an action to the BotFramework-WebChat store to remove a notification. * If the store is not available, it logs an error message. * * @param {string} id - The ID of the notification to dismiss. */; _proto.dismissNotification = function dismissNotification(id) { if (!this.store) { console.error('Unable to dismiss notification. BotFramework-WebChat store not found.'); return; } this.store.dispatch({ type: 'WEB_CHAT/DISMISS_NOTIFICATION', payload: { id: id } }); } /** * Check for LivePerson agent availability * * @returns {Promise} Response from the fetch call */ /* eslint-disable no-await-in-loop */; _proto.checkLivePersonAgentAvailability = /*#__PURE__*/ function () { var _checkLivePersonAgentAvailability = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(retries, delay) { var checkAgentAvailabilityEndpoint, headers, options, attempt, response, jsonResponse; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (retries === void 0) { retries = 3; } if (delay === void 0) { delay = 1000; } checkAgentAvailabilityEndpoint = _classPrivateFieldLooseBase(this, _getLPEndpoint)[_getLPEndpoint](this.dataConnectorBaseEndpoint, 'liveperson/v1/check'); headers = new Headers(); headers.append('Content-Type', 'application/json'); options = { method: 'POST', headers: headers, body: JSON.stringify({ metadata: { skillId: this.skillId } }) }; attempt = 1; case 7: if (!(attempt <= retries)) { _context.next = 34; break; } _context.prev = 8; _context.next = 11; return fetch(checkAgentAvailabilityEndpoint, options); case 11: response = _context.sent; if (response.ok) { _context.next = 14; break; } throw new Error("Error checking LivePerson agent availability. Response status: " + response.status); case 14: _context.next = 16; return response.json(); case 16: jsonResponse = _context.sent; return _context.abrupt("return", jsonResponse.availability); case 20: _context.prev = 20; _context.t0 = _context["catch"](8); console.error("Attempt " + attempt + " failed: " + _context.t0.message); if (!(attempt < retries)) { _context.next = 28; break; } _context.next = 26; return new Promise(function (resolve) { return setTimeout(resolve, delay); }); case 26: _context.next = 31; break; case 28: this.setNotification(this.livePersonGenericErrorText, NotificationLevel.ERROR); console.error('All retry attempts failed.'); throw _context.t0; case 31: attempt++; _context.next = 7; break; case 34: case "end": return _context.stop(); } }, _callee, this, [[8, 20]]); })); function checkLivePersonAgentAvailability(_x, _x2) { return _checkLivePersonAgentAvailability.apply(this, arguments); } return checkLivePersonAgentAvailability; }() /* eslint-enable no-await-in-loop */ /** * Get the lead ID based on the current page's origin and pathname. * @returns {string} The generated lead ID. */ ; _proto.getLeadId = function getLeadId() { return window.location.origin + window.location.pathname; } /** * Creates or updates a live-person engagement session for current client * @returns live-person engagement session create response */; _proto.createLivePersonSession = /*#__PURE__*/ function () { var _createLivePersonSession = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { var _window$oc$geo$countr, _window$oc, _window$oc$geo, _document$querySelect, _window$oc$lp$topic, _window$oc2, _window$oc2$lp; var country, topic, leadId, ipAddress, cookieObject, localSession, isCreatingSession, requestData, callOptions, isSessionUpdated, result, _result, _this$updateAIChatDra; return _regeneratorRuntime().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: country = (_window$oc$geo$countr = (_window$oc = window.oc) == null ? void 0 : (_window$oc$geo = _window$oc.geo) == null ? void 0 : _window$oc$geo.country) != null ? _window$oc$geo$countr : (_document$querySelect = document.querySelector('[data-geo-country]')) == null ? void 0 : _document$querySelect.getAttribute('data-geo-country'); topic = (_window$oc$lp$topic = (_window$oc2 = window.oc) == null ? void 0 : (_window$oc2$lp = _window$oc2.lp) == null ? void 0 : _window$oc2$lp.topic) != null ? _window$oc$lp$topic : ''; leadId = this.getLeadId(); ipAddress = ''; // TODO - Get ip-address cookieObject = this.getAIChatDrawerCookieObject(); localSession = cookieObject[StorageKeys.lpSession]; isCreatingSession = false; requestData = { account: this.accountId, country: country, topic: topic, leadId: leadId, ipAddress: ipAddress, pageId: null, visitorId: null, sessionId: null }; // Check if session already exists and matches with current if (!(localSession && localSession.pageId && localSession.visitorId && localSession.sessionId)) { _context2.next = 16; break; } if (!(localSession.topic === topic && localSession.leadId === leadId && localSession.country === country)) { _context2.next = 11; break; } return _context2.abrupt("return", localSession); case 11: requestData.pageId = localSession.pageId; requestData.visitorId = localSession.visitorId; requestData.sessionId = localSession.sessionId; _context2.next = 17; break; case 16: isCreatingSession = true; case 17: callOptions = { // Arguments must be in order of the calling function args: [requestData] }; _context2.prev = 18; isSessionUpdated = false; if (isCreatingSession) { _context2.next = 25; break; } _context2.next = 23; return LPUtils.exponentialBackoff(LPUtils.engagement.updateSession, function (response) { if (response > 499) { // Retry in case of server-side issue from live-person return true; } return false; }, callOptions); case 23: result = _context2.sent; isSessionUpdated = result === 200; case 25: if (isSessionUpdated) { _context2.next = 33; break; } // Clear out any existing session data requestData.pageId = null; requestData.visitorId = null; requestData.sessionId = null; _context2.next = 31; return LPUtils.exponentialBackoff(LPUtils.engagement.createSession, function (response, error, options) { if (!response && !error) { // Set retry flag to true return true; } // Check if current response contains the session id and visitor id if (response.sessionId && response.visitorId) { // Set retry flag to false as we have received the success response return false; // this will return the create session results back via `exponentialBackoff` } var errorMessage = (error == null ? void 0 : error.message) || (response == null ? void 0 : response.message); if (errorMessage) { // Extract the visitor id and retry var _errorMessage$split = errorMessage.split('vid: '), vid = _errorMessage$split[1]; if (vid) { // Update the args - need to add the visitor id if it is provided when retrying a 5xx response requestData.visitorId = vid; options.args = [requestData]; } console.warn('[LP] received error while trying to create session:', error || response, vid); } // Set retry flag to true return true; }, callOptions); case 31: _result = _context2.sent; if (_result.visitorId && _result.sessionId) { requestData.pageId = _result.pageId; requestData.visitorId = _result.visitorId; requestData.sessionId = _result.sessionId; // Update cookie with the LivePerson session this.updateAIChatDrawerCookie((_this$updateAIChatDra = {}, _this$updateAIChatDra[StorageKeys.lpSession] = requestData, _this$updateAIChatDra)); } case 33: _context2.next = 38; break; case 35: _context2.prev = 35; _context2.t0 = _context2["catch"](18); console.error('[LP] failed to create lp-engagement session:', _context2.t0); case 38: return _context2.abrupt("return", requestData); case 39: case "end": return _context2.stop(); } }, _callee2, this, [[18, 35]]); })); function createLivePersonSession() { return _createLivePersonSession.apply(this, arguments); } return createLivePersonSession; }() /** * Get the LivePerson JWT * * @param {number} retryCount The number of retries * * @returns {Promise} The LivePerson JWT */ ; _proto.getLivePersonJWT = /*#__PURE__*/ function () { var _getLivePersonJWT = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(retryCount) { var _this3 = this; var timeoutPromise; return _regeneratorRuntime().wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: if (retryCount === void 0) { retryCount = 0; } timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.GET_JWT_TIMEOUT, 'Getting JWT for LivePerson timed out')); }, ms); }); }; return _context3.abrupt("return", Promise.race([LPUtils.getJWT(this.accountId, this.getAIChatDrawerCookieObject(), StorageKeys.lpJWT), timeoutPromise(livePersonResponseTimeout)])["catch"](function (error) { _this3.handleLivePersonError(error, function (newRetryCount) { return _this3.getLivePersonJWT(newRetryCount); }, retryCount); })); case 3: case "end": return _context3.stop(); } }, _callee3, this); })); function getLivePersonJWT(_x3) { return _getLivePersonJWT.apply(this, arguments); } return getLivePersonJWT; }() /** * Get the LivePerson UMS domain * * @returns {Promise} The LivePerson UMS domain */ ; _proto.getLivePersonUmsDomain = /*#__PURE__*/ function () { var _getLivePersonUmsDomain = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { return _regeneratorRuntime().wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: _context4.prev = 0; return _context4.abrupt("return", LPUtils.getDomain(this.accountId, 'asyncMessagingEnt')); case 4: _context4.prev = 4; _context4.t0 = _context4["catch"](0); console.error('Error fetching UMS domain:', _context4.t0); // Handle the error appropriately, e.g., show an error message to the user or retry the operation return _context4.abrupt("return", null); case 8: case "end": return _context4.stop(); } }, _callee4, this, [[0, 4]]); })); function getLivePersonUmsDomain() { return _getLivePersonUmsDomain.apply(this, arguments); } return getLivePersonUmsDomain; }() /** * Initialize the LivePerson websocket * * @param {string} umsDomain The LivePerson UMS domain * @param {number} retryCount The number of retries * * @returns {Promise} The LivePerson websocket instance */ ; _proto.initLivePersonWebsocket = /*#__PURE__*/ function () { var _initLivePersonWebsocket = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(umsDomain, retryCount) { var _this4 = this; var timeoutPromise; return _regeneratorRuntime().wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: if (retryCount === void 0) { retryCount = 0; } timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.INIT_WS_TIMEOUT, 'Initializing LivePerson websocket timed out')); }, ms); }); }; return _context5.abrupt("return", Promise.race([LPWs.connect("wss://" + umsDomain + "/ws_api/account/" + this.accountId + "/messaging/consumer?v=3"), timeoutPromise(livePersonResponseTimeout)])["catch"](function (error) { _this4.handleLivePersonError(error, function (newRetryCount) { return _this4.initLivePersonWebsocket(umsDomain, newRetryCount); }, retryCount); })); case 3: case "end": return _context5.stop(); } }, _callee5, this); })); function initLivePersonWebsocket(_x4, _x5) { return _initLivePersonWebsocket.apply(this, arguments); } return initLivePersonWebsocket; }(); /** * Update the LivePerson agent state in the UI * * @param {string} state The agent state */ _proto.updateAgentState = function updateAgentState(state) { // Designs do not have all states here. We may remove states if not needed. switch (state) { case livePersonChatStateTypes.ACTIVE: { // is in the chat break; } case livePersonChatStateTypes.INACTIVE: { // navigated away but application is still open break; } case livePersonChatStateTypes.GONE: { // closed the chat application break; } case livePersonChatStateTypes.COMPOSING: { // is typing // Dispatch bot typing activity to the store so it renders in the WebChat this.store.dispatch({ type: 'DIRECT_LINE/INCOMING_ACTIVITY', payload: { activity: { type: 'typing', from: { role: 'bot' }, timestamp: new Date().toISOString() } } }); break; } } } /** * Subscribe to LivePerson messaging events * * @param {string} dialogId The dialogId to subscribe to * @param {string} conversationId The conversationId to subscribe to. For main dialog, conversationId and dialogId * are the same. For survey dialog, conversationId and dialogId are different * @param {number} fromSeq The sequence number to start from * @param {number} retryCount The number of retries */; _proto.subscribeToLivePersonMessagingEvents = function subscribeToLivePersonMessagingEvents(dialogId, conversationId, fromSeq, retryCount) { var _this5 = this; if (fromSeq === void 0) { fromSeq = 0; } if (retryCount === void 0) { retryCount = 0; } this.lpWebsocket.subscribeMessagingEvents({ fromSeq: fromSeq, dialogId: dialogId, conversationId: conversationId }).then(function (response) { return _this5.handleLivePersonResponse(response); })["catch"](function (error) { return _this5.handleLivePersonError(error, function (newRetryCount) { return _this5.subscribeToLivePersonMessagingEvents(dialogId, conversationId, fromSeq, newRetryCount); }, retryCount); }); } /** * Handle response from LivePerson websocket. Throw an error if the response code is an error code. * * @param {Response} response The response from the LivePerson API * * @returns {Response} The response from the LivePerson API */; _proto.handleLivePersonResponse = function handleLivePersonResponse(response) { if (response.code >= 400 && response.code < 600) { throw Object.assign(new Error(response.body), { code: response.code }); } else { return response; } } /** * Handles errors from LivePerson API calls with retry logic. * LivePerson Retry Policy Recommendations: https://developers.liveperson.com/retry-policy-recommendations.html * * @param {Object} error - The error object returned from the LivePerson API. * @param {Function} retryCallback - The callback function to retry the API call. * @param {number} [retryCount=0] - The current retry attempt count. * @param {number} [maxRetries=3] - The maximum number of retry attempts. */; _proto.handleLivePersonError = function handleLivePersonError(error, retryCallback, retryCount, maxRetries) { var _this6 = this; if (retryCount === void 0) { retryCount = 0; } if (maxRetries === void 0) { maxRetries = 3; } // Max number of retries hit if (retryCount >= maxRetries) { console.error("Max retries reached for error type " + error.type + ":", error); if (error.type === LPErrorTypes.SEND_MESSAGE_TIMEOUT) { this.handleLivePersonSendMessageTimeout(error.data.messageId); } if (error.type === LPErrorTypes.USER_CLOSE_CONVERSATION_TIMEOUT) { // User atttempted to close conversation, but the request to LP timed out. // Return user to AI Chat so they are not stuck this.returnUIToAIChatBot(); } return; } if (!error.code || error.code >= 400 && error.code < 500) { if (error.code === 429 && typeof retryCallback === 'function') { // Request is being throttled due to rate-limiting // Too many requests, retry after at least 1 second (or 5 seconds for login requests), avoid bursts of requests var retryInterval = 1000; setTimeout(function () { retryCallback(retryCount + 1).then(function (response) { return _this6.handleLivePersonResponse(response); })["catch"](function (error) { return _this6.handleLivePersonError(error, retryCallback, retryCount + 1, maxRetries); }); }, retryInterval); } else { // Handle other types of errors switch (error.type) { case LPErrorTypes.SEND_MESSAGE_TIMEOUT: { // Retry sending the message retryCallback(error.data.messageId, retryCount + 1); break; } case LPErrorTypes.USER_CLOSE_CONVERSATION_TIMEOUT: { // Retry closing the conversation retryCallback(retryCount + 1); break; } case LPErrorTypes.WEBSOCKET_NOT_OPEN: { console.error('LivePerson websocket not open:', error); // Display a generic error message to the user this.setNotification(this.livePersonGenericErrorText, NotificationLevel.ERROR); break; } case LPErrorTypes.ACCEPT_STATUS_TIMEOUT: { // Retry updating the message accept status retryCallback(error.data.sequence, error.data.status, error.data.dialogId, retryCount + 1); break; } default: { console.error('Client-side error:', error); // Display a generic error message to the user this.setNotification(this.livePersonGenericErrorText, NotificationLevel.ERROR); break; } } } } else if (error.code >= 500 && error.code < 600) { // Server error, retry 3 times with 5, 10, 15 second pause between retries var retryDelays = [5000, 10000, 15000]; var delay = retryDelays[Math.min(retryCount, retryDelays.length - 1)]; setTimeout(function () { retryCallback(retryCount + 1).then(function (response) { return _this6.handleLivePersonResponse(response); })["catch"](function (error) { return _this6.handleLivePersonError(error, retryCallback, retryCount + 1, maxRetries); }); }, delay); } } /** * Update the status of a LivePerson message in the chat. For example, "Read" text will appear after * timestamp when the message is read by LivePerson. * * @param {number} sequence The sequence number of the message * @param {string} status The status of the message * @param {string} dialogId The dialogId of the message */; _proto.updateLivePersonMessageStatus = function updateLivePersonMessageStatus(sequence, status, dialogId) { // Get message element var messageElement = this.lpMessages[dialogId + "-" + sequence]; // Return if message element does not exist if (!messageElement) { return; } // Update the accept status messageElement.dataset.acceptStatus = status; switch (status) { case 'ACCEPT': { break; } case 'READ': { this.markMessageAsRead(messageElement); break; } } } /** * Handle LivePerson conversation notifications * * @param {Object} notificationBody The notification body */; _proto.handleLivePersonConversationNotification = function handleLivePersonConversationNotification(notificationBody) { var _this7 = this; notificationBody.changes.forEach(function (change) { var _this7$updateAIChatDr5; // Check if there are no active dialogs open var isConversationOpen = change.result.conversationDetails.state !== LPUtils.conversationStateTypes.CLOSE || change.result.conversationDetails.stage !== LPUtils.conversationStateTypes.CLOSE; // Get active dialog var activeDialog = change.result.conversationDetails.dialogs.find(function (d) { return d.state === LPUtils.conversationStateTypes.OPEN; }); // Check if post survey is enabled _this7.isPostSurveyEnabled = change.result.conversationDetails.state === LPUtils.conversationStateTypes.CLOSE && change.result.conversationDetails.stage === LPUtils.conversationStateTypes.OPEN; // Conversation is closed or there is no active dialog if (!isConversationOpen || !activeDialog) { if (Object.hasOwn(_this7.lpOpenConvs, change.result.convId)) { var _this7$lpWebsocket; // Only show the message if the survey was completed fully by the user if (!_this7.lpSurveyForcedClosed) { var _change$result, _change$result$conver; _this7.webChatSendMessage(_this7.livePersonSurveyCloseMessage, new Date((_change$result = change.result) == null ? void 0 : (_change$result$conver = _change$result.conversationDetails) == null ? void 0 : _change$result$conver.endTs).toISOString(), 'lp-system', null, null, null); } // Cancel the get clock interval (_this7$lpWebsocket = _this7.lpWebsocket) == null ? void 0 : _this7$lpWebsocket.getClockRequest.cancel(); // Cancel debounced chat states _this7.debouncedChatStateToComposing.cancel({ upcomingOnly: true }); _this7.debouncedChatStateToPause.cancel({ upcomingOnly: true }); // Reset the agent state _this7.updateAgentState(livePersonChatStateTypes.DEFAULT); // Unsubscribe from conversation metadata for this subscriptionId _this7.livePersonUnsubscribeExConversations(notificationBody.subscriptionId)["finally"](function () { var _this7$updateAIChatDr; // Reset subscribed to messaging events flag _this7.lpSubscribedToMessagingEvents = false; // Reset the current change sequence _this7.curLpChangeSequence = 0; // Return the UI to AI chat bot _this7.returnUIToAIChatBot(); // Delete the conversation from open conversations metadata object delete _this7.lpOpenConvs[change.result.convId]; // Update the cookie _this7.updateAIChatDrawerCookie((_this7$updateAIChatDr = {}, _this7$updateAIChatDr[StorageKeys.lpOpenConvs] = _this7.lpOpenConvs, _this7$updateAIChatDr)); }); } return; } // Check if this is a notification for a new conversation if (!_this7.lpOpenConvs[change.result.convId]) { var _this7$updateAIChatDr2; // Create and store conversation metadata _this7.lpOpenConvs[change.result.convId] = { result: { convId: change.result.convId, dialogs: change.result.conversationDetails.dialogs.map(function (dialog) { return { dialogId: dialog.dialogId, dialogType: dialog.dialogType }; }) }, activeDialogId: activeDialog.dialogId, chatState: livePersonChatStateTypes.DEFAULT, closeMsgSent: false }; // Update cookie _this7.updateAIChatDrawerCookie((_this7$updateAIChatDr2 = {}, _this7$updateAIChatDr2[StorageKeys.lpOpenConvs] = _this7.lpOpenConvs, _this7$updateAIChatDr2)); // Send event to PVA to record the new Live Person conversation ID to cosmos DB var eventValue = { skillId: _this7.skillId, LPConversationID: change.result.convId }; _this7.webChatSendEvent(EventName$k.LIVEPERSON_SAVE_IDS, eventValue); // Send transcript to LivePerson if user has elected to do so if (_this7.isSendTranscript) { _this7.sendTranscriptToLivePerson(); } // Subscribe to messaging events with active dialog id _this7.subscribeToLivePersonMessagingEvents(activeDialog.dialogId, change.result.convId); _this7.lpSubscribedToMessagingEvents = true; } // Check if there are new dialogs added to this conversation if (change.result.conversationDetails.dialogs.length !== _this7.lpOpenConvs[change.result.convId].result.dialogs.length) { var _this7$updateAIChatDr4; // if the new dialog is a survey dialog, post the conversation closed message if (change.result.conversationDetails.dialogs.some(function (dialog) { return dialog.dialogType === 'POST_SURVEY'; }) && // Check if the close message has already been sent in this conversation _this7.lpOpenConvs[change.result.convId] && !_this7.lpOpenConvs[change.result.convId].closeMsgSent) { var _change$result2, _change$result2$conve, _this7$updateAIChatDr3; var closeMessage = ''; // Show a message based on who closed the chat if (change.result.conversationDetails && change.result.conversationDetails.closeReason === 'CONSUMER') { closeMessage = _this7.livePersonUserClosedConversationText; } else if (change.result.conversationDetails && change.result.conversationDetails.closeReason === 'AGENT') { closeMessage = _this7.livePersonAgentClosedConversationText; } else { closeMessage = _this7.livePersonSystemClosedConversationText; } var timestamp = new Date().toISOString(); if (change.serverTimestamp) { // If serverTimestamp is available, use it timestamp = new Date(change.serverTimestamp).toISOString(); } else if ((_change$result2 = change.result) != null && (_change$result2$conve = _change$result2.conversationDetails) != null && _change$result2$conve.dialogs) { // If serverTimestamp is not available, use the end timestamp of the main dialog var mainDialog = change.result.conversationDetails.dialogs.find(function (dialog) { return dialog.dialogType === 'MAIN' && dialog.state === 'CLOSE'; }); if (mainDialog && mainDialog.endTs) { timestamp = new Date(mainDialog.endTs).toISOString(); } } _this7.webChatSendMessage(closeMessage, timestamp, 'lp-system', null, null, null); // Update the lpOpenConvs object to track the close message _this7.lpOpenConvs[change.result.convId].closeMsgSent = true; // Update the lpOpenConvs in the cookie _this7.updateAIChatDrawerCookie((_this7$updateAIChatDr3 = {}, _this7$updateAIChatDr3[StorageKeys.lpOpenConvs] = _this7.lpOpenConvs, _this7$updateAIChatDr3)); // Disable the chat message box _this7.toggleWebChatUserTextBoxDisabled(true); } // Track the active dialog // Update the dialog id in case the dialogs have switched _this7.lpOpenConvs[change.result.convId].activeDialogId = activeDialog.dialogId; // Update the cookie _this7.updateAIChatDrawerCookie((_this7$updateAIChatDr4 = {}, _this7$updateAIChatDr4[StorageKeys.lpOpenConvs] = _this7.lpOpenConvs, _this7$updateAIChatDr4)); // Subscribe to messaging events of the new active dialog id _this7.subscribeToLivePersonMessagingEvents(activeDialog.dialogId, change.result.convId); _this7.lpSubscribedToMessagingEvents = true; } // Check if we need to subscribe to messaging events for an existing conversation if (!_this7.lpSubscribedToMessagingEvents) { // Subscribe to messaging events with active dialog id, from the current change sequence _this7.subscribeToLivePersonMessagingEvents(activeDialog.dialogId, change.result.convId, _this7.curLpChangeSequence); _this7.lpSubscribedToMessagingEvents = true; } // Update the current conversation result details in open conversations metadata object _this7.lpOpenConvs[change.result.convId].result = { convId: change.result.convId, dialogs: change.result.conversationDetails.dialogs.map(function (dialog) { return { dialogId: dialog.dialogId, dialogType: dialog.dialogType }; }) }; // Update the cookie _this7.updateAIChatDrawerCookie((_this7$updateAIChatDr5 = {}, _this7$updateAIChatDr5[StorageKeys.lpOpenConvs] = _this7.lpOpenConvs, _this7$updateAIChatDr5)); if (change.type === 'UPSERT') { if (_this7.isPostSurveyEnabled) { _this7.toggleLivePersonDisclaimer(true, _this7.surveyBotDisclaimerText); return; } // Check for agent assignment var hasAgentAssigned = change.result.conversationDetails.participants.some(function (p) { return p.role === 'ASSIGNED_AGENT'; }); if (hasAgentAssigned) { if (!_this7.isLivePersonAgentAssigned) { // Change the disclaimer text to the Speaking With LivePerson disclaimer text _this7.toggleLivePersonDisclaimer(true, _this7.livePersonDisclaimerText); // Re-enable the chat message box, but not any other action-set buttons _this7.toggleWebChatUserTextBoxDisabled(false); // Keep track of agent assigned state _this7.isLivePersonAgentAssigned = true; } _this7.updateAgentState(livePersonChatStateTypes.ACTIVE); } else { _this7.updateAgentState(livePersonChatStateTypes.INACTIVE); } } }); } /** * Publish a message to LivePerson websocket * * @param {string} messageText The message text * @param {string} messageId The message ID * @returns {Promise} A promise that resolves when the message is published */; _proto.publishToLivePersonWebsocket = function publishToLivePersonWebsocket(messageText, messageId) { if (messageId === void 0) { messageId = null; } return this.lpWebsocket.publishEvent({ dialogId: this.lpOpenConvs[Object.keys(this.lpOpenConvs)[0]].activeDialogId, conversationId: Object.keys(this.lpOpenConvs)[0], event: { type: 'ContentEvent', contentType: 'text/plain', message: messageText }, messageId: messageId || Math.floor(Math.random() * 1e9) }); } /** * Send accept status to LivePerson websocket * * @param {string} status The status to send * @param {number} sequence The sequence number * @param {number} retryCount The number of retries */; _proto.acceptStatusToLivePersonWebsocket = function acceptStatusToLivePersonWebsocket(status, sequence, retryCount) { var _this8 = this; if (retryCount === void 0) { retryCount = 0; } var timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.ACCEPT_STATUS_TIMEOUT, 'Accept status to LivePerson timed out', { status: status, sequence: sequence })); }, ms); }); }; Promise.race([this.lpWebsocket.publishEvent({ dialogId: this.lpOpenConvs[Object.keys(this.lpOpenConvs)[0]].activeDialogId, conversationId: Object.keys(this.lpOpenConvs)[0], event: { type: 'AcceptStatusEvent', status: status, sequenceList: [sequence] } }), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this8.handleLivePersonResponse(response); })["catch"](function (error) { _this8.handleLivePersonError(error, function (newRetryCount) { return _this8.acceptStatusToLivePersonWebsocket(status, sequence, newRetryCount); }, retryCount); }); } /** * On close LivePerson websocket * * @param {Event} event The close event */; _proto.onCloseLivePersonWebsocket = /*#__PURE__*/ function () { var _onCloseLivePersonWebsocket = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(event) { var _this9 = this; var notificationId, pollingFunction, retryCondition; return _regeneratorRuntime().wrap(function _callee8$(_context8) { while (1) switch (_context8.prev = _context8.next) { case 0: if (this.isLivePersonChatActive) { _context8.next = 4; break; } console.warn('LivePerson websocket closed. event:', event); // Return the UI to the AI Chat Bot this.returnUIToAIChatBot(); return _context8.abrupt("return"); case 4: if (!(event.code === 4401 || event.code === 4407)) { _context8.next = 12; break; } console.warn('LivePerson websocket closed - API token expired. event:', event); // LivePerson API token expired // From LivePerson documentation - The client should return to the initation step, issue a fresh token, and reestablish the connection. // Display a message to the user that the connection to LivePerson was closed this.setNotification(this.livePersonSystemClosedConversationText, NotificationLevel.ERROR); this.lpWebsocket.ws = null; this.lpWebsocket = null; this.returnUIToAIChatBot(); _context8.next = 35; break; case 12: // From LivePerson documentation - For any other closeReason, the client should wait a few seconds and then try reconnecting. console.warn('LivePerson websocket closed - unknown reason. event:', event); this.isLivePersonAgentAssigned = false; // If there is an open conversation, try to reconnect after 3 seconds, then back off exponentially if (!(Object.keys(this.lpOpenConvs).length > 0)) { _context8.next = 31; break; } notificationId = null; pollingFunction = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() { return _regeneratorRuntime().wrap(function _callee6$(_context6) { while (1) switch (_context6.prev = _context6.next) { case 0: // eslint-disable-next-line no-console console.log('Attempting to reconnect to LivePerson...'); if (!notificationId) { // Display a warning notification to the user that they were disconnected, and trying to reconnect notificationId = _this9.setNotification(_this9.livePersonDisconnectedReconnectingText, NotificationLevel.WARN); } // Exit early if LivePerson chat is no longer active if (_this9.isLivePersonChatActive) { _context6.next = 7; break; } console.warn('LivePerson chat is no longer active. Returning UI to AI Chat Bot.'); _this9.dismissNotification(notificationId); _this9.returnUIToAIChatBot(); return _context6.abrupt("return", { success: false }); case 7: _context6.prev = 7; _context6.next = 10; return _this9.initLivePersonChat(); case 10: // Reconnected successfully. Update the notification and return a success response, and close the notification // after 10 seconds // eslint-disable-next-line no-console console.log('Reconnected to LivePerson successfully.'); _this9.setNotification(_this9.livePersonReconnectedText, NotificationLevel.SUCCESS, notificationId); setTimeout(function () { return _this9.dismissNotification(notificationId); }, 10000); return _context6.abrupt("return", { success: true }); case 16: _context6.prev = 16; _context6.t0 = _context6["catch"](7); // Did not reconnect successfully. Log the error and return a failure response console.error('Error reconnecting to LivePerson:', _context6.t0); return _context6.abrupt("return", { success: false }); case 20: case "end": return _context6.stop(); } }, _callee6, null, [[7, 16]]); })); return function pollingFunction() { return _ref2.apply(this, arguments); }; }(); retryCondition = /*#__PURE__*/function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(response, error, _options) { return _regeneratorRuntime().wrap(function _callee7$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: if (_this9.isLivePersonChatActive) { _context7.next = 2; break; } return _context7.abrupt("return", false); case 2: return _context7.abrupt("return", Boolean(error) || response && !response.success); case 3: case "end": return _context7.stop(); } }, _callee7); })); return function retryCondition(_x7, _x8, _x9) { return _ref3.apply(this, arguments); }; }(); _context8.prev = 18; _context8.next = 21; return LPUtils.exponentialBackoff(pollingFunction, retryCondition, { maxRetries: 7, // Maximum number of retries delayInSeconds: 3 // Initial delay in seconds }); case 21: _context8.next = 29; break; case 23: _context8.prev = 23; _context8.t0 = _context8["catch"](18); // All attempts to reconnect failed. Log the error and return the UI to the AI Chat Bot console.error('Failed to reconnect to LivePerson:', _context8.t0); this.lpWebsocket.ws = null; this.lpWebsocket = null; this.returnUIToAIChatBot(); case 29: _context8.next = 35; break; case 31: // If there are no open conversations, return the UI to the AI Chat Bot console.warn('No open LivePerson conversations. Returning UI to AI Chat Bot.'); this.lpWebsocket.ws = null; this.lpWebsocket = null; this.returnUIToAIChatBot(); case 35: case "end": return _context8.stop(); } }, _callee8, this, [[18, 23]]); })); function onCloseLivePersonWebsocket(_x6) { return _onCloseLivePersonWebsocket.apply(this, arguments); } return onCloseLivePersonWebsocket; }() /** * Sends an event activity to the bot framework store. * * @param {string} eventName The name of the event * @param {Object} eventValue The value for the event (typically an object) */ ; _proto.webChatSendEvent = function webChatSendEvent(eventName, eventValue) { if (!this.store) { console.error('Error sending event to bot. WebChat store is not defined.'); return; } this.store.dispatch({ type: 'DIRECT_LINE/POST_ACTIVITY', meta: { method: 'keyboard' }, payload: { activity: { channelData: { postBack: true }, name: eventName, type: 'event', value: eventValue } } }); } /** * Dispatch an incoming-activity message to the bot framework store. * The 'store' adds the message bubble to the transcript window, using the 'role' to style the message as 'bot', 'user', or * our custom 'lp-system' message. * Only used when connected to a Live Person conversation, and for post Live Person conversation's survey messages. * * @params {string} message The message to dispatch * @param {string} timestamp The timestamp of the message * @param {string} role The role of the message sender: "bot", "user", or "lp-system" * @param {string} originatorId The originator id of the message sender * @param {string} messageId The id of the message. If not provided, a random id is generated * @param {number} messageSequence The sequence number of the message (only applies when rendering a message received from * LivePerson websocket) */; _proto.webChatSendMessage = function webChatSendMessage(message, timestampForWebChat, roleForWebChat, originatorId, messageId, messageSequence) { if (messageId === void 0) { messageId = null; } if (messageSequence === void 0) { messageSequence = null; } var processedMessage = message.replace(/#\/?md#/g, ''); // Removes all HTML tags from the message to avoid HTML injection into the WebStore processedMessage = new DOMParser().parseFromString(processedMessage, 'text/html').body.textContent; // If id is not provided, generate a random id if (!messageId) { messageId = Math.floor(Math.random() * 1e9); } // Ensure messageId is a string messageId = String(messageId); // Dispatch message to WebChat store so it renders in the WebChat UI this.store.dispatch({ type: 'DIRECT_LINE/INCOMING_ACTIVITY', payload: { activity: { type: 'message', text: processedMessage, from: { id: originatorId, role: roleForWebChat }, id: messageId, sequence: messageSequence, timestamp: timestampForWebChat } } }); }; /** * Initialize the LivePerson connection * * @param {number} retryCount The number of retries */ _proto.initLivePersonConnection = function initLivePersonConnection(retryCount) { var _this10 = this; if (retryCount === void 0) { retryCount = 0; } var timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.INIT_CONNECTION_TIMEOUT, 'Initializing LivePerson connection timed out')); }, ms); }); }; // Resolve the promise that completes first Promise.race([this.lpWebsocket.initConnection({}, [{ type: '.ams.headers.ConsumerAuthentication', jwt: this.lpJWT }, { type: '.ams.headers.ClientProperties', features: ['AUTO_MESSAGES', 'RICH_CONTENT', 'QUICK_REPLIES', 'MULTI_DIALOG', 'MARKDOWN_HYPERLINKS'] }]), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this10.handleLivePersonResponse(response); })["catch"](function (error) { _this10.handleLivePersonError(error, function (newRetryCount) { return _this10.initLivePersonConnection(newRetryCount); }, retryCount); }); } /** * Subscribe to LivePerson open conversations metadata * * @param {number} retryCount The number of retries * * @returns {Promise} A promise that resolves when the LivePerson websocket is subscribed to conversations metadata. * Existing conversations that match the filter will also be sent. The promise rejects if the * request times out. */; _proto.livePersonSubscribeExConversations = /*#__PURE__*/ function () { var _livePersonSubscribeExConversations = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(retryCount) { var _this11 = this; var timeoutPromise; return _regeneratorRuntime().wrap(function _callee9$(_context9) { while (1) switch (_context9.prev = _context9.next) { case 0: if (retryCount === void 0) { retryCount = 0; } timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.SUBSCRIBE_CONVERSATION_TIMEOUT, 'Subscribing to LivePerson conversation metadata timed out')); }, ms); }); }; return _context9.abrupt("return", Promise.race([this.lpWebsocket.subscribeExConversations({ stage: [LPUtils.conversationStageTypes.OPEN, LPUtils.conversationStageTypes.CLOSE], convState: [LPUtils.conversationStateTypes.OPEN, LPUtils.conversationStateTypes.CLOSE] }), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this11.handleLivePersonResponse(response); })["catch"](function (error) { _this11.handleLivePersonError(error, function (newRetryCount) { return _this11.livePersonSubscribeExConversations(newRetryCount); }, retryCount); })); case 3: case "end": return _context9.stop(); } }, _callee9, this); })); function livePersonSubscribeExConversations(_x10) { return _livePersonSubscribeExConversations.apply(this, arguments); } return livePersonSubscribeExConversations; }() /** * Unsubscribe from LivePerson conversation * * @param {string} subscriptionId The subscriptionId to unsubscribe from * @param {number} retryCount The number of retries * * @returns {Promise} A promise that resolves when the LivePerson websocket is unsubscribed from the conversation */ ; _proto.livePersonUnsubscribeExConversations = /*#__PURE__*/ function () { var _livePersonUnsubscribeExConversations = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(subscriptionId, retryCount) { var _this12 = this; var timeoutPromise; return _regeneratorRuntime().wrap(function _callee10$(_context10) { while (1) switch (_context10.prev = _context10.next) { case 0: if (retryCount === void 0) { retryCount = 0; } timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.UNSUBSCRIBE_CONVERSATION_TIMEOUT, 'Unsubscribing from LivePerson conversation metadata timed out')); }, ms); }); }; return _context10.abrupt("return", Promise.race([this.lpWebsocket.unsubscribeExConversations({ subscriptionId: subscriptionId }), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this12.handleLivePersonResponse(response); })["catch"](function (error) { _this12.handleLivePersonError(error, function (newRetryCount) { return _this12.livePersonUnsubscribeExConversations(subscriptionId, newRetryCount); }, retryCount); })); case 3: case "end": return _context10.stop(); } }, _callee10, this); })); function livePersonUnsubscribeExConversations(_x11, _x12) { return _livePersonUnsubscribeExConversations.apply(this, arguments); } return livePersonUnsubscribeExConversations; }() /** * Disables all survey response buttons in the last message to prevent further interaction. * */ ; _proto.disablePreviousQuestionSurveyResponseButtons = function disablePreviousQuestionSurveyResponseButtons() { if (!this.isPostSurveyEnabled) return; // Get all survey messages except the last one (current question awaiting a response) var surveyMessages = Array.from(this.el.querySelectorAll("section" + Selector$j.WEB_CHAT_TRANSCRIPT_TRANSCRIPT + " " + Selector$j.ARTICLE)).slice(0, -1); // Iterate over the survey messages and disable buttons surveyMessages.forEach(function (message) { var buttons = message.querySelectorAll(Selector$j.POST_SURVEY_JSON_POLLOCK_BUTTON); buttons.forEach(function (button) { button.disabled = true; }); }); } /** * Consumer request conversation to LivePerson * * @param {number} retryCount The number of retries */; _proto.livePersonConsumerRequestConversation = function livePersonConsumerRequestConversation(retryCount) { var _this13 = this; if (retryCount === void 0) { retryCount = 0; } var timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.CONSUMER_REQUEST_CONVERSATION_TIMEOUT, 'Consumer request conversation to LivePerson timed out')); }, ms); }); }; Promise.race([this.lpWebsocket.consumerRequestConversation({ skillId: this.skillId, conversationContext: { visitorId: this.lpSession.visitorId, sessionId: this.lpSession.sessionId, lang: document.documentElement.lang, type: 'SharkContext', features: ['AUTO_MESSAGES', 'RICH_CONTENT', 'QUICK_REPLIES', 'MULTI_DIALOG', 'MARKDOWN_HYPERLINKS'] } }), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this13.handleLivePersonResponse(response); })["catch"](function (error) { _this13.handleLivePersonError(error, function (newRetryCount) { return _this13.livePersonConsumerRequestConversation(newRetryCount); }, retryCount); }); } /** * Updates or waits for a LivePerson message element in the DOM, setting its originator and optionally updating its timestamp. * * - If the message element already exists, updates its `originator` dataset property. * - If the element has a `data-lp-message-id` attribute, calls `webChatSendMessage` to update the message with the server timestamp. * - If the element does not exist, observes the DOM for its appearance, updates its `originator`, and resolves when found or after a timeout. * * @async * @param {string} messageText - The text content of the message. * @param {string} dialogId - The dialog ID associated with the message. * @param {string|number} sequence - The sequence number of the message within the dialog. * @param {string} originatorId - The ID of the message originator. * @param {string} roleForWebChat - The role (e.g., 'user', 'agent') for the web chat. * @param {string} timestampFromServerString - The timestamp string from the server. * @returns {Promise} Resolves with the message element when found or updated, or `null` if not found within the timeout. */; _proto.updateLivePersonMessageInDOM = /*#__PURE__*/ function () { var _updateLivePersonMessageInDOM = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(messageText, dialogId, sequence, originatorId, roleForWebChat, timestampFromServerString) { var _this14 = this; return _regeneratorRuntime().wrap(function _callee11$(_context11) { while (1) switch (_context11.prev = _context11.next) { case 0: return _context11.abrupt("return", new Promise(function (resolve) { // Check if element already exists var messageElem = _this14.webChatTranscriptElem.querySelector("[data-lp-message-dialog-id=\"" + dialogId + "\"][data-lp-message-sequence=\"" + sequence + "\"]"); if (messageElem) { messageElem.dataset.originator = roleForWebChat; // If message has an has a data-lp-message-id attribute, it was already rendered from a user message send. Call webChatSendMessage to // update the message in the transcript with the timestamp from the server to ensure that the message is rendered // in the correct order var messageId = messageElem.dataset.lpMessageId; if (messageId) { _this14.webChatSendMessage(messageText, timestampFromServerString, roleForWebChat, originatorId, messageId, sequence); resolve(messageElem); return; } resolve(messageElem); return; } // Set up observer to wait for the element to appear var observer = new MutationObserver(function () { var messageElem = _this14.webChatTranscriptElem.querySelector("[data-lp-message-dialog-id=\"" + dialogId + "\"][data-lp-message-sequence=\"" + sequence + "\"]"); if (messageElem) { messageElem.dataset.originator = roleForWebChat; observer.disconnect(); clearTimeout(observerTimeout); resolve(messageElem); } }); // Start observing the transcript for changes observer.observe(_this14.webChatTranscriptElem, { childList: true, subtree: true, attributes: true, attributeFilter: ['data-lp-message-dialog-id', 'data-lp-message-sequence'] }); // Set a timeout to avoid hanging indefinitely var observerTimeout = setTimeout(function () { observer.disconnect(); console.warn("Message element for dialogId=" + dialogId + ", sequence=" + sequence + " not found within timeout period"); resolve(null); }, 5000); })); case 1: case "end": return _context11.stop(); } }, _callee11); })); function updateLivePersonMessageInDOM(_x13, _x14, _x15, _x16, _x17, _x18) { return _updateLivePersonMessageInDOM.apply(this, arguments); } return updateLivePersonMessageInDOM; }() /** * Renders quick reply options inside a LivePerson survey chat message element using JsonPollock. * * @param {Object} quickRepliesData - The data object representing quick replies to render. * @param {HTMLElement} messageElem - The DOM element representing the chat message bubble. * @param {boolean} [requiresStarReplacement=false] - Indicates if rating star replacement is required for the survey. * * @throws {Error} Logs an error if rendering fails or required elements are not found. */ ; _proto.renderQuickReplies = function renderQuickReplies(quickRepliesData, messageElem, requiresStarReplacement) { if (requiresStarReplacement === void 0) { requiresStarReplacement = false; } if (!quickRepliesData || !messageElem) return; try { var container = window.JsonPollock.render(quickRepliesData); var bubbleContent = messageElem.querySelector(Selector$j.WEB_CHAT_BUBBLE_CONTENT); if (!bubbleContent) { console.error('webchat__bubble__content element not found in the messageElem'); return; } // Append the rendered container bubbleContent.append(container); // If post-survey is enabled if (this.isPostSurveyEnabled) { // Set data attribute based on requiresStarReplacement flag bubbleContent.dataset.requiresStarReplacement = requiresStarReplacement.toString(); // Add class to distinguish survey questions bubbleContent.classList.add(ClassName$d.LP_SURVEY_QUESTIONNAIRE); // If requiresStarReplacement is false, add 'lp-pcs-richContent' class for styling rich content if (!requiresStarReplacement) { bubbleContent.classList.add(ClassName$d.LP_SURVEY_RICH_CONTENT); } } } catch (error) { console.error('Error rendering quick replies:', error); } } /** * Accepts a message via the LivePerson WebSocket if the role is not 'user'. * * @param {string} roleForWebChat - The role associated with the web chat message. * @param {number} sequence - The sequence number for the message. */; _proto.acceptMessageIfNotUser = function acceptMessageIfNotUser(roleForWebChat, sequence) { if (roleForWebChat !== 'user') { this.acceptStatusToLivePersonWebsocket(LPUtils.acceptStatusTypes.ACCEPT, sequence); } } /** * Handle LivePerson opened websocket * * @returns {Promise} A promise that resolves when the LivePerson websocket is opened */; _proto.handleLivePersonOpenedSocket = /*#__PURE__*/ function () { var _handleLivePersonOpenedSocket = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12() { var _this15 = this, _subscribeExConversat; var userId, subscribeExConversationsResponse; return _regeneratorRuntime().wrap(function _callee12$(_context12) { while (1) switch (_context12.prev = _context12.next) { case 0: this.lpWebsocket.registerRequests(livePersonApiRequestTypes); userId = _classPrivateFieldLooseBase(this, _getLivePersonIdFromJWT)[_getLivePersonIdFromJWT](); if (userId) { _context12.next = 6; break; } console.error('No LivePerson userId found'); this.setNotification(NotificationLevel.ERROR, this.livePersonGenericErrorText); return _context12.abrupt("return"); case 6: this.initLivePersonConnection(); this.lpWebsocket.onNotification(withType('MessagingEvent'), function (body) { var _body$changes; return (_body$changes = body.changes) == null ? void 0 : _body$changes.forEach(function (change) { var originatorId = change.originatorMetadata.id; var roleForWebChat = change.originatorId === userId ? 'user' : 'bot'; if (change.sequence) { _this15.curLpChangeSequence = change.sequence; } // publish the survey response to LivePerson Chat if (!_this15.isSurveyTextActionPublished && change.sequence) { window.JsonPollock.registerAction('publishText', function (data) { _this15.acceptStatusToLivePersonWebsocket(LPUtils.acceptStatusTypes.ACTION, change.sequence); _this15.handleLivePersonSendMessage(data.actionData.text); }); _this15.isSurveyTextActionPublished = true; } switch (change.event.type) { case 'RichContentEvent': { // Extract message text from the first element of content var messageTextElement = change.event.content.elements.find(function (el) { return el.type === 'text'; }); var messageText = messageTextElement ? messageTextElement.text : ''; var serverTimestampString = new Date(change.serverTimestamp).toISOString(); _this15.webChatSendMessage(messageText, serverTimestampString, roleForWebChat, originatorId, null, change.sequence); // Update message in DOM _this15.updateLivePersonMessageInDOM(messageText, change.dialogId, change.sequence, originatorId, roleForWebChat, serverTimestampString).then(function (messageElem) { _this15.lpMessages[change.dialogId + "-" + change.sequence] = messageElem; // Prepare buttons data for JSON-Pollock rendering var buttonElements = change.event.content.elements.filter(function (el) { return el.type === 'button'; }); if (buttonElements.length > 0) { var quickRepliesData = { type: change.event.content.type, elements: buttonElements.map(function (button) { return { type: button.type, title: button.title, tooltip: button.tooltip, click: { actions: button.click.actions } }; }) }; _this15.renderQuickReplies(quickRepliesData, messageElem, false); } }); break; } case 'ContentEvent': { var _serverTimestampString = new Date(change.serverTimestamp).toISOString(); if (roleForWebChat === 'user' && (change.event.message.startsWith(_this15.transcriptIntroText) || change.event.message.startsWith(_this15.transcriptContinuedText))) { // Don't render transcript messages the user sent to LivePerson in the WebChat UI break; } // If the transcript does not already contain the message, render it in the WebChat UI if (!_this15.webChatTranscriptElem.querySelector("[data-lp-message-dialog-id=\"" + change.dialogId + "\"][data-lp-message-sequence=\"" + change.sequence + "\"]")) { _this15.webChatSendMessage(change.event.message, _serverTimestampString, roleForWebChat, originatorId, null, change.sequence); } // Update message in DOM _this15.updateLivePersonMessageInDOM(change.event.message, change.dialogId, change.sequence, originatorId, roleForWebChat, _serverTimestampString).then(function (messageElem) { var _change$metadata, _change$metadata$; _this15.lpMessages[change.dialogId + "-" + change.sequence] = messageElem; // Accept the message to acknowledge as received - note this is not a READ receipt _this15.acceptMessageIfNotUser(roleForWebChat, change.sequence); // Handle quick replies if present if (change.event.quickReplies && Array.isArray(change.event.quickReplies.replies)) { var quickRepliesData = { type: 'horizontal', elements: change.event.quickReplies.replies.map(function (reply) { return { type: reply.type, title: reply.title, tooltip: reply.tooltip, click: { actions: reply.click.actions } }; }) }; _this15.renderQuickReplies(quickRepliesData, messageElem, true); } else if (((_change$metadata = change.metadata) == null ? void 0 : (_change$metadata$ = _change$metadata[0]) == null ? void 0 : _change$metadata$.type) === 'Question' && _this15.isPostSurveyEnabled) { // If the message is a question and part of the survey that ALSO doesn't have quick replies... re-enable the chat message box // Regrettably, this is a workaround for the fact that the LivePerson API doesn't provide a way to determine if a message is a question // with buttons or a freeform text question. _this15.toggleWebChatUserTextBoxDisabled(false); } }); break; } case 'ChatStateEvent': { if (roleForWebChat !== 'user' && roleForWebChat !== 'lp-system') { _this15.updateAgentState(change.event.chatState); } break; } case 'AcceptStatusEvent': { change.event.sequenceList.forEach(function (sequence) { return _this15.updateLivePersonMessageStatus(sequence, change.event.status, change.dialogId); }); break; } } }); }); // If there is an existing subscriptionId, user is reconnecting to websocket. Set lpSubscribedToMessagingEvents to false // since we are getting a new subscriptionId from livePersonSubscribeExConversations if (this.lpSubscriptionId) { this.lpSubscribedToMessagingEvents = false; } // subscribe to open conversations metadata _context12.next = 11; return this.livePersonSubscribeExConversations(); case 11: subscribeExConversationsResponse = _context12.sent; if ((_subscribeExConversat = subscribeExConversationsResponse.body) != null && _subscribeExConversat.subscriptionId) { _context12.next = 16; break; } console.error('No subscriptionId found in LivePerson subscribeExConversations response'); this.setNotification(NotificationLevel.ERROR, this.livePersonGenericErrorText); return _context12.abrupt("return"); case 16: this.lpSubscriptionId = subscribeExConversationsResponse.body.subscriptionId; // handle notifications for open conversations this.lpWebsocket.onNotification(withSubscriptionID(this.lpSubscriptionId), function (notificationBody) { _this15.handleLivePersonConversationNotification(notificationBody); }); // If no open conversations, request a new conversation if (!Object.keys(this.lpOpenConvs)[0]) { this.livePersonConsumerRequestConversation(); } // Add event listener for textarea changes this.webChatTextarea.addEventListener(EventName$k.INPUT, this.handleLpUserInput); // Listen for user publishing content (sending messages) to LivePerson this.lpWebsocket.onPublishContent(function (contentObj, timestampString) { return new Promise(function (resolve, reject) { try { if (contentObj.body.event.message.startsWith(_this15.transcriptIntroText) || contentObj.body.event.message.startsWith(_this15.transcriptContinuedText)) { // Don't render transcript messages the user is sending to LivePerson resolve(); return; } // Render the message in the WebChat UI immediately, that way when success/error/timeout happens, // we can find the rendered message by id and update it as needed _this15.webChatSendMessage(contentObj.body.event.message, timestampString, 'user', userId, contentObj.id, null); // Use setTimeout to wait until the message is rendered in the WebChat UI setTimeout(function () { // Dispatch event that LivePerson message is rendered var event = new CustomEvent(EventName$k.LIVEPERSON_MESSAGE_RENDERED, { detail: { messageId: contentObj.id } }); window.dispatchEvent(event); // Resolve the promise when done resolve(); }); } catch (error) { // Add messageId to error object data error.data.messageId = contentObj.id; // Reject the promise if there's an error reject(error); } }); }); // Add event listener for closing the LivePerson websocket this.lpWebsocket.ws.addEventListener(EventName$k.CLOSE, function (event) { return _this15.onCloseLivePersonWebsocket(event); }); case 22: case "end": return _context12.stop(); } }, _callee12, this); })); function handleLivePersonOpenedSocket() { return _handleLivePersonOpenedSocket.apply(this, arguments); } return handleLivePersonOpenedSocket; }() /** * Initialize the LivePerson chat * * @returns {Promise} A promise that resolves when the LivePerson chat is initialized */ ; _proto.initLivePersonChat = /*#__PURE__*/ function () { var _initLivePersonChat = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13() { var _this16 = this; var isExistingConversation, isAgentAvailable, _this$updateAIChatDra2, _this$lpWebsocket$ws, umsDomain, chatTranscript, mutationConfig; return _regeneratorRuntime().wrap(function _callee13$(_context13) { while (1) switch (_context13.prev = _context13.next) { case 0: // Disable the chat box and any action buttons until agent is connected this.toggleWebChatDisabled(true); isExistingConversation = Object.keys(this.lpOpenConvs).length > 0; isAgentAvailable = false; if (isExistingConversation) { _context13.next = 7; break; } _context13.next = 6; return this.checkLivePersonAgentAvailability(); case 6: isAgentAvailable = _context13.sent; case 7: if (!(isExistingConversation || isAgentAvailable)) { _context13.next = 48; break; } _context13.next = 10; return this.createLivePersonSession(); case 10: this.lpSession = _context13.sent; if (this.lpSession.sessionId) { _context13.next = 15; break; } console.error('No LivePerson Session found'); this.toggleWebChatDisabled(false); return _context13.abrupt("return"); case 15: _context13.next = 17; return this.getLivePersonJWT(); case 17: this.lpJWT = _context13.sent; if (this.lpJWT) { _context13.next = 22; break; } console.error('No LivePerson JWT found'); this.toggleWebChatDisabled(false); return _context13.abrupt("return"); case 22: // Update cookie with the LivePerson JWT this.updateAIChatDrawerCookie((_this$updateAIChatDra2 = {}, _this$updateAIChatDra2[StorageKeys.lpJWT] = this.lpJWT, _this$updateAIChatDra2)); _context13.next = 25; return this.getLivePersonUmsDomain(); case 25: umsDomain = _context13.sent; if (umsDomain) { _context13.next = 30; break; } console.error('No LivePerson UMS domain found'); this.toggleWebChatDisabled(false); return _context13.abrupt("return"); case 30: if (!(!this.lpWebsocket || ((_this$lpWebsocket$ws = this.lpWebsocket.ws) == null ? void 0 : _this$lpWebsocket$ws.readyState) !== WebSocket.OPEN)) { _context13.next = 34; break; } _context13.next = 33; return this.initLivePersonWebsocket(umsDomain); case 33: this.lpWebsocket = _context13.sent; case 34: if (this.lpWebsocket) { _context13.next = 38; break; } console.error('No LivePerson websocket found'); this.toggleWebChatDisabled(false); return _context13.abrupt("return"); case 38: _context13.next = 40; return _classPrivateFieldLooseBase(this, _initializeJsonPollock)[_initializeJsonPollock](); case 40: this.handleLivePersonOpenedSocket(); // Begin watching the transcript window for new Article elements; specifically the messages // from an Agent. We will add intersection observers to the new elements to detect when the User // has read them. if (!this.lpMutationObserver) { chatTranscript = this.el.querySelector(Selector$j.WEB_CHAT_TRANSCRIPT_TRANSCRIPT); this.lpMutationObserver = new MutationObserver(function (mutations) { for (var _iterator = _createForOfIteratorHelperLoose(mutations), _step; !(_step = _iterator()).done;) { var mutation = _step.value; if (mutation.type === 'childList') { mutation.addedNodes.forEach(function (node) { if (node.nodeName.toLowerCase() === Selector$j.ARTICLE && !node.querySelector(Selector$j.WEB_CHAT_BUBBLE_FROM_USER)) { // filter out articles that are from user messages _this16.observeArticleForLivePersonRead(node); _this16.disablePreviousQuestionSurveyResponseButtons(); // Disable previous survey response buttons } }); } } }); mutationConfig = { childList: true, subtree: false }; this.lpMutationObserver.observe(chatTranscript, mutationConfig); } // Set this to true once connected to a live agent this.isLivePersonChatActive = true; // Switch to LivePerson Chat In Queue disclaimer text once connected to a live agent this.toggleLivePersonDisclaimer(true, this.livePersonInQueueText); this.updateDrawerTitleText(this.drawerLivePersonTitleText); this.updateButtonTitleText(this.buttonLivePersonTitleText); _context13.next = 50; break; case 48: // Post a message to the user that no agent is available. this.webChatSendMessage(this.livePersonNoAgentsText, new Date().toISOString(), 'bot', null, null, null); this.toggleWebChatDisabled(false); case 50: case "end": return _context13.stop(); } }, _callee13, this); })); function initLivePersonChat() { return _initLivePersonChat.apply(this, arguments); } return initLivePersonChat; }() /** * Handle user closing main LivePerson conversation * * @param {number} retryCount The current retry count */ ; _proto.handleUserCloseLivePersonConversation = /*#__PURE__*/ function () { var _handleUserCloseLivePersonConversation = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee14(retryCount) { var _this17 = this; var conversationId, timeoutPromise; return _regeneratorRuntime().wrap(function _callee14$(_context14) { while (1) switch (_context14.prev = _context14.next) { case 0: if (retryCount === void 0) { retryCount = 0; } if (this.isPostSurveyEnabled) { this.lpSurveyForcedClosed = true; // The End live chat button was clicked *during* the survey. Track this so we don't send a survey close message. } conversationId = Object.keys(this.lpOpenConvs)[0]; if (conversationId) { timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.USER_CLOSE_CONVERSATION_TIMEOUT, 'User closing LivePerson conversation timed out')); }, ms); }); }; Promise.race([this.lpWebsocket.updateConversationField({ conversationId: conversationId, conversationField: [{ field: 'DialogChange', type: 'UPDATE', dialog: { dialogId: this.lpOpenConvs[conversationId].activeDialogId, state: LPUtils.conversationStateTypes.CLOSE, closedCause: 'Closed by consumer' } }] }), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { return _this17.handleLivePersonResponse(response); })["catch"](function (error) { _this17.handleLivePersonError(error, function (newRetryCount) { return _this17.handleUserCloseLivePersonConversation(newRetryCount); }, retryCount); }); } else { console.warn('User closing LivePerson conversation, but no LivePerson conversation found...'); this.returnUIToAIChatBot(); } case 4: case "end": return _context14.stop(); } }, _callee14, this); })); function handleUserCloseLivePersonConversation(_x19) { return _handleUserCloseLivePersonConversation.apply(this, arguments); } return handleUserCloseLivePersonConversation; }() /** * Return the UI to the AI Chat Bot state */ ; _proto.returnUIToAIChatBot = function returnUIToAIChatBot() { var _this$lpMutationObser; // ensure the forced close state is reset this.lpSurveyForcedClosed = false; // Set isLivePersonChatActive to false this.isLivePersonChatActive = false; // Switch back to AI Chat disclaimer text this.toggleLivePersonDisclaimer(false); // Reset the agent assigned state this.isLivePersonAgentAssigned = false; // Enable the chat box this.toggleWebChatDisabled(false); // Reset isSendTranscript flag this.isSendTranscript = false; // Focus the WebChat textarea this.webChatTextarea.focus(); // Remove the mutation observer (_this$lpMutationObser = this.lpMutationObserver) == null ? void 0 : _this$lpMutationObser.disconnect(); // Remove the event listener for textarea changes this.webChatTextarea.removeEventListener(EventName$k.INPUT, this.handleLpUserInput); // Return text to the standard AI Chat text this.updateDrawerTitleText(this.drawerTitleText); this.updateButtonTitleText(this.buttonTitleText); // Reset and close the LivePerson websocket to ensure a fresh connection next time if (this.lpWebsocket) { if (this.lpWebsocket.ws && this.lpWebsocket.ws.readyState === WebSocket.OPEN) { // Only try to close if it's open this.lpWebsocket.ws.close(); } this.lpWebsocket = null; } // Reset the subscription ID so a new one will be created on reconnect this.lpSubscriptionId = null; // Clear any stored conversations this.lpOpenConvs = {}; this.lpMessages = {}; this.curLpChangeSequence = 0; this.lpSubscribedToMessagingEvents = false; } /** * Observe article elements for LivePerson read status * * @param {HTMLElement} article The article element to observe */; _proto.observeArticleForLivePersonRead = function observeArticleForLivePersonRead(article) { var _this18 = this; var articleObserver = new IntersectionObserver(function (entries, observer) { entries.forEach(function (entry) { if (entry.intersectionRatio >= 0.9 && entry.target.dataset.lpMessageSequence && entry.target.dataset.lpMessageSequence !== 'pending') { var sequence = entry.target.dataset.lpMessageSequence; _this18.acceptStatusToLivePersonWebsocket(LPUtils.acceptStatusTypes.READ, sequence); observer.unobserve(entry.target); observer.disconnect(); } }); }, { threshold: 0.9 }); articleObserver.observe(article); } /** * Update AI Chat Drawer title text * * @param {string} text The text to update the title with */; _proto.updateDrawerTitleText = function updateDrawerTitleText(text) { this.el.querySelector(Selector$j.BLOCK_FEATURE_TITLE).textContent = text; } /** * Update AI Chat Button title text * * @param {string} text The text to update the title with */; _proto.updateButtonTitleText = function updateButtonTitleText(text) { this.aiChatButton.querySelector(Selector$j.AI_CHAT_BUTTON_TEXT + " span").textContent = text; } /** * Shows or Hides the Live Person specific 'Disclaimer Text', while hiding any other disclaimer text. * @param {boolean} true if we should switch to the Live Person disclaimer, false if we should switch it back to the AI-Assistant disclaimer */; _proto.toggleLivePersonDisclaimer = function toggleLivePersonDisclaimer(isShown, disclaimerText) { var _this19 = this; if (isShown) { var lpDisclaimerTextSpan = document.createElement('span'); lpDisclaimerTextSpan.textContent = disclaimerText; var lpDisclaimerButton = document.createElement('a'); lpDisclaimerButton.href = '#'; lpDisclaimerButton.setAttribute('role', 'button'); lpDisclaimerButton.classList.add(ClassName$d.RETURN_TO_AI_CHAT); lpDisclaimerButton.innerHTML = "" + this.returnToAiChatText + ""; lpDisclaimerButton.addEventListener(EventName$k.CLICK, function (event) { event.preventDefault(); _this19.handleUserCloseLivePersonConversation(); }); lpDisclaimerButton.addEventListener(EventName$k.KEYDOWN, function (event) { if (event.key === ' ' || event.key === 'Enter') { event.preventDefault(); _this19.handleUserCloseLivePersonConversation(); } }); this.aiDisclaimerDiv.innerHTML = ''; this.aiDisclaimerDiv.append(lpDisclaimerTextSpan, ' ', lpDisclaimerButton); } else { // Set disclaimer back to the AI Disclaimer Text this.aiDisclaimerDiv.innerHTML = this.aiDisclaimerText; } } /** * Open the chat drawer. * @param {string} initialChatText Optional initial chat text to send to bot */; _proto.chatOpen = /*#__PURE__*/ function () { var _chatOpen = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee15(initialChatText) { var _this$updateAIChatDra3, _this20 = this; return _regeneratorRuntime().wrap(function _callee15$(_context15) { while (1) switch (_context15.prev = _context15.next) { case 0: if (initialChatText === void 0) { initialChatText = ''; } this.previouslyFocusedElem = document.activeElement; this.el.hidden = false; this.updateAIChatDrawerCookie((_this$updateAIChatDra3 = {}, _this$updateAIChatDra3[StorageKeys.chatDrawerState] = 'OPEN', _this$updateAIChatDra3)); // If source site has changed, send updated source site to bot, and update cookie if (!(this.sourceSite !== this.getAIChatDrawerCookieObject()[StorageKeys.sourceSite])) { _context15.next = 7; break; } _context15.next = 7; return this.updateSourceSite(this.sourceSite); case 7: requestAnimationFrame(function () { _this20.el.classList.add(ClassName$d.SHOW); if (_this20.mediaQueryListModalDialog.matches) { _this20.toggleModalDialogMode(true); } else { _this20.toggleModalDialogMode(false); } }); if (this.aiChatButton) { this.showChatButton(false); } if (initialChatText && this.webChatInstance) { this.store.dispatch({ type: 'WEB_CHAT/SEND_MESSAGE', payload: { text: initialChatText } }); } this.webChatTextarea.focus(); case 11: case "end": return _context15.stop(); } }, _callee15, this); })); function chatOpen(_x20) { return _chatOpen.apply(this, arguments); } return chatOpen; }() /** * Close the chat drawer, reenable web chat elements if they were disabled, and focus the search input in banner if it exists, * otherwise focus the previously focused element. */ ; _proto.chatClose = function chatClose() { var _this$updateAIChatDra4; this.el.classList.remove(ClassName$d.SHOW); this.toggleModalDialogMode(false); this.updateAIChatDrawerCookie((_this$updateAIChatDra4 = {}, _this$updateAIChatDra4[StorageKeys.chatDrawerState] = 'CLOSED', _this$updateAIChatDra4)); if (this.aiChatButton) { this.showChatButton(true); } clearTimeout(this.messageWaitTimeout); if (this.aiSearchFormComponent) { this.aiSearchFormComponent.searchInput.focus(); } else if (this.previouslyFocusedElem) { this.previouslyFocusedElem.focus(); } } /** * Opens the chat drawer if it is already initialized, otherwise initializes the chat drawer. * * @param {string} [initialChatText=''] - The initial text to be sent to the bot when opening or initializing the drawer. */; _proto.chatOpenOrInit = function chatOpenOrInit(initialChatText) { if (initialChatText === void 0) { initialChatText = ''; } if (this.chatInitialized) { this.chatOpen(initialChatText); } else { this.initChat(initialChatText); } } /** * Returns a Promise that resolves when the first message from the bot has rendered. If a message from the bot is already * rendered, the Promise resolves immediately. * * @returns {Promise} */; _proto.welcomeMessageRendered = function welcomeMessageRendered() { var _this21 = this; return new Promise(function (resolve, reject) { var transcript = _this21.el.querySelector(Selector$j.WEB_CHAT_TRANSCRIPT); if (!transcript) { reject(new Error('Transcript element not found. Cannot observe for welcome message.')); return; } // Check if a webchat bubble from the bot already exists var existingBotBubble = transcript.querySelector(Selector$j.WEB_CHAT_BUBBLE_FROM_BOT); if (existingBotBubble) { resolve(); return; } var observer = new MutationObserver(function (mutationsList, observer) { for (var _iterator2 = _createForOfIteratorHelperLoose(mutationsList), _step2; !(_step2 = _iterator2()).done;) { var mutation = _step2.value; for (var _iterator3 = _createForOfIteratorHelperLoose(mutation.addedNodes), _step3; !(_step3 = _iterator3()).done;) { var addedNode = _step3.value; if (addedNode.nodeType === Node.ELEMENT_NODE) { var botBubble = addedNode.querySelector(Selector$j.WEB_CHAT_BUBBLE_FROM_BOT); if (botBubble) { observer.disconnect(); resolve(); return; } } } } }); observer.observe(transcript, { childList: true, subtree: true }); }); } /** * Handle connect fulfilled event on the WebChat instance. Store a reference to the WebChat instance, and store references * to the send box, form, textarea, and send button elements. Append disclaimer text above send box. Open the chat drawer. */; _proto.onWebChatConnectFulfilled = function onWebChatConnectFulfilled() { this.webChatInstance = window.WebChat; this.chatInitialized = true; this.webChatSendBox = this.el.querySelector(Selector$j.WEB_CHAT_SEND_BOX); this.webChatForm = this.webChatSendBox.querySelector('form'); this.webChatTextarea = this.webChatForm.querySelector('textarea'); this.webChatTextarea.maxLength = this.webChatMaximumCharacters; this.webChatSendButton = this.webChatSendBox.querySelector(Selector$j.WEB_CHAT_SEND_BUTTON); this.firstFocusableElem = this.closeButton; this.lastFocusableElem = this.webChatSendButton; // Append disclaimer text above send box if (this.webChatSendBox && !this.aiDisclaimerDiv) { this.aiDisclaimerDiv = document.createElement('small'); this.aiDisclaimerDiv.classList.add(ClassName$d.AI_DISCLAIMER); this.aiDisclaimerDiv.innerHTML = this.aiDisclaimerText; this.webChatSendBox.insertAdjacentElement('beforebegin', this.aiDisclaimerDiv); } this.chatOpen(); } /** * Handle start conversation fulfilled event on the WebChat instance. If initial chat text was passed in, send it to the bot * after the welcome message has rendered. * * @param {CustomEvent} event 'startconversationfulfilled' event on the WebChat instance */; _proto.onStartConversationFulfilled = /*#__PURE__*/ function () { var _onStartConversationFulfilled = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee16(event) { var initialChatText, eventValue; return _regeneratorRuntime().wrap(function _callee16$(_context16) { while (1) switch (_context16.prev = _context16.next) { case 0: initialChatText = event.data; if (!(initialChatText && this.webChatInstance)) { _context16.next = 8; break; } _context16.next = 4; return this.welcomeMessageRendered(); case 4: this.store.dispatch({ type: 'WEB_CHAT/SEND_MESSAGE', payload: { text: initialChatText } }); _classPrivateFieldLooseBase(this, _initWebChatTranscriptObserver)[_initWebChatTranscriptObserver](); _context16.next = 9; break; case 8: _classPrivateFieldLooseBase(this, _initWebChatTranscriptObserver)[_initWebChatTranscriptObserver](); case 9: // Disable any previously sent transcript checkboxes and "Continue" buttons that start a new chat with LivePerson, // as they could be confusing to the user this.hideLivePersonChatIntroElems(); if (Object.keys(this.lpOpenConvs).length) { // There is possibly an active conversation with LivePerson // Don't send transcript again since user is reconnecting and not starting chat from "startLPChat" event this.isSendTranscript = false; // Attempt to reconnect to LivePerson this.initLivePersonChat(); } // If user opened chat drawer via proactive chat, send proactive chat event to bot if (this.isInstantiatedByProactiveChat) { eventValue = { instantiatedByProactiveChat: this.isInstantiatedByProactiveChat }; this.webChatSendEvent(EventName$k.INSTANTIATED_BY_PROACTIVE_CHAT, eventValue); } case 12: case "end": return _context16.stop(); } }, _callee16, this); })); function onStartConversationFulfilled(_x21) { return _onStartConversationFulfilled.apply(this, arguments); } return onStartConversationFulfilled; }() /** * Handle transition end event on the chat drawer. */ ; _proto.onAIChatDrawerTransitionEnd = function onAIChatDrawerTransitionEnd() { // When chat drawer has finished sliding off screen, add hidden attribute so elements inside cannot be focused/interacted with if (!this.el.classList.contains(ClassName$d.SHOW)) { this.el.hidden = true; } } /** * Detect when message from bot is appended to the WebChat transcript. If a message from the bot is appended, reenable the * WebChat elements if they were disabled, and focus the textarea in drawer if it had focus before the message was appended. * * @param {MutationRecord[]} mutationsList - List of mutations */; _proto.onWebChatTranscriptMutation = function onWebChatTranscriptMutation(mutationsList) { for (var _iterator4 = _createForOfIteratorHelperLoose(mutationsList), _step4; !(_step4 = _iterator4()).done;) { var mutation = _step4.value; for (var _iterator5 = _createForOfIteratorHelperLoose(mutation.addedNodes), _step5; !(_step5 = _iterator5()).done;) { var addedNode = _step5.value; if (addedNode.nodeType !== Node.ELEMENT_NODE) { continue; } var botBubble = addedNode.querySelector(Selector$j.WEB_CHAT_BUBBLE_FROM_BOT); // Not a message from bot, or bot is still generating a response if (!botBubble || botBubble.textContent.startsWith(this.botGeneratingResponseText)) { continue; } // Message from bot rendered, reenable web chat elements. // Don't handle this for live person messages. if (!this.isLivePersonChatActive) { this.toggleWebChatDisabled(false); } // Clear timeout clearTimeout(this.messageWaitTimeout); if (this.webChatTextAreaHadFocus) { this.webChatTextarea.focus(); } return; // Exit once bot bubble is found and handled } } } /** * Hide live person messages and transcript form that would trigger a new chat with LivePerson. */; _proto.hideLivePersonChatIntroElems = function hideLivePersonChatIntroElems() { // get all of the intro messages and forms var introElems = this.getLPIntroMessageElements(); introElems.forEach(function (elem) { // Find the parent 'article' element and hide it var articleElem = elem.closest(Selector$j.ARTICLE); if (articleElem) { articleElem.hidden = true; } }); } /** * Initialize chat. * @param {string} initialChatText Optional initial chat text to send to bot */; _proto.initChat = /*#__PURE__*/ function () { var _initChat = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee18(initialChatText) { var _this22 = this; var token; return _regeneratorRuntime().wrap(function _callee18$(_context18) { while (1) switch (_context18.prev = _context18.next) { case 0: if (initialChatText === void 0) { initialChatText = ''; } _context18.next = 3; return _classPrivateFieldLooseBase(this, _generateDirectLineToken)[_generateDirectLineToken](); case 3: token = _context18.sent; // Create Redux store for WebChat this.store = window.WebChat.createStore({}, function (_ref4) { var dispatch = _ref4.dispatch; return function (next) { return /*#__PURE__*/function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee17(action) { var cookieCreation, currentTime, result; return _regeneratorRuntime().wrap(function _callee17$(_context17) { while (1) switch (_context17.prev = _context17.next) { case 0: _context17.t0 = action.type; _context17.next = _context17.t0 === 'DIRECT_LINE/CONNECT' ? 3 : _context17.t0 === 'DIRECT_LINE/CONNECT_FULFILLED' ? 5 : _context17.t0 === 'DIRECT_LINE/POST_ACTIVITY' ? 8 : _context17.t0 === 'DIRECT_LINE/POST_ACTIVITY_FULFILLED' ? 11 : _context17.t0 === 'DIRECT_LINE/INCOMING_ACTIVITY' ? 13 : _context17.t0 === 'WEB_CHAT/SEND_MESSAGE' ? 15 : 23; break; case 3: _this22.handlePreConnect(); return _context17.abrupt("break", 24); case 5: _this22.handleConnectFulfilled(dispatch); _this22.sendLPFeatureFlagToBot(dispatch); return _context17.abrupt("break", 24); case 8: if (!(_this22.isLivePersonChatActive && action.payload.activity.name !== EventName$k.LIVEPERSON_SAVE_IDS)) { _context17.next = 10; break; } return _context17.abrupt("return"); case 10: return _context17.abrupt("break", 24); case 11: _this22.handlePostActivityFulfilled(action, initialChatText); return _context17.abrupt("break", 24); case 13: _this22.handleIncomingActivity(action, dispatch); return _context17.abrupt("break", 24); case 15: if (!_this22.isLivePersonChatActive) { _context17.next = 20; break; } // Change the composing state to pause before sending a message _this22.debouncedChatStateToPause.cancel({ upcomingOnly: true }); _this22.chatStateToPause(); // Send the message text to LivePerson _this22.handleLivePersonSendMessage(action.payload.text); // Return early to prevent dispatching the action to next middleware or store return _context17.abrupt("return"); case 20: // Refresh/Regenerate the token if (token) { cookieCreation = _this22.getAIChatDrawerCookieObject()[StorageKeys.tokenCreated]; currentTime = Date.now() / 1000; if (currentTime - cookieCreation < _this22.refreshAfter) { _classPrivateFieldLooseBase(_this22, _refreshDirectLineToken)[_refreshDirectLineToken](); } } else { _classPrivateFieldLooseBase(_this22, _regenerateAIChatDrawerToken)[_regenerateAIChatDrawerToken](); } _this22.handleWebChatSendMessage(action); return _context17.abrupt("break", 24); case 23: return _context17.abrupt("break", 24); case 24: // Dispatch the action to next middleware or store result = next(action); return _context17.abrupt("return", result); case 26: case "end": return _context17.stop(); } }, _callee17); })); return function (_x23) { return _ref5.apply(this, arguments); }; }(); }; }); this.directLine = window.WebChat.createDirectLine({ token: token, webSocket: true }); // Makes connection to Engine through direct line, with the defined actions and parameters this.renderWebChat(); case 7: case "end": return _context18.stop(); } }, _callee18, this); })); function initChat(_x22) { return _initChat.apply(this, arguments); } return initChat; }() /** * Sends an event to the Copilot Chatbot which will update its LivePerson feature flag * to the current state of the client. * @param {Function} dispatch - The dispatch function (Redux) */ ; _proto.sendLPFeatureFlagToBot = function sendLPFeatureFlagToBot(dispatch) { dispatch({ type: 'DIRECT_LINE/POST_ACTIVITY', meta: { method: 'keyboard' }, payload: { activity: { type: 'event', name: 'livePersonFeatureFlagEvent', value: { livePersonFeatureFlag: this.isLivePersonChatFeatureEnabled }, channelData: { postBack: true } } } }); } /** * Split the transcript into chunks that are within the LivePerson message character limit. * * @param {string} transcript The transcript to split * @returns {string[]} An array of transcript chunks */; _proto.splitTranscript = function splitTranscript(transcript) { var chunks = []; var startIndex = 0; var continuedText = this.transcriptContinuedText + "\n\n"; var continuedTextLength = continuedText.length; while (startIndex < transcript.length) { var endIndex = startIndex + this.livePersonMessageCharLimit; if (chunks.length > 0) { endIndex -= continuedTextLength; } if (endIndex > transcript.length) { endIndex = transcript.length; } else { // Ensure we don't split in the middle of a word var lastSpaceIndex = transcript.lastIndexOf(' ', endIndex); if (lastSpaceIndex > startIndex) { endIndex = lastSpaceIndex; } } var chunk = transcript.slice(startIndex, endIndex).trim(); if (chunks.length > 0) { chunk = continuedText + chunk; } chunks.push(chunk); startIndex = endIndex; } return chunks; } /** * Send the chat transcript to LivePerson. If the transcript exceeds the character limit, split it into multiple messages. * * @returns {void} */; _proto.sendTranscriptToLivePerson = function sendTranscriptToLivePerson() { var _this23 = this; var messageBubbleElems = Array.from(this.webChatTranscriptElem.querySelectorAll(Selector$j.WEB_CHAT_BUBBLE)); if (!messageBubbleElems.length) { console.error('No messages found in the WebChat transcript'); return; } var fullTranscript = this.transcriptIntroText + "\n\n"; messageBubbleElems.forEach(function (messageBubbleElem) { var fromText = messageBubbleElem.classList.contains(Selector$j.WEB_CHAT_BUBBLE_FROM_USER.replace('.', '')) ? _this23.transcriptFromUserText : _this23.transcriptFromAssistantText; var messageTextContent = messageBubbleElem.textContent.trim(); fullTranscript += fromText + " " + messageTextContent + "\n\n"; }); var fullTranscriptCharCount = fullTranscript.length; if (fullTranscriptCharCount > this.livePersonMessageCharLimit) { // Send multiple messages if the full transcript exceeds the character limit var messages = this.splitTranscript(fullTranscript, this.livePersonMessageCharLimit); messages.forEach( /*#__PURE__*/function () { var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee19(message) { return _regeneratorRuntime().wrap(function _callee19$(_context19) { while (1) switch (_context19.prev = _context19.next) { case 0: _context19.next = 2; return _this23.handleLivePersonSendMessage(message); case 2: _context19.next = 4; return new Promise(function (resolve) { return setTimeout(resolve, 500); }); case 4: case "end": return _context19.stop(); } }, _callee19); })); return function (_x24) { return _ref6.apply(this, arguments); }; }()); } else { // Send the full transcript as a single message this.handleLivePersonSendMessage(fullTranscript); } } /** * Handle feedback event activity sent from the Copilot. * Update accessibility properties for the feedback buttons. * Add event listeners to feedback buttons. * @param {Object} action - The action object (Redux) * @param {Function} dispatch - The dispatch function (Redux) */; _proto.handleFeedbackRequestFromBot = function handleFeedbackRequestFromBot(action, dispatch) { var _this24 = this; var messageId = action.payload.activity.value; var positiveActionSet = document.getElementById(messageId + "-positive"); var negativeActionSet = document.getElementById(messageId + "-negative"); if (positiveActionSet) { var positiveButton = positiveActionSet.querySelector('button'); positiveButton.classList.add(ClassName$d.FEEDBACK_BUTTON); positiveButton.setAttribute('aria-label', this.botFeedbackPositiveAriaLabel); positiveButton.querySelector('div').setAttribute('aria-hidden', 'true'); positiveButton.addEventListener(EventName$k.CLICK, function () { _this24.handleFeedbackButtonClick(dispatch, messageId, 'positive', positiveButton); }); var positiveButtonImg = positiveButton.querySelector('img'); if (positiveButtonImg) { positiveButtonImg.setAttribute('alt', ''); } } if (negativeActionSet) { var negativeButton = negativeActionSet.querySelector('button'); negativeButton.classList.add(ClassName$d.FEEDBACK_BUTTON); negativeButton.setAttribute('aria-label', this.botFeedbackNegativeAriaLabel); negativeButton.querySelector('div').setAttribute('aria-hidden', 'true'); negativeButton.addEventListener(EventName$k.CLICK, function () { _this24.handleFeedbackButtonClick(dispatch, messageId, 'negative', negativeButton); }); var negativeButtonImg = negativeButton.querySelector('img'); if (negativeButtonImg) { negativeButtonImg.setAttribute('alt', ''); } } } /** * Handle incoming adaptive card from the bot. * Add a class to the follow-up bubble content to remove the background. * Disable the deflection flow buttons after click. * * @param {Object} adaptiveCardData - The adaptive card data */; _proto.handleIncomingAdaptiveCard = function handleIncomingAdaptiveCard(adaptiveCardData) { var _adaptiveCardData$id, _adaptiveCardData$bod; if ((_adaptiveCardData$id = adaptiveCardData.id) != null && _adaptiveCardData$id.startsWith('follow-up')) { var adaptiveCardId = adaptiveCardData.id; // Use setTimeout to ensure the adaptive card is rendered before adding the class window.setTimeout(function () { var followUpAdaptiveCardElem = document.getElementById(adaptiveCardId); if (followUpAdaptiveCardElem) { // Add class to remove background from follow-up bubble content var webChatBubbleContent = followUpAdaptiveCardElem.closest(Selector$j.WEB_CHAT_BUBBLE_CONTENT); webChatBubbleContent.classList.add(ClassName$d.WEBCHAT_BUBBLE_CONTENT_FOLLOW_UP); } }); } else if ((_adaptiveCardData$bod = adaptiveCardData.body) != null && _adaptiveCardData$bod.length) { var _loop = function _loop() { var _bodyItem$id; var bodyItem = _step6.value; if ((_bodyItem$id = bodyItem.id) != null && _bodyItem$id.startsWith('deflection-')) { var deflectionFlowId = bodyItem.id; // Wait until deflection flow card is rendered using setTimeout window.setTimeout(function () { var _document$getElementB; var deflectionFlowCardElem = (_document$getElementB = document.getElementById(deflectionFlowId)) == null ? void 0 : _document$getElementB.closest(Selector$j.ARTICLE); if (deflectionFlowCardElem) { var deflectionFlowButtons = deflectionFlowCardElem.querySelectorAll('button'); for (var _iterator7 = _createForOfIteratorHelperLoose(deflectionFlowButtons), _step7; !(_step7 = _iterator7()).done;) { var button = _step7.value; // Disable all buttons after any one of them is clicked button.addEventListener(EventName$k.CLICK, function () { for (var _iterator8 = _createForOfIteratorHelperLoose(deflectionFlowButtons), _step8; !(_step8 = _iterator8()).done;) { var btn = _step8.value; btn.disabled = true; } }); } } }); return "break"; // break out of loop after finding deflection flow item } }; for (var _iterator6 = _createForOfIteratorHelperLoose(adaptiveCardData.body), _step6; !(_step6 = _iterator6()).done;) { var _ret = _loop(); if (_ret === "break") break; } } } /** * Handle incoming activity from the WebChat store. * * @param {Object} action - The action object (Redux) * @param {Function} dispatch - The dispatch function (Redux) */; _proto.handleIncomingActivity = function handleIncomingActivity(action, dispatch) { var _activity$from, _activity$attachments, _activity$attachments2, _activity$from2; var activity = action.payload.activity; if (activity.type === 'message' && ((_activity$from = activity.from) == null ? void 0 : _activity$from.role) === 'bot' && (_activity$attachments = activity.attachments) != null && _activity$attachments.length && ((_activity$attachments2 = activity.attachments[0].content) == null ? void 0 : _activity$attachments2.type) === 'AdaptiveCard') { var adaptiveCardData = activity.attachments[0].content; this.handleIncomingAdaptiveCard(adaptiveCardData); } if (activity.type === 'message' && ((_activity$from2 = activity.from) == null ? void 0 : _activity$from2.role) === 'bot' && !this.isLivePersonChatActive) { // emit an event that a message is received. Developers can listen to this event to perform additional actions, such as fire telemetry events. var event = new Event(EventName$k.WEBCHAT_MESSAGE_RECEIVED); window.dispatchEvent(event); } if (this.isLivePersonChatActive && activity.type === 'message') { this.handleLivePersonIncomingActivity(activity); } if (activity.type === 'event' && activity.name === EventName$k.FEEDBACK_SENT) { this.handleFeedbackRequestFromBot(action, dispatch); } if (activity.type === 'event' && activity.name === EventName$k.GENERATE_REIMAGINE_UMP) { this.handleReimagineUMPRequest(action, dispatch); } if (activity.type === 'event' && activity.name === EventName$k.LIVEPERSON_CHAT_START && !Object.keys(this.lpOpenConvs).length) { var _this$updateAIChatDra5; this.skillId = activity.value.skillId; this.accountId = activity.value.accountId; this.isSendTranscript = activity.value.sendTranscript; // If this "startLPChat" activity has already been seen (from bot chat history), don't start a new LivePerson chat if (this.startLPChatActivityIds.includes(activity.id)) { return; } this.startLPChatActivityIds.push(activity.id); this.updateAIChatDrawerCookie((_this$updateAIChatDra5 = {}, _this$updateAIChatDra5[StorageKeys.startLPChatActivityIds] = this.startLPChatActivityIds, _this$updateAIChatDra5)); this.initLivePersonChat(); } } /* * @returns {NodeList} - The list of elements that are part of the LivePerson chat intro messages and send transcript forms */; _proto.getLPIntroMessageElements = function getLPIntroMessageElements() { return this.el.querySelectorAll("[id^=\"form-\"], [id^=\"greeting-\"], [id^=\"post-\"]"); } /** * Handle sending a message to the bot from the WebChat. * * @param {Object} action - The action object (Redux) */; _proto.handleWebChatSendMessage = /*#__PURE__*/ function () { var _handleWebChatSendMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee20(action) { var _this25 = this; return _regeneratorRuntime().wrap(function _callee20$(_context20) { while (1) switch (_context20.prev = _context20.next) { case 0: if (document.activeElement === this.webChatTextarea) { this.webChatTextAreaHadFocus = true; } // Ensure channelData exists and add pageUrl action.payload = action.payload || {}; action.payload.channelData = Object.assign({}, action.payload.channelData, { pageUrl: window.location.href }); this.toggleWebChatDisabled(true); this.messageWaitTimeout = setTimeout(function () { _this25.toggleWebChatDisabled(false); }, this.messageWaitTimeoutDuration); // If source site has changed, send updated source site to bot, and update cookie if (!(this.sourceSite !== this.getAIChatDrawerCookieObject()[StorageKeys.sourceSite])) { _context20.next = 8; break; } _context20.next = 8; return this.updateSourceSite(this.sourceSite); case 8: case "end": return _context20.stop(); } }, _callee20, this); })); function handleWebChatSendMessage(_x25) { return _handleWebChatSendMessage.apply(this, arguments); } return handleWebChatSendMessage; }() /** * Update the chat state of the user in the LivePerson chat. * * @param {string} state The chat state * @returns {Promise} A promise that resolves when the chat state is updated */ ; _proto.chatStateTo = /*#__PURE__*/ function () { var _chatStateTo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee21(state) { var conversationId; return _regeneratorRuntime().wrap(function _callee21$(_context21) { while (1) switch (_context21.prev = _context21.next) { case 0: conversationId = Object.keys(this.lpOpenConvs)[0]; return _context21.abrupt("return", this.lpWebsocket.publishEvent({ dialogId: this.lpOpenConvs[conversationId].activeDialogId, conversationId: Object.keys(this.lpOpenConvs)[0], event: { type: 'ChatStateEvent', chatState: state } })); case 2: case "end": return _context21.stop(); } }, _callee21, this); })); function chatStateTo(_x26) { return _chatStateTo.apply(this, arguments); } return chatStateTo; }() /** * Set the user's chat state to COMPOSING for LivePerson */ ; _proto.chatStateToComposing = function chatStateToComposing() { try { this.chatStateTo(livePersonChatStateTypes.COMPOSING); } catch (error) { console.error('Error setting user chat state to COMPOSING:', error); } } /** * Set the user's chat state to PAUSE for LivePerson */; _proto.chatStateToPause = function chatStateToPause() { try { this.chatStateTo(livePersonChatStateTypes.PAUSE); } catch (error) { console.error('Error setting user chat state to PAUSE:', error); } } /** * Returns whether the AI Chat Drawer is visually suppressed or not. * The AI Chat Drawer is visually suppressed if the isHidden attribute is set to true. * This is used in scenarios where the AI Chat Drawer should be rendered in HTML, but should not be (or become) visible to the user. * @returns {boolean} - Whether the AI Chat Drawer is visually suppressed or not */; _proto.getIsHidden = function getIsHidden() { return this.el.getAttribute(Attributes$a.IS_HIDDEN) !== null; } /** * Debounce input event on WebChat textarea to set the user's chat state to COMPOSING and PAUSE for LivePerson. */; _proto.handleLpUserInput = function handleLpUserInput() { this.debouncedChatStateToComposing(); this.debouncedChatStateToPause(); } /** * Handle sending message to LivePerson. * * @param {string} messageText The text to send to LivePerson * @param {string} messageId The message ID (only used when retrying sending a message) * @param {number} retryCount The current retry count */; _proto.handleLivePersonSendMessage = function handleLivePersonSendMessage(messageText, messageId, retryCount) { var _this26 = this; if (messageId === void 0) { messageId = null; } if (retryCount === void 0) { retryCount = 0; } var isTranscriptMessage = messageText.startsWith(this.transcriptIntroText) || messageText.startsWith(this.transcriptContinuedText); messageText = new DOMParser().parseFromString(messageText, 'text/html').body.textContent; // Generate a messageId if one wasn't provided, and immediately render the message in the // WebChat UI with the generated messageId (if not a transcript message) if (!messageId && !isTranscriptMessage) { messageId = Math.floor(Math.random() * 1e9); // Render the message in the WebChat UI with the generated messageId var timestampString = new Date().toISOString(); var userId = _classPrivateFieldLooseBase(this, _getLivePersonIdFromJWT)[_getLivePersonIdFromJWT](); this.webChatSendMessage(messageText, timestampString, 'user', userId, messageId, null); // Preemptively set the dialog-id and sequence attributes on the message element // This will prevent duplicate messages when LivePerson sends back a ContentEvent setTimeout(function () { var renderedMessageElem = _this26.webChatTranscriptElem.querySelector("[data-lp-message-id=\"" + messageId + "\"]"); if (renderedMessageElem) { var _this26$lpOpenConvs$O; var activeDialogId = (_this26$lpOpenConvs$O = _this26.lpOpenConvs[Object.keys(_this26.lpOpenConvs)[0]]) == null ? void 0 : _this26$lpOpenConvs$O.activeDialogId; if (activeDialogId) { renderedMessageElem.dataset.lpMessageDialogId = activeDialogId; // We don't know the sequence yet, but we can use a placeholder that will prevent duplicates renderedMessageElem.dataset.lpMessageSequence = 'pending'; } } // Dispatch event that LivePerson message is rendered var event = new CustomEvent(EventName$k.LIVEPERSON_MESSAGE_RENDERED, { detail: { messageId: messageId } }); window.dispatchEvent(event); }, 0); } var timeoutPromise = function timeoutPromise(ms) { return new Promise(function (_, reject) { return setTimeout(function () { return reject(new LPError(LPErrorTypes.SEND_MESSAGE_TIMEOUT, 'Send message to LivePerson timed out', { messageId: messageId })); }, ms); }); }; // Resolve the promise that completes first Promise.race([this.publishToLivePersonWebsocket(messageText, messageId), timeoutPromise(livePersonResponseTimeout)]).then(function (response) { var _response$body; _this26.handleLivePersonResponse(response); var messageId = response.reqId; var renderedMessageElem = _this26.webChatTranscriptElem.querySelector("[data-lp-message-id=\"" + messageId + "\"]"); if (renderedMessageElem && ((_response$body = response.body) == null ? void 0 : _response$body.sequence) >= 0) { // Add data-lp-message-dialog-id and data-lp-message-sequence attributes to the found message element renderedMessageElem.dataset.lpMessageDialogId = _this26.lpOpenConvs[Object.keys(_this26.lpOpenConvs)[0]].activeDialogId; renderedMessageElem.dataset.lpMessageSequence = response.body.sequence; // Update the message element to show the timestamp _this26.markMessageAsSent(renderedMessageElem); } })["catch"](function (error) { error.data.messageId = messageId; _this26.handleLivePersonError(error, function (messageId, newRetryCount) { return _this26.handleLivePersonSendMessage(messageText, messageId, newRetryCount); }, retryCount); }); } /** * Handle LivePerson incoming activity. * * @param {Object} activity - The activity for a LivePerson incoming message */; _proto.handleLivePersonIncomingActivity = function handleLivePersonIncomingActivity(activity) { var _this27 = this; var activityText = activity.text, activityId = activity.id, messageSequence = activity.sequence; if (!activityText) { console.error('No text found in LivePerson message activity'); return; } // Use MutationObserver to wait until message is rendered in the WebChat transcript var observer = new MutationObserver(function (mutationsList, observer) { for (var _iterator9 = _createForOfIteratorHelperLoose(mutationsList), _step9; !(_step9 = _iterator9()).done;) { var mutation = _step9.value; if (mutation.type === 'childList') { for (var _iterator10 = _createForOfIteratorHelperLoose(mutation.addedNodes), _step10; !(_step10 = _iterator10()).done;) { var node = _step10.value; if (node.nodeType === Node.ELEMENT_NODE) { var messageBubbleElem = node.querySelector(Selector$j.WEB_CHAT_BUBBLE); /* eslint-disable max-depth */ if (messageBubbleElem && Util.normalizeText(messageBubbleElem.textContent) === Util.normalizeText(activityText)) { var _activity$from3; switch ((_activity$from3 = activity.from) == null ? void 0 : _activity$from3.role) { case 'lp-system': { // Add class to system message bubble to style it differently messageBubbleElem.classList.add(ClassName$d.WEBCHAT_BUBBLE_LP_SYSTEM_MESSAGE); // Add screen-reader-only class to timestamp to hide it visually var timestampElem = node.querySelector(Selector$j.WEB_CHAT_STATUS); timestampElem == null ? void 0 : timestampElem.classList.add(ClassName$d.SCREEN_READER_ONLY); break; } case 'user': { // Activity is from user, either from user sending a message, or from websocket event var articleElem = messageBubbleElem.closest(Selector$j.ARTICLE); if (articleElem) { // Add data-lp-message-id attribute to the article element articleElem.dataset.lpMessageId = activityId; if (messageSequence !== null && messageSequence !== undefined && messageSequence >= 0) { // Activity is from LivePerson data and has a sequence // Add data-lp-message-dialog-id and data-lp-message-sequence attributes to the article element articleElem.dataset.lpMessageDialogId = _this27.lpOpenConvs[Object.keys(_this27.lpOpenConvs)[0]].activeDialogId; articleElem.dataset.lpMessageSequence = messageSequence; } else if (!articleElem.dataset.lpMessageSequence || articleElem.dataset.lpMessageSequence === 'pending') { // Message from user is still pending _this27.markMessageAsSending(articleElem); } } break; } case 'bot': { // Message is from LivePerson bot var _articleElem = messageBubbleElem.closest(Selector$j.ARTICLE); if (_articleElem) { // Add data-lp-message-dialog-id attribute to the article element _articleElem.dataset.lpMessageDialogId = _this27.lpOpenConvs[Object.keys(_this27.lpOpenConvs)[0]].activeDialogId; // Add data-lp-message-sequence attribute to the article element _articleElem.dataset.lpMessageSequence = messageSequence; } break; } // No default } // Stop observing once the element is found and modified observer.disconnect(); return; } /* eslint-enable max-depth */ } } } } }); // Start observing the target node for configured mutations var targetNode = document.querySelector(Selector$j.WEB_CHAT_TRANSCRIPT); var config = { childList: true, subtree: true }; observer.observe(targetNode, config); } /** * Handles the timeout for sending a message via LivePerson. * * This function is triggered when a message fails to send within a specified timeout period. * It attempts to find the message element in the web chat transcript using the provided messageId. * If the message element is found, it marks the message as failed to send. * * @param {string} messageId - The unique identifier of the message that failed to send. */; _proto.handleLivePersonSendMessageTimeout = function handleLivePersonSendMessageTimeout(messageId) { var messageElem = this.webChatTranscriptElem.querySelector("[data-lp-message-id=\"" + messageId + "\"]"); if (!messageElem) { console.error("Message element with messageId " + messageId + " not found"); return; } // Set the message sequence to -1 to indicate that the message failed to send messageElem.dataset.lpMessageSequence = -1; // Mark the message as failed to send this.markMessageAsSendFailed(messageElem); } /** * Creates a quick component and appends it to the associated Adaptive Card container's DOM * then initializes the UMP with the provided data from the event action. * @param {} action */; _proto.handleReimagineUMPRequest = function handleReimagineUMPRequest(action) { // The UMP script and package should be added to pages already. /* eslint-disable no-undef */ if (!ump) { console.error('UMP is not defined'); return; } var _action$payload$activ = action.payload.activity.value, dataVideo = _action$payload$activ.dataVideo, messageId = _action$payload$activ.messageId; var umpContainer = document.getElementById("" + messageId); if (!umpContainer) { console.error("UMP container with messageId " + messageId + " not found"); return; } umpContainer.innerHTML = _classPrivateFieldLooseBase(this, _UMP_HTML_TEMPLATE)[_UMP_HTML_TEMPLATE]; var umplayer = umpContainer.querySelector('universal-media-player'); ump(umplayer, dataVideo); /* eslint-enable no-undef */ } /* * Handle feedback button click. * Updates the icon to the filled svg icon. * Post a 'feedback' event activity to the bot. * @param {Function} dispatch - The dispatch function (Redux) * @param {string} messageId - The message ID * @param {string} interactionResult - The interaction result (positive/negative) */; _proto.handleFeedbackButtonClick = function handleFeedbackButtonClick(dispatch, messageId, interactionResult, thisButton) { // Updates icon in the button var iconSrc = thisButton.querySelector('img').src; if (iconSrc && interactionResult === 'positive') { thisButton.querySelector('img').setAttribute('src', FEEDBACK_ICON_SVGS.POSITIVE_FILLED); } else if (iconSrc && interactionResult === 'negative') { thisButton.querySelector('img').setAttribute('src', FEEDBACK_ICON_SVGS.NEGATIVE_FILLED); } // Send the event activity to the bot dispatch({ type: 'DIRECT_LINE/POST_ACTIVITY', meta: { method: 'keyboard' }, payload: { activity: { channelData: { postBack: true }, name: "feedback" + interactionResult + "Request", type: 'event', text: messageId, value: { sourceSite: this.sourceSite } } } }); } /** * Code to run while connecting to the bot. Dispatch a custom event to indicate that the WebChat * connection is being initiated. */; _proto.handlePreConnect = function handlePreConnect() { var event = new Event(EventName$k.WEBCHAT_CONNECT_INITIATED); window.dispatchEvent(event); } /** * Handle connect fulfilled event on the WebChat instance. Send a 'startConversation' event to the bot. * @param {Function} dispatch - The dispatch function (Redux) */; _proto.handleConnectFulfilled = function handleConnectFulfilled(dispatch) { dispatch({ meta: { method: 'keyboard' }, payload: { activity: { channelData: { postBack: true, pageUrl: window.location.href }, name: 'startConversation', type: 'event', value: { sourceSite: this.sourceSite, leadId: this.getLeadId() } } }, type: 'DIRECT_LINE/POST_ACTIVITY' }); var event = new Event(EventName$k.WEBCHAT_CONNECT_FULFILLED); window.dispatchEvent(event); } /** * Handle post activity fulfilled event on the WebChat instance. If the activity is a 'startConversation' event, dispatch * a custom event to send initial chat text to the bot. * @param {Object} action - The action object (Redux) * @param {string} initialChatText - Optional initial chat text to send to bot */; _proto.handlePostActivityFulfilled = function handlePostActivityFulfilled(action, initialChatText) { var _action$payload$activ2 = action.payload.activity, type = _action$payload$activ2.type, name = _action$payload$activ2.name; if (type === 'event' && name === 'startConversation') { var event = new Event(EventName$k.START_CONVERSATION_FULFILLED); event.data = initialChatText; window.dispatchEvent(event); } if (type === 'event' && name === 'sourceSiteEvent') { // Resolve the sourceSite update promise this.resolveSourceSiteUpdate(); } } /** * Set the isHidden attribute on the AI Chat Drawer. If true, the AI Chat Drawer will be visually suppressed and not shown to the user. * @param {boolean} isHidden - Whether the AI Chat Drawer should be visually suppressed or not */; _proto.setIsHidden = function setIsHidden(isHidden) { if (isHidden) { this.el.setAttribute(Attributes$a.IS_HIDDEN, ''); // Set attribute with no value this.showChatButton(false); } else { this.el.removeAttribute(Attributes$a.IS_HIDDEN); // AI Chat Drawer is unhidden, need to add events for chat action type links var eventsToAdd = this.addChatActionTypeLinkEvents(); if (eventsToAdd.length) { Util$1.addEvents(eventsToAdd); } } } /** * Marks a message as sending by appending a bulleted span to the status message. * * @param {HTMLElement} element - The HTML element representing the message to be marked as sending. */; _proto.markMessageAsSending = function markMessageAsSending(element) { this.appendBulletedSpanToStatusMessage(element, this.livePersonSendingMessageText); } /** * Marks a message as sent by removing the "* Sending" status message. * * @param {HTMLElement} element - The HTML element representing the message to be marked as sent. */; _proto.markMessageAsSent = function markMessageAsSent(element) { // Remove * Sending from the status message this.removeBulletedSpanFromStatusMessage(element); } /** * Marks a message as failed to send and provides a retry option. * * @param {HTMLElement} element - The message element to mark as failed. * @returns {void} */; _proto.markMessageAsSendFailed = function markMessageAsSendFailed(element) { var _this28 = this; if (!element) { console.error('No message element found'); return; } var statusMessage = element.querySelector(Selector$j.WEB_CHAT_STATUS); if (!statusMessage) { console.error('No status message found in message element'); return; } // Clear existing HTML from statusMessage statusMessage.innerHTML = ''; var sendFailedSpan = document.createElement('span'); sendFailedSpan.textContent = this.livePersonSendFailedText; statusMessage.append(sendFailedSpan); // Add retry button var retryButton = document.createElement('a'); retryButton.setAttribute('role', 'button'); retryButton.setAttribute('href', '#'); retryButton.textContent = this.retryButtonText; retryButton.dataset.biCompnm = 'AI Chat Drawer'; retryButton.dataset.biId = 'ai-chat-drawer'; retryButton.dataset.biCn = this.retryButtonText; retryButton.dataset.biEcn = 'Retry'; var handleRetryButtonClick = function handleRetryButtonClick(event) { event.preventDefault(); // Get the text content of the message bubble var messageText = element.querySelector(Selector$j.WEB_CHAT_BUBBLE_CONTENT).textContent; if (!messageText) { console.error('No message text found in message bubble'); return; } // Send a new message to LivePerson with the same text _this28.handleLivePersonSendMessage(messageText); }; retryButton.addEventListener(EventName$k.CLICK, handleRetryButtonClick); retryButton.addEventListener(EventName$k.KEYDOWN, function (event) { if (event.key === 'Enter' || event.key === ' ') { handleRetryButtonClick(event); } }); statusMessage.append(retryButton); } /** * Mark the message as read in the WebChat transcript. * * @param {HTMLElement} element - The message element to mark as read */; _proto.markMessageAsRead = function markMessageAsRead(element) { this.appendBulletedSpanToStatusMessage(element, this.livePersonReadText); } /** * Appends a bulleted span with the specified text to the status message element within the given element. * * @param {HTMLElement} element - The parent element containing the status message element. * @param {string} textToAppend - The text to append as a bulleted span. */; _proto.appendBulletedSpanToStatusMessage = function appendBulletedSpanToStatusMessage(element, textToAppend) { var _statusMessage$textCo; if (!element) { return; } var statusMessage = element.querySelector(Selector$j.WEB_CHAT_STATUS); if (!statusMessage) { return; } var isAlreadyMarked = (_statusMessage$textCo = statusMessage.textContent) == null ? void 0 : _statusMessage$textCo.includes(textToAppend); if (!isAlreadyMarked) { var bulletedSpan = document.createElement('span'); bulletedSpan.innerHTML = "• " + textToAppend; statusMessage.append(bulletedSpan); } } /** * Removes any span elements that start with a bullet point (•) from the status message within the given element. * * @param {HTMLElement} element - The parent element containing the status message. */; _proto.removeBulletedSpanFromStatusMessage = function removeBulletedSpanFromStatusMessage(element) { if (!element) { return; } var statusMessage = element.querySelector(Selector$j.WEB_CHAT_STATUS); if (!statusMessage) { return; } var spans = statusMessage.querySelectorAll('span'); for (var _iterator11 = _createForOfIteratorHelperLoose(spans), _step11; !(_step11 = _iterator11()).done;) { var span = _step11.value; if (span.textContent.startsWith('•')) { span.remove(); } } } /** * Code to run when the UHF header intersects with the viewport. Add/remove scroll listener to align chat drawer with bottom * of UHF header, or top of viewport. * @param {IntersectionObserverEntry[]} entries - Array of intersection observer entries */; _proto.onUhfHeaderIntersect = function onUhfHeaderIntersect(entries) { var _this29 = this; entries.forEach(function (entry) { if (entry.isIntersecting) { // UHF header is visible. Add scroll listener to align chat drawer with bottom of UHF header _this29.uhfHeaderIsVisible = true; document.addEventListener(EventName$k.SCROLL, _this29.boundOnScrollWithUhfVisible, false); _this29.boundOnScrollWithUhfVisible(); } else { // UHF header is not visible. Remove scroll listener, align chat drawer to top of viewport. _this29.uhfHeaderIsVisible = false; document.removeEventListener(EventName$k.SCROLL, _this29.boundOnScrollWithUhfVisible, false); _this29.el.style.top = 0; _this29.el.style.height = '100%'; } }); } /** * Code to run when the sticky nav is stuck/unstuck. Align chat drawer with bottom of sticky nav when stuck, otherwise align * to top of viewport. * @param {MutationRecord[]} mutations - Array of mutation records */; _proto.onStickyNavMutation = function onStickyNavMutation(mutations) { var _this30 = this; mutations.forEach(function (mutation) { var classHasChanged = mutation.target.getAttribute('class') !== mutation.oldValue; // Ignore mutations that don't involve the sticky nav being stuck/unstuck if (!classHasChanged || mutation.target.classList.contains(ClassName$d.GET_HEIGHT) || mutation.oldValue.includes(ClassName$d.GET_HEIGHT)) { return; } var isStuck = mutation.target.classList.contains(ClassName$d.STUCK); if (isStuck) { // Sticky nav is stuck. Align chat drawer with bottom of sticky nav. var stickyNavBottom = _this30.stickyNavElem.getBoundingClientRect().bottom; _this30.el.style.top = stickyNavBottom + "px"; _this30.el.style.height = "calc(100% - " + stickyNavBottom + "px)"; } else if (_this30.uhfHeaderElem && _this30.uhfHeaderElem.getBoundingClientRect().bottom > 0) { // When the sticky nav transitions from desktop to mobile and is in unstuck, it aligns to the top of the viewport. // If the UHF header is still in view, align the chat drawer to the bottom of the UHF header. _this30.onScrollWithUhfVisible(); } else { // Sticky nav went from stuck to unstuck. Align chat drawer to top of viewport. _this30.el.style.top = 0; _this30.el.style.height = '100%'; } }); } /** * Code to run when the page is scrolled and the UHF header is visible. Align chat drawer with bottom of UHF header. */; _proto.onScrollWithUhfVisible = function onScrollWithUhfVisible() { var _this31 = this; if (!this.uhfHeaderElem) { return; } var ticking = false; if (!ticking) { window.requestAnimationFrame(function () { var uhfHeaderBottom = _this31.uhfHeaderElem.getBoundingClientRect().bottom + uhfHeaderMarginBottomVal; // At smaller viewports (<860px), the nav bar turns into a dropdown with position:absolute, and a margin-bottom is added to the header. // Align the chat drawer below the dropdown to avoid overlapping the nav menu when it takes full width at VP1 (360px). var marginBottom = parseFloat(window.getComputedStyle(_this31.uhfHeaderElem).marginBottom); var totalUhfBottom = uhfHeaderBottom + marginBottom; _this31.el.style.top = totalUhfBottom + "px"; _this31.el.style.height = "calc(100% - " + totalUhfBottom + "px)"; ticking = false; }); ticking = true; } } /** * Code to run when the browser is resized, to adjust the chat drawer's position and related UI elements. * - If the UHF header is visible, aligns the chat drawer with the bottom of the UHF header. * - Toggles the UHF footer padding based on the chat button/drawer visibility. */; _proto.onBrowserResize = function onBrowserResize() { if (this.uhfHeaderIsVisible) { // If the UHF header is visible, align chat drawer with bottom of UHF header this.onScrollWithUhfVisible(); } // Toggle the UHF footer bottom padding based on whether the chat is hidden or not this.toggleUHFBottomPadding(this.mediaQueryListChatHidden.matches); } /** * Code to run when the media query list for chat hidden changes. Toggle the UHF footer padding based on whether the chat is * hidden or not. * * @param {MediaQueryListEvent} event - The media query list event */; _proto.onMediaQueryListChatHiddenChange = function onMediaQueryListChatHiddenChange(event) { this.toggleUHFBottomPadding(event.matches); } /** * Handles changes to the media query list for modal dialog mode. * Toggles modal dialog mode based on whether the media query matches. * * @param {MediaQueryListEvent} event - The event object representing the change in the media query list. */; _proto.onMediaQueryListModalDialogChange = function onMediaQueryListModalDialogChange(event) { if (event.matches) { // If the media query matches, enter modal dialog mode this.toggleModalDialogMode(true); } else { // If the media query does not match, exit modal dialog mode this.toggleModalDialogMode(false); } } /** * Toggles the modal dialog mode for the AI Chat Drawer. * * If the drawer is open, this method will: * - Add or remove the 'overflow-hidden' class on the body element based on the modal dialog mode. * - Set the 'aria-modal' attribute on the drawer element to indicate modal or non-modal state. * - Set or unset the 'inert' attribute on the drawer's sibling elements for accessibility. * * @param {boolean} isModalDialogMode - Whether to enable (true) or disable (false) modal dialog mode. */; _proto.toggleModalDialogMode = function toggleModalDialogMode(isModalDialogMode) { var isDrawerOpen = this.el.classList.contains(ClassName$d.SHOW); if (!isDrawerOpen) { // If the drawer is not open, set back to non-modal dialog mode isModalDialogMode = false; } // Toggle overflow-hidden class on the body element document.body.classList.toggle(ClassName$d.OVERFLOW_HIDDEN, isModalDialogMode); // Toggle aria-modal to indicate that the AI Chat Drawer is a modal dialog or non-modal dialog this.el.setAttribute('aria-modal', isModalDialogMode ? 'true' : 'false'); // Toggle AI Chat Drawer element siblings as inert Util.toggleSiblingsInert(this.el, isModalDialogMode); } /** * Toggles the visibility of the AI Chat Button component. * If the Drawer is visibly suppressed, the chat button is not allowed to become visible by this method. * @param {show} A boolean indicating whether to show or hide the chat button */; _proto.showChatButton = function showChatButton(show) { if (this.getIsHidden()) { return; // Do not allow the chat button to be changed to a visible state if the AI Chat Drawer is visually suppressed } this.aiChatButton.classList.toggle(ClassName$d.DISPLAY_NONE, !show); // Do allow hiding it though, roflcopter this.aiChatButton.hidden = !show; } /** * Toggle the UHF footer padding based on whether the chat is hidden or not. * @param {boolean} isHidden - Whether the chat is hidden or not */; _proto.toggleUHFBottomPadding = function toggleUHFBottomPadding(isHidden) { if (!this.uhfFooterElem) { return; } this.uhfFooterElem.style.paddingBottom = isHidden ? this.uhfFooterOriginalPadding : this.aiChatButton.offsetHeight + "px"; } /* * Toggles the user text input and submit buttons for the WebChat * @param {boolean} isDisabled - Whether to disable or enable the user text input and submit button */; _proto.toggleWebChatUserTextBoxDisabled = function toggleWebChatUserTextBoxDisabled(isDisabled) { if (!this.webChatInstance) { return; } this.webChatForm.ariaDisabled = isDisabled; this.webChatTextarea.ariaDisabled = isDisabled; this.webChatTextarea.readOnly = isDisabled; this.webChatSendButton.ariaDisabled = isDisabled; } /** * Disable/Enable web chat elements. * @param {boolean} isDisabled - Whether to disable or enable web chat elements */; _proto.toggleWebChatDisabled = function toggleWebChatDisabled(isDisabled) { // Toggle disabling AI Search Form if (this.aiSearchFormComponent) { this.aiSearchFormComponent.toggleDisabled(isDisabled); } this.toggleWebChatUserTextBoxDisabled(isDisabled); // Toggle disabling all buttons in chat history var actionSetButtons = this.webChatContainer.querySelectorAll(Selector$j.WEB_CHAT_ACTION_SET_BUTTONS); for (var _iterator12 = _createForOfIteratorHelperLoose(actionSetButtons), _step12; !(_step12 = _iterator12()).done;) { var _button$closest, _button$closest2; var button = _step12.value; var isStartLivePersonChatButton = ((_button$closest = button.closest(Selector$j.ARTICLE)) == null ? void 0 : _button$closest.querySelector(Selector$j.SEND_TRANSCRIPT_CHECKBOX_CONTAINER)) !== null; var isDeflectionFlowButton = ((_button$closest2 = button.closest(Selector$j.ARTICLE)) == null ? void 0 : _button$closest2.querySelector(Selector$j.DEFLECTION_FLOW_ELEMENT)) !== null; // Skip disabling/enabling "Continue" buttons that start a new chat with LivePerson or deflection flow buttons if (isStartLivePersonChatButton || isDeflectionFlowButton) { continue; } button.ariaDisabled = isDisabled; button.classList.toggle(ClassName$d.DISABLED, isDisabled); button.tabIndex = isDisabled ? -1 : 0; } // Update last focusable element in the chat drawer if (isDisabled) { var allFocusableDrawerElems = this.el.querySelectorAll(Selector$j.FOCUSABLE_ELEMENTS); this.lastFocusableElem = allFocusableDrawerElems[allFocusableDrawerElems.length - 1]; } else { this.lastFocusableElem = this.webChatSendButton; } } /** * Update the source site value. Dispatch a new activity to the bot with the updated source site value, and update cookies * with the new source site. Wait for the source site update promise to resolve, then reset the source site update promise. * @param {string} newSourceSite - The new source site value */; _proto.updateSourceSite = /*#__PURE__*/ function () { var _updateSourceSite = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee22(newSourceSite) { var _this$updateAIChatDra6; return _regeneratorRuntime().wrap(function _callee22$(_context22) { while (1) switch (_context22.prev = _context22.next) { case 0: // Dispatch a new activity to the bot with the updated sourceSite value this.store.dispatch({ type: 'DIRECT_LINE/POST_ACTIVITY', meta: { method: 'keyboard' }, payload: { activity: { type: 'event', name: 'sourceSiteEvent', value: { sourceSite: newSourceSite }, channelData: { postBack: true } } } }); // Update cookie with the new source site this.updateAIChatDrawerCookie((_this$updateAIChatDra6 = {}, _this$updateAIChatDra6[StorageKeys.sourceSite] = newSourceSite, _this$updateAIChatDra6)); // Wait for the sourceSite update promise to resolve _context22.next = 4; return this.sourceSiteUpdatePromise; case 4: // Reset the sourceSite update promise _classPrivateFieldLooseBase(this, _resetSourceSiteUpdatePromise)[_resetSourceSiteUpdatePromise](); case 5: case "end": return _context22.stop(); } }, _callee22, this); })); function updateSourceSite(_x27) { return _updateSourceSite.apply(this, arguments); } return updateSourceSite; }() /** * Get the AI Chat Drawer cookie object. * @returns {Object | null} The AI Chat Drawer cookie object, or null if it cannot be parsed. */ ; _proto.getAIChatDrawerCookieObject = function getAIChatDrawerCookieObject() { var cookieObj = null; var cookieString = getCookie(StorageKeys.cookieName); if (!cookieString) { return null; } try { cookieObj = JSON.parse(cookieString); } catch (error) { console.error('Failed to parse AI Chat Drawer cookie', error); } return cookieObj; } /** * Update the AI Chat Drawer cookie with the new cookie object. * @param {Object} newCookieObject The new cookie object to update the AI Chat Drawer cookie with. */; _proto.updateAIChatDrawerCookie = function updateAIChatDrawerCookie(newCookieObject) { var existingCookieObject = this.getAIChatDrawerCookieObject(); var updatedCookieObject = Object.assign({}, existingCookieObject, newCookieObject); setCookie(StorageKeys.cookieName, JSON.stringify(updatedCookieObject), CookieConstants.expiryDays, CookieConstants.domain); } /** * Delete the AI Chat Drawer cookie. */; _proto.deleteAIChatDrawerCookie = function deleteAIChatDrawerCookie() { // Set the Expiration to a negative value, so the browser auto-deletes the cookie. setCookie(StorageKeys.cookieName, '', -1, CookieConstants.domain); } /** * Remove event handlers. * @this AIChatDrawer */; _proto.remove = function remove() { var _this$uhfHeaderInters, _this$stickyNavMutati, _this$webChatTranscri, _this$webChatTextarea, _this$lpMutationObser2; // remove events, intersection observer, etc. Util$1.removeEvents(this.events); document.removeEventListener(EventName$k.SCROLL, this.boundOnScrollWithUhfVisible); (_this$uhfHeaderInters = this.uhfHeaderIntersectionObserver) == null ? void 0 : _this$uhfHeaderInters.disconnect(); (_this$stickyNavMutati = this.stickyNavMutationObserver) == null ? void 0 : _this$stickyNavMutati.disconnect(); (_this$webChatTranscri = this.webChatTranscriptMutationObserver) == null ? void 0 : _this$webChatTranscri.disconnect(); (_this$webChatTextarea = this.webChatTextarea) == null ? void 0 : _this$webChatTextarea.removeEventListener(EventName$k.INPUT, this.handleLpUserInput); (_this$lpMutationObser2 = this.lpMutationObserver) == null ? void 0 : _this$lpMutationObser2.disconnect(); // remove this reference from array of instances var index = aiChatDrawers.indexOf(this); aiChatDrawers.splice(index, 1); // Create and dispatch custom event this[EventName$k.ON_REMOVE] = new CustomEvent(EventName$k.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$k.ON_REMOVE]); } /** * Get instances. * @returns {Object} A object instance */; AIChatDrawer.getInstances = function getInstances() { return aiChatDrawers; }; return AIChatDrawer; }(); function _setDefaultValuesInMarkup2() { // Update drawer title text this.updateDrawerTitleText(this.drawerTitleText); // Set header controls aria label if (this.headerControls) { this.headerControls.setAttribute('aria-label', this.closeButtonAriaLabel); } // Update el's aria label this.el.setAttribute('aria-label', this.chatDrawerAriaLabel); // Update chat button's default values _classPrivateFieldLooseBase(this, _setDefaultValuesAiChatButton)[_setDefaultValuesAiChatButton](); } function _setDefaultValuesAiChatButton2() { // Return if there is no click group if (!this.aiChatButton) { return; } // Update the default theme-day if (!this.aiChatButton.classList.contains('theme-day') && !this.aiChatButton.classList.contains('theme-night')) { this.aiChatButton.classList.add('theme-day'); } // Update the floating button header text if (this.aiChatButtonHeader && !this.aiChatButtonHeader.textContent) { this.aiChatButtonHeader.textContent = this.buttonTitleText; } // Update the floating badge aria label if (this.aiChatButtonAnchor && !this.aiChatButtonAnchor.getAttribute('aria-label')) { this.aiChatButtonAnchor.setAttribute('aria-label', 'Expand AI-powered assistant chat dialog'); } } function _addEventHandlers2() { var _this32 = this; this.events = []; var elementsToBind = [this.closeButton, this.uhfNavMenuExpandElem]; // Hide the chat drawer when the close button and UHF nav menu expand button (at mobile viewport) are clicked elementsToBind.forEach(function (element) { if (element) { _this32.events.push({ el: element, handler: _this32.chatClose.bind(_this32), type: EventName$k.CLICK }); } }); if (this.aiSearchFormComponent) { this.events.push({ el: this.aiSearchFormComponent.el, handler: this.onAiSearchFormSubmit.bind(this), type: EventName$l.ON_AI_SEARCH_FORM_SUBMIT }); } if (this.aiChatButtonDataMount) { this.events.push({ el: this.aiChatButtonDataMount, handler: this.onAiChatButtonClick.bind(this), type: EventName$k.CLICK }); if (this.aiChatButtonDataMount.tagName !== 'BUTTON') { this.events.push({ el: this.aiChatButtonDataMount, handler: this.onAiChatButtonClick.bind(this), type: EventName$k.KEYDOWN }); } } if (!this.getIsHidden()) { this.addChatActionTypeLinkEvents(); } this.events.push({ el: this.el, handler: this.onAIChatDrawerTransitionEnd.bind(this), type: EventName$k.TRANSITION_END }, { el: this.el, handler: this.onKeyDown.bind(this), type: EventName$k.KEYDOWN }, { el: document, handler: this.onDocumentKeyDown.bind(this), type: EventName$k.KEYDOWN }, { el: window, handler: this.onWebChatConnectFulfilled.bind(this), type: EventName$k.WEBCHAT_CONNECT_FULFILLED }, { el: window, handler: this.onStartConversationFulfilled.bind(this), type: EventName$k.START_CONVERSATION_FULFILLED }, { el: window, handler: debounce(this.debouncedResizeDelay, this.onBrowserResize.bind(this)), type: EventName$k.RESIZE }, { el: this.mediaQueryListChatHidden, handler: this.onMediaQueryListChatHiddenChange.bind(this), type: EventName$k.CHANGE }, { el: this.mediaQueryListModalDialog, handler: this.onMediaQueryListModalDialogChange.bind(this), type: EventName$k.CHANGE }); this.boundOnScrollWithUhfVisible = this.onScrollWithUhfVisible.bind(this); Util$1.addEvents(this.events); } function _initUhfIntersectionObserver2() { if (!this.uhfHeaderElem) { return; } var options = { rootMargin: "0px 0px " + uhfHeaderMarginBottomVal + "px 0px" }; this.uhfHeaderIntersectionObserver = new IntersectionObserver(this.onUhfHeaderIntersect.bind(this), options); this.uhfHeaderIntersectionObserver.observe(this.uhfHeaderElem); } function _initStickyNavMutationObserver2() { if (!this.stickyNavElem) { return; } var stickyParentElem = this.stickyNavElem.closest(Selector$j.STICKY); this.stickyNavMutationObserver = new MutationObserver(this.onStickyNavMutation.bind(this)); this.stickyNavMutationObserver.observe(stickyParentElem, { attributeFilter: ['class'], attributeOldValue: true }); } function _initWebChatTranscriptObserver2() { this.webChatTranscriptElem = this.el.querySelector(Selector$j.WEB_CHAT_TRANSCRIPT); if (!this.webChatTranscriptElem) { console.error('Web Chat transcript element not found.'); return; } this.webChatTranscriptMutationObserver = new MutationObserver(this.onWebChatTranscriptMutation.bind(this)); this.webChatTranscriptMutationObserver.observe(this.webChatTranscriptElem, { subtree: true, childList: true }); } function _positionAiChatButton2() { if (!this.aiChatButton) { return; } var uhfFooter = document.querySelector(Selector$j.UHF_FOOTER); if (uhfFooter) { // insert before the UHF footer uhfFooter.insertAdjacentElement('beforebegin', this.aiChatButton); this.showChatButton(true); } else { // insert before the closing body tag document.body.insertAdjacentElement('beforeend', this.aiChatButton); this.showChatButton(true); } } function _positionAiChatDrawer2() { var uhfFooter = document.querySelector(Selector$j.UHF_FOOTER); if (uhfFooter) { uhfFooter.insertAdjacentElement('beforebegin', this.el); } else { document.body.insertAdjacentElement('beforeend', this.el); } this.el.hidden = true; } function _getAISearchFormInstance2() { var aiSearchFormInstances = AISearchForm.getInstances(); if (!aiSearchFormInstances.length) { return null; } // There should only be one AI Search Form instance. Get the first one. return aiSearchFormInstances[0]; } function _resetSourceSiteUpdatePromise2() { var _this33 = this; this.sourceSiteUpdatePromise = new Promise(function (resolve) { _this33.resolveSourceSiteUpdate = resolve; }); } function _regenerateAIChatDrawerToken2() { return _regenerateAIChatDrawerToken3.apply(this, arguments); } function _regenerateAIChatDrawerToken3() { _regenerateAIChatDrawerToken3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee23() { return _regeneratorRuntime().wrap(function _callee23$(_context23) { while (1) switch (_context23.prev = _context23.next) { case 0: this.deleteAIChatDrawerCookie(); _classPrivateFieldLooseBase(this, _generateDirectLineToken)[_generateDirectLineToken](); case 2: case "end": return _context23.stop(); } }, _callee23, this); })); return _regenerateAIChatDrawerToken3.apply(this, arguments); } function _generateDirectLineToken2() { return _generateDirectLineToken3.apply(this, arguments); } function _generateDirectLineToken3() { _generateDirectLineToken3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee24() { var token, cookieObj, _cookieObject, requestOptions, res, _yield$res$json, directLineToken, expiration, cookieObject; return _regeneratorRuntime().wrap(function _callee24$(_context24) { while (1) switch (_context24.prev = _context24.next) { case 0: token = null; cookieObj = this.getAIChatDrawerCookieObject(); if (typeof cookieObj === 'object' && cookieObj !== null) { token = cookieObj[StorageKeys.token]; } _context24.prev = 3; if (this.hasValidToken()) { _context24.next = 18; break; } requestOptions = { method: 'GET', redirect: 'follow', headers: { 'ms-cv': window.mscv } }; _context24.next = 8; return fetch(this.tokenEndpoint, requestOptions); case 8: res = _context24.sent; _context24.next = 11; return res.json(); case 11: _yield$res$json = _context24.sent; directLineToken = _yield$res$json.token; expiration = _yield$res$json.expires_in; token = directLineToken; cookieObject = (_cookieObject = {}, _cookieObject[StorageKeys.token] = token, _cookieObject[StorageKeys.tokenCreated] = Date.now() / 1000, _cookieObject[StorageKeys.tuid] = this.tuid, _cookieObject[StorageKeys.lpOpenConvs] = {}, _cookieObject[StorageKeys.startLPChatActivityIds] = [], _cookieObject); this.updateAIChatDrawerCookie(cookieObject); _classPrivateFieldLooseBase(this, _setRefreshTimer)[_setRefreshTimer](expiration); case 18: return _context24.abrupt("return", token); case 21: _context24.prev = 21; _context24.t0 = _context24["catch"](3); console.error('Error generating Direct Line token:', _context24.t0); clearTimeout(this.messageWaitTimeout); this.toggleWebChatDisabled(false); // Display generic error notification if possible this.setNotification(NotificationLevel.ERROR, this.livePersonGenericErrorText); // TODO if drawer is not open, any way to notify user that the AI Chat Drawer won't work, refresh? case 27: case "end": return _context24.stop(); } }, _callee24, this, [[3, 21]]); })); return _generateDirectLineToken3.apply(this, arguments); } function _refreshDirectLineToken2() { return _refreshDirectLineToken3.apply(this, arguments); } function _refreshDirectLineToken3() { _refreshDirectLineToken3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee25() { var _cookieObject2, requestOptions, res, _yield$res$json2, directLineToken, expiration, cookieObject; return _regeneratorRuntime().wrap(function _callee25$(_context25) { while (1) switch (_context25.prev = _context25.next) { case 0: _context25.prev = 0; requestOptions = { method: 'POST', redirect: 'follow', headers: { authorization: "Bearer " + this.getAIChatDrawerCookieObject()[StorageKeys.token] } }; _context25.next = 4; return fetch(this.refreshTokenUrl, requestOptions); case 4: res = _context25.sent; _context25.next = 7; return res.json(); case 7: _yield$res$json2 = _context25.sent; directLineToken = _yield$res$json2.token; expiration = _yield$res$json2.expires_in; cookieObject = (_cookieObject2 = {}, _cookieObject2[StorageKeys.token] = directLineToken, _cookieObject2[StorageKeys.tokenCreated] = Date.now() / 1000, _cookieObject2[StorageKeys.tuid] = this.tuid, _cookieObject2); this.updateAIChatDrawerCookie(cookieObject); _classPrivateFieldLooseBase(this, _setRefreshTimer)[_setRefreshTimer](expiration); _context25.next = 20; break; case 15: _context25.prev = 15; _context25.t0 = _context25["catch"](0); console.error('Error refreshing Direct Line token:', _context25.t0); clearTimeout(this.messageWaitTimeout); this.toggleWebChatDisabled(false); case 20: case "end": return _context25.stop(); } }, _callee25, this, [[0, 15]]); })); return _refreshDirectLineToken3.apply(this, arguments); } function _setRefreshTimer2(expiration) { var _this34 = this; var computedExpiration = 0; if (expiration > this.refreshBefore) { computedExpiration = (expiration - this.refreshBefore) * 1000; } else { throw new Error('Error refreshing Direct Line Token.'); } // Set a timeout to refresh the token x mins before it expires setTimeout(function () { return _classPrivateFieldLooseBase(_this34, _refreshDirectLineToken)[_refreshDirectLineToken](); }, computedExpiration); } function _getLocale2() { // if document.documentElement.lang is in format 'll-CC', return it // if (document.documentElement.lang?.includes('-')) { // return document.documentElement.lang; // } // return navigator.languages && navigator.languages.length // ? navigator.languages[0] // : navigator.language; return 'en-US'; } function _initializeJsonPollock2() { return _initializeJsonPollock3.apply(this, arguments); } function _initializeJsonPollock3() { _initializeJsonPollock3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee26() { return _regeneratorRuntime().wrap(function _callee26$(_context26) { while (1) switch (_context26.prev = _context26.next) { case 0: _context26.prev = 0; _context26.next = 3; return Util.loadScript(jsonPollockScriptSrc, 'body'); case 3: if (window.JsonPollock) { _context26.next = 6; break; } console.error('JsonPollock not found.'); return _context26.abrupt("return"); case 6: window.JsonPollock.init({ maxAllowedElements: 200, onAfterElementRendered: this.onAfterElementRenderedHandler }); _context26.next = 12; break; case 9: _context26.prev = 9; _context26.t0 = _context26["catch"](0); console.error('Error loading JsonPollock:', _context26.t0); case 12: case "end": return _context26.stop(); } }, _callee26, this, [[0, 9]]); })); return _initializeJsonPollock3.apply(this, arguments); } function _handlePageOpenState2() { try { var cookieObject = this.getAIChatDrawerCookieObject(); var lastState = cookieObject ? cookieObject[StorageKeys.chatDrawerState] : null; var isMobileViewport = window.matchMedia("(max-width: " + (ViewPort.MD - 0.2) + "px)").matches; // If at mobile viewport and the chat drawer is open, set lastState to 'CLOSED' to close the chat drawer on navigated page. if (isMobileViewport && lastState === 'OPEN') { var _this$updateAIChatDra7; this.updateAIChatDrawerCookie((_this$updateAIChatDra7 = {}, _this$updateAIChatDra7[StorageKeys.chatDrawerState] = 'CLOSED', _this$updateAIChatDra7)); lastState = 'CLOSED'; } var token = cookieObject ? cookieObject[StorageKeys.token] : null; // If the cookie exists and is still valid for the Direct Line, refresh it if (token) { var cookieCreation = this.getAIChatDrawerCookieObject()[StorageKeys.tokenCreated]; var currentTime = Date.now() / 1000; if (currentTime - cookieCreation < this.refreshAfter) { _classPrivateFieldLooseBase(this, _refreshDirectLineToken)[_refreshDirectLineToken](); } } if (this.isChatPersistEnabled && lastState === 'OPEN' && this.hasValidToken()) { this.chatOpenOrInit(); } } catch (error) { console.error('Failed to get chat drawer state from cookies', error); } } function _getSourceSite2() { try { var url = new URL(window.location.href); var domain = url.hostname; var path = url.pathname.split('/'); var langLoc = document.documentElement.lang.toLowerCase(); // find index of langLoc in path var langLocIndex = -1; // Map of language locales to possible source sites. // Special cases for Serbian language locales. var langLocs = { 'sr-rs': ['sr-rs', 'sr-latn-rs', 'sr-cyrl-rs'], "default": [langLoc] }; var possibleLangLocs = langLocs[langLoc] || langLocs["default"]; langLocIndex = possibleLangLocs.map(function (loc) { return path.indexOf(loc); }).find(function (index) { return index > -1; }); if (domain === 'azure.microsoft.com' || url.pathname.startsWith('/content/azure/acom')) { return 'azure'; } // Example: www.microsoft.com/fr-fr/isv/offer-benefits => isv if (langLocIndex > -1 && path.length > langLocIndex + 1) { var siteNameWithoutHtmlExtension = path[langLocIndex + 1].replace('.html', ''); return siteNameWithoutHtmlExtension; } } catch (error) { console.error('Failed to get source site:', error); } return 'azure'; // fallback } function _getLPEndpoint2(baseEndpoint, path) { // passing in path such as 'lp/check' var endpointURL = new URL(baseEndpoint); endpointURL.pathname = path; return endpointURL.href; } function _getLivePersonIdFromJWT2() { try { var payload = JSON.parse(atob(this.lpJWT.split('.')[1])); return payload.sub; } catch (error) { console.error('Error decoding JWT:', error); return null; } } var instances$e = []; var Selector$i = { DATA_MOUNT: '.alert-dismissible, [data-mount="alert-dismissible"]', DISMISS: '[data-dismiss="alert"]' }; var EventName$j = { CLOSE: 'onClose', CLOSED: 'onClosed', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; var ClassName$c = { FADE: 'fade', SHOW: 'show' }; function _removeElement$1(element) { var _this = this; element.classList.remove(ClassName$c.SHOW); if (!element.classList.contains(ClassName$c.FADE)) { _destroyElement$1.call(this, element); return; } var transitionDuration = Util$1.getTransitionDurationFromElement(element); element.addEventListener(Util$1.TRANSITION_END, function (event) { return _destroyElement$1.call(_this, element, event); }, { once: true }); Util$1.emulateTransitionEnd(element, transitionDuration); } function _destroyElement$1(element) { // Create and dispatch custom event this[EventName$j.CLOSED] = new CustomEvent(EventName$j.CLOSED); element.dispatchEvent(this[EventName$j.CLOSED]); element.remove(); } var Alert = /*#__PURE__*/function () { /** * Create an Alert instance * @param {Object} opts - the Alert options * @param {HTMLElement} opts.el - the Alert container element */ function Alert(opts) { var _this2 = this; this.el = opts.el; this.dismiss = this.el.querySelector(Selector$i.DISMISS); // Add event handlers if (this.dismiss) { this.events = [{ el: this.dismiss, type: 'click', handler: function handler() { _this2.close(); } }]; Util$1.addEvents(this.events); } instances$e.push(this); } /** * Perform a close action */ var _proto = Alert.prototype; _proto.close = function close() { var rootElement = this.el; // Create and dispatch custom event this[EventName$j.CLOSE] = new CustomEvent(EventName$j.CLOSE, { cancelable: true }); rootElement.dispatchEvent(this[EventName$j.CLOSE]); if (this[EventName$j.CLOSE].defaultPrevented) { return; } _removeElement$1.call(this, rootElement); } /** * Update instance. Added for API consistency */; _proto.update = function update() { // Create and dispatch custom event this[EventName$j.ON_UPDATE] = new CustomEvent(EventName$j.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$j.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { Util$1.removeEvents(this.events); var index = instances$e.indexOf(this); instances$e.splice(index, 1); // Create and dispatch custom event this[EventName$j.ON_REMOVE] = new CustomEvent(EventName$j.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$j.ON_REMOVE]); } /** * Get alert instances. * @returns {Object[]} An array of alert instances */; Alert.getInstances = function getInstances() { return instances$e; }; return Alert; }(); var instances$d = []; var Selector$h = { DATA_MOUNT: '.alert-dismissible, [data-mount="ocr-alert-dismissible"]', DISMISS: '[data-dismiss="alert"]' }; var EventName$i = { CLOSE: 'onClose', CLOSED: 'onClosed', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; var ClassName$b = { FADE: 'fade', SHOW: 'show' }; function _removeElement(element) { var _this = this; element.classList.remove(ClassName$b.SHOW); if (!element.classList.contains(ClassName$b.FADE)) { _destroyElement.call(this, element); return; } var transitionDuration = Util$1.getTransitionDurationFromElement(element); element.addEventListener(Util$1.TRANSITION_END, function (event) { return _destroyElement.call(_this, element, event); }, { once: true }); Util$1.emulateTransitionEnd(element, transitionDuration); } function _destroyElement(element) { // Create and dispatch custom event this[EventName$i.CLOSED] = new CustomEvent(EventName$i.CLOSED); element.dispatchEvent(this[EventName$i.CLOSED]); element.remove(); } var AlertExtension = /*#__PURE__*/function (_Alert) { _inheritsLoose(AlertExtension, _Alert); /** * Create an Alert instance * @param {Object} opts - the Alert options * @param {HTMLElement} opts.el - the Alert container element */ function AlertExtension(opts) { var _this2; _this2 = _Alert.call(this, opts) || this; _this2.el = opts.el; _this2.dismiss = _this2.el.querySelector(Selector$h.DISMISS); // remove old event listeners Util$1.removeEvents(_this2.events); // Add event handlers if (_this2.dismiss) { // remove events _this2.events = _this2.events.filter(function (event) { return event.el !== _this2.dismiss; }); var closeEvent = { el: _this2.dismiss, type: 'click', handler: function handler() { _this2.closeAlert(); } }; _this2.events.push(closeEvent); Util$1.addEvents(_this2.events); } instances$d.push(_assertThisInitialized(_this2)); return _this2; } /** * Perform a close action */ var _proto = AlertExtension.prototype; _proto.closeAlert = function closeAlert() { var rootElement = this.el; // Create and dispatch custom event this[EventName$i.CLOSE] = new CustomEvent(EventName$i.CLOSE, { cancelable: true }); rootElement.dispatchEvent(this[EventName$i.CLOSE]); if (this[EventName$i.CLOSE].defaultPrevented) { return; } // add text for a11y after close button var dismissText = document.querySelector('[data-dismiss-text]').getAttribute('data-dismiss-text'); this.el.nextElementSibling.innerHTML = dismissText; _removeElement.call(this, rootElement); this.remove(); } /** * Update instance. Added for API consistency */; _proto.update = function update() { // Create and dispatch custom event this[EventName$i.ON_UPDATE] = new CustomEvent(EventName$i.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$i.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { Util$1.removeEvents(this.events); var index = instances$d.indexOf(this); instances$d.splice(index, 1); // Create and dispatch custom event this[EventName$i.ON_REMOVE] = new CustomEvent(EventName$i.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$i.ON_REMOVE]); } /** * Get alert instances. * @returns {Object[]} An array of alert instances */; AlertExtension.getInstances = function getInstances() { return instances$d; }; return AlertExtension; }(Alert); var Selector$g = { DATA_MOUNT: '[data-mount="ocr-fixed-sticky"]', SHOW_STUCK: '.sticky-show-stuck', HIDE_STUCK: '.sticky-hide-stuck', TABLE: '.ocr-table__table' }; var ClassName$a = { STICKY: 'fixed-sticky', SENTINEL: 'sticky-sentinel', STUCK: 'stuck', GET_HEIGHT: 'get-height', STICKY_TOP: 'sticky-direction-top', STICKY_BOTTOM: 'sticky-direction-bottom' }; var Attribute$3 = { DATA_DIRECTION: 'data-direction', DATA_OBSERVER_BEHAVIOR: 'data-observer-behavior', DATA_SMOOTH_TRANSITION: 'data-smooth-transition', ARIA_HIDDEN: 'aria-hidden' }; var Direction$1 = { TOP: 'top', BOTTOM: 'bottom' }; var EventName$h = { ON_STUCK: 'onSticky', ON_UNSTUCK: 'onStatic', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove', FOCUS_IN: 'focusin', RESIZE: 'resize' }; var Default$1 = { DIRECTION: 'top' }; /** * @enum {string} */ var ObserverBehavior$1 = { ALWAYS: 'always', OFF: 'off', SIZE_AWARE: 'size-aware' }; var stickies$1 = []; /** * Private functions. */ /** * Check for the `data-smooth-transition` attribute. * Its presence makes this option `true` unless the value is specifically set to `false` * @param {HTMLElement} node - The element to check for the attribute `data-smooth-transition` * @returns {Boolean} return false if contentDivTarget is null */ function _hasSmoothTransition$1(node) { if (node.hasAttribute(Attribute$3.DATA_SMOOTH_TRANSITION) && node.dataset.smoothTransition !== 'false') { return true; } return false; } /** * Get the direction of the sticky. * @param {string} str - The string to parse. * @param {string} [defaultValue=top] - The default value to fallback to. * @returns {string} The direction of the sticky. */ function _getDirection$1(str, defaultValue) { if (defaultValue === void 0) { defaultValue = Default$1.DIRECTION; } switch (str) { case 'top': case 'bottom': { return str; } default: { return defaultValue; } } } /** * Handle intersection observer * @this FixedSticky */ function _onStickyChange$1() { this.el.classList.toggle(ClassName$a.STUCK, this.isStuck); _updateContentDivSpacing$1.bind(this)(); _updateScrollPadding$1.bind(this)(); } /** * Update margin spacing on the element before/after the sticky bar so that overlapping * does not occur when the page bar is fixed. Remove property if it is not stuck * @this FixedSticky */ function _updateContentDivSpacing$1() { if (this.contentDivTarget === null) { return; } var adjustNextElementSpacing = this.stickyElementHeight + this.contentDivTargetSpacing; if (this.rootMarginOffset !== 0) { adjustNextElementSpacing -= this.rootMarginOffset; } if (this.isStuck) { this.contentDivTarget.style.setProperty(this.styleProp, adjustNextElementSpacing + 'px', 'important'); } else { this.contentDivTarget.style.setProperty(this.styleProp, ''); } } /** * Updates scroll padding so that elements scrolled into view don't stay behind * @this FixedSticky */ function _updateScrollPadding$1(removeScrollPadding) { var htmlElement = document.querySelector('html'); this.stickyElementHeight = this.el.getBoundingClientRect().height; if (removeScrollPadding) { htmlElement.style.scrollPaddingTop = '0'; htmlElement.style.scrollPaddingBottom = '0'; } if (this.direction === Direction$1.TOP) { if (this.isStuck) { htmlElement.style.scrollPaddingTop = this.stickyElementHeight + this.extraScrollPaddingPx + 'px'; } else { htmlElement.style.scrollPaddingTop = this.stickyElementHeight + this.rootMarginOffset + this.extraScrollPaddingPx + 'px'; } } else if (this.direction === Direction$1.BOTTOM) { if (this.isStuck) { htmlElement.style.scrollPaddingBottom = this.stickyElementHeight + this.extraScrollPaddingPx + 'px'; } else { htmlElement.style.scrollPaddingBottom = this.stickyElementHeight + this.rootMarginOffset + this.extraScrollPaddingPx + 'px'; } } } /** * Triggers a boundary check when focus changes to handle edge cases where Intersection Observer does not fire * Uses focusin because focus does not bubble * @this FixedSticky */ function _onFocusin$1() { if (this.enableObserver) { this.isStuck = this.doesSentinelExceedBoundary(); this.el.classList.toggle(ClassName$a.STUCK, this.isStuck); _updateScrollPadding$1.bind(this)(); } } /** Calculate whether the height of the sticky has exceeded 33% of the viewport height based on height of the sticky's hidden elements and the height of the sticky's visible elements. @returns {boolean} Whether the height of the sticky has exceeded 33% of the viewport height. @this FixedSticky */ function _stickyExceedsAcceptedHeight$1() { // Subtracting two additional pixels based on a border that is toggled based on visibility. return (this.hiddenElementsHeight + this.visibleElementsHeight - 2) / window.innerHeight > 0.33; } /** Set the status of the sticky observer, dependent on configuration and/or height condition @this FixedSticky */ function _setObserver$1() { switch (this.observerBehavior) { case ObserverBehavior$1.OFF: { this.setObserverStatus(false); break; } case ObserverBehavior$1.ALWAYS: { this.setObserverStatus(true); break; } default: { if (_stickyExceedsAcceptedHeight$1.call(this)) { this.setObserverStatus(false); } else { this.setObserverStatus(true); } } } } /** * Validate observer behavior or fall back to default * @param {string} [option] - configuration for observerBehavior * @returns {ObserverBehavior} * @this FixedSticky */ function _getObserverBehavior$1(option) { // TODO: remove in v2 - deprecated as of v1.14.0 // handle previous `enableObserver: false` and override if (this.enableObserverInitial === false) { return ObserverBehavior$1.OFF; } var isValid = function isValid(behavior) { return Object.values(ObserverBehavior$1).includes(behavior); }; if (option && isValid(option)) { return option; } if (isValid(this.el.dataset.observerBehavior)) { return this.el.dataset.observerBehavior; } return ObserverBehavior$1.SIZE_AWARE; } /** * Generate child elements acting as sentinels based on the type of the parent element. * @this FixedSticky */ function _generateSentinelElement() { var tagName = this.fixedStickyInTable ? 'tr' : 'div'; var sentinel = document.createElement(tagName); var childelements = this.el.children; if (this.fixedStickyInTable) { Array.from(childelements).forEach(function (el) { var cellTagName = el.tagName === 'TH' ? 'th' : 'td'; var cloneCell = document.createElement(cellTagName); cloneCell.ariaHidden = true; cloneCell.style.display = 'none'; sentinel.append(cloneCell); }); } sentinel.classList.add(ClassName$a.SENTINEL); sentinel.setAttribute(Attribute$3.ARIA_HIDDEN, true); this.sentinel = sentinel; this.el.insertAdjacentElement('beforebegin', this.sentinel); } /** Calculate the combined height of all ".sticky-show-stuck" elements. @returns {number} Combined height of all ".sticky-show-stuck" elements. @this FixedSticky */ function _getShowStuckHeight$1() { var _this = this; var hiddenHeight = 0; // Calculate the height of hidden elements when not stuck var showStuck = this.el.querySelectorAll(Selector$g.SHOW_STUCK); if (showStuck && showStuck instanceof NodeList) { // Get the height of all hidden elements showStuck.forEach(function (el, index, list) { hiddenHeight += window.mwf.Util.getElementOuterHeight(el, { cssSelectors: ['margin', 'padding'] }); // If this is the last item in the node list, remove the CSS hack that displays hidden elements if (index === list.length - 1) { _this.el.classList.remove(ClassName$a.GET_HEIGHT); } }); } return hiddenHeight; } /** Calculate the height of hidden and visible elements. @returns {Object} Object containing height of hidden and visible elements. @this FixedSticky */ function _calculateHeights$1() { this.el.classList.add(ClassName$a.GET_HEIGHT); var hiddenHeight = this.fixedStickyInTable ? this.el.offsetHeight : _getShowStuckHeight$1.call(this); var visibleHeight = this.fixedStickyInTable ? 0 : this.el.offsetHeight; this.el.classList.remove(ClassName$a.GET_HEIGHT); return { hidden: hiddenHeight, visible: visibleHeight }; } /** * Set value of instances members and DOM node properties depending on the direction instance member * @this FixedSticky */ function _setDirectionalProps$1() { if (this.direction === Direction$1.BOTTOM) { this.el.style.top = null; // prevent interference this.el.style.bottom = '0'; this.contentDivTarget = this.el.previousElementSibling; this.contentDivTargetSpacing = this.contentDivTarget ? parseInt(getComputedStyle(this.contentDivTarget).paddingBottom, 10) + parseInt(getComputedStyle(this.contentDivTarget).marginBottom, 10) : 0; this.styleProp = 'margin-bottom'; this.el.classList.add(ClassName$a.STICKY_BOTTOM); this.el.classList.remove(ClassName$a.STICKY_TOP); } else { // Assume direction is Direction.TOP this.el.style.bottom = null; this.el.style.top = '0'; this.contentDivTarget = this.el.nextElementSibling; this.contentDivTargetSpacing = this.contentDivTarget ? parseInt(getComputedStyle(this.contentDivTarget).paddingTop, 10) + parseInt(getComputedStyle(this.contentDivTarget).marginTop, 10) : 0; this.styleProp = 'margin-top'; this.el.classList.add(ClassName$a.STICKY_TOP); this.el.classList.remove(ClassName$a.STICKY_BOTTOM); } } /** * Create a new observer instance member, disconnecting the old one if present. Instance member sentinel must already exist * @this FixedSticky */ function _createObserver$1() { var _this2 = this; if (this.observer) { this.observer.disconnect(); } // If smooth transition is enabled, the`rootMarginOffset` value should reflect the combined height // of all elements hidden prior to the sticky becoming stuck. Adding this value to the rootMargin option // of the intersection observer will allow for the sticky to activate sooner, resulting in a more // seamless transition var observerOptions = { rootMargin: "-" + this.rootMarginOffset + "px 0px 0px 0px" }; var onStickyChange = _onStickyChange$1.bind(this); this.observer = new IntersectionObserver(function (entries) { // fire onStickyChange if not in viewport if (_this2.enableObserver) { var prevState = _this2.isStuck; _this2.isStuck = _this2.doesSentinelExceedBoundary() && !entries[0].isIntersecting; // Check if sticky has changed state from unstuck to stuck and vice versa // in order to trigger custom events if (prevState !== undefined && prevState !== _this2.isStuck) { if (_this2.isStuck) { // Create and dispatch custom event _this2[EventName$h.ON_STUCK] = new CustomEvent(EventName$h.ON_STUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$h.ON_STUCK]); } else { // Create and dispatch custom event _this2[EventName$h.ON_UNSTUCK] = new CustomEvent(EventName$h.ON_UNSTUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$h.ON_UNSTUCK]); } } onStickyChange(); } }, observerOptions); if (this.sentinel) { this.observer.observe(this.sentinel); } } /** * Helper function to clear key properties of an instance * @this FixedSticky */ function _teardownInstance$1() { window.mwf.Util.removeEvents(this.events); // remove the attribute from the element this.el.classList.remove(ClassName$a.STICKY); _updateScrollPadding$1.call(this, [true]); // remove sticky-sentinel element this.sentinel.remove(); // disconnect observer this.observer.disconnect(); } /** * Class representing a Sticky Element. */ var OcrFixedSticky = /*#__PURE__*/function () { /** * Create the Sticky Element * @param {Object} opts - The Sticky Element options. * @param {HTMLElement} opts.el - The Sticky Element DOM node. * @param {string} opts.direction - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will attempt to read `data-direction` attribute, then defaults TOP * @param {boolean} opts.enableSmoothTransition - Whether to enable a smoother transition to hiding/showing elements as the sticky become stuck. If not defined, will attempt to read `data-smooth-transition` attribute, defaults to false * @param {boolean} opts.enableObserver - deprecated: enable the observer on initialization (defaults to true) * @param {ObserverBehavior} opts.observerBehavior - the behavior of the intersection observer to toggle stuck/unstuck states * @param {number} opts.extraScrollPaddingPx - Extra scroll padding to reduce crowding into sticky bars, defaults to 12px, same as minimal gutters */ function OcrFixedSticky(opts) { this.el = opts.el; this.direction = _getDirection$1(opts.direction || this.el.dataset.direction); this.enableSmoothTransition = typeof opts.enableSmoothTransition === 'boolean' ? opts.enableSmoothTransition : _hasSmoothTransition$1(this.el); this.extraScrollPaddingPx = typeof opts.extraScrollPaddingPx === 'number' ? opts.extraScrollPaddingPx : 12; this.enableObserver = opts.enableObserver !== false; // Saves the initial value of enable observer status from construction. Is used to flag whether the sticky should be automatically disabled when the height of the sticky exceeds 33% of the viewport // TODO: remove in v2 - deprecated as of v1.14.0 this.enableObserverInitial = this.enableObserver; this.observerBehavior = _getObserverBehavior$1.call(this, opts.observerBehavior); // Add "sticky" class only while initialized to attach style and functionality provided by CSS // Set prior to all height calculations so that styles are applied first this.el.classList.add(ClassName$a.STICKY); // HTML element with the property data-mount="sticky" // Create a property to hold the value for the sticky element height to be reused in both the _updateContentDivSpacing and _updateScrollPadding functions. this.stickyElementHeight = 0; // Set properties based on the anchor direction this.contentDivTarget = null; this.contentDivTargetSpacing = 0; this.styleProp = ''; _setDirectionalProps$1.call(this); // Add event handlers this.events = [{ el: document.body, type: EventName$h.FOCUS_IN, handler: _onFocusin$1.bind(this) }, { el: window, type: EventName$h.RESIZE, handler: throttle(200, _updateScrollPadding$1.bind(this)) }, { el: window, type: EventName$h.RESIZE, handler: debounce(300, _setObserver$1.bind(this)), options: { passive: true } }]; window.mwf.Util.addEvents(this.events); this.fixedStickyInTable = this.el.closest(Selector$g.TABLE) !== null; var _calculateHeights$cal = _calculateHeights$1.call(this), hiddenElementsHeight = _calculateHeights$cal.hidden, visibleElementsHeight = _calculateHeights$cal.visible; // Adjusts where the sentinel to the intersection observer triggers. Expected to be 0 if smooth transition is disabled. this.rootMarginOffset = this.enableSmoothTransition ? hiddenElementsHeight : 0; this.hiddenElementsHeight = hiddenElementsHeight; this.visibleElementsHeight = visibleElementsHeight; _generateSentinelElement.call(this); this.isStuck = false; this.observer = null; _createObserver$1.call(this); _setObserver$1.call(this); stickies$1.push(this); } /** * Check if the sentinel Exceeds the boundary * @returns {boolean} State of sentinel boundary */ var _proto = OcrFixedSticky.prototype; _proto.doesSentinelExceedBoundary = function doesSentinelExceedBoundary() { var sentinelRect = this.sentinel.getBoundingClientRect(); var sentinelTop = sentinelRect.top - this.rootMarginOffset; var sentinelBottom = sentinelRect.bottom; if (this.direction === Direction$1.TOP && sentinelTop < 0) { return true; } if (this.direction === Direction$1.BOTTOM && sentinelBottom > window.innerHeight) { return true; } return false; } /** * Set the status (enabled/disabled) of the intersection observer * @param {boolean} status The status to set */; _proto.setObserverStatus = function setObserverStatus(status) { if (this.doesSentinelExceedBoundary()) { _updateScrollPadding$1.call(this); if (status) { this.el.classList.add(ClassName$a.STUCK); } else { this.el.classList.remove(ClassName$a.STUCK); } } this.enableObserver = status; } /** * Updates key aspects the instance * @param {Object} opts - The Sticky options. * @param {string} [opts.direction] - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will maintain current setting * @param {boolean} [opts.enableSmoothTransition] - Whether to enable a smoother transition to hiding/showing elements as the sticky become stuck. If not defined, will maintain current setting * @param {number} [opts.extraScrollPaddingPx] - Extra scroll padding to reduce crowding into sticky bars. If not define, will maintain current setting * @param {ObserverBehavior} [opts.observerBehavior] - the behavior of the intersection observer to toggle stuck/unstuck states */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } var updateDirection = typeof opts.direction === 'string' ? _getDirection$1(opts.direction) : this.direction; var updateEnableSmoothTransition = typeof opts.enableSmoothTransition === 'boolean' ? opts.enableSmoothTransition : this.enableSmoothTransition; var updateExtraScrollPaddingPx = typeof opts.extraScrollPaddingPx === 'number' ? opts.extraScrollPaddingPx : this.extraScrollPaddingPx; var _calculateHeights$cal2 = _calculateHeights$1.call(this), updateHiddenElementsHeight = _calculateHeights$cal2.hidden, updateVisibleElementsHeight = _calculateHeights$cal2.visible; // update visibleElementsHeight for future calculations this.visibleElementsHeight = updateVisibleElementsHeight; // Set properties based on the anchor direction if changed if (this.direction !== updateDirection) { this.direction = updateDirection; _setDirectionalProps$1.call(this); // need to update scroll padding if direction changes this.extraScrollPaddingPx = updateExtraScrollPaddingPx; _updateScrollPadding$1.call(this, [true]); } // update scroll padding if extraScrollPaddingPx updated but direction not updated if (this.extraScrollPaddingPx !== updateExtraScrollPaddingPx) { this.extraScrollPaddingPx = updateExtraScrollPaddingPx; _updateScrollPadding$1.call(this, [true]); } // update observer if smooth transition has changed, or hiddenElementsHeight has changed if (this.enableSmoothTransition !== updateEnableSmoothTransition || this.hiddenElementsHeight !== updateHiddenElementsHeight) { this.enableSmoothTransition = updateEnableSmoothTransition; this.hiddenElementsHeight = updateHiddenElementsHeight; this.rootMarginOffset = this.enableSmoothTransition ? updateHiddenElementsHeight : 0; _createObserver$1.call(this); } if (opts.observerBehavior) { this.observerBehavior = _getObserverBehavior$1.call(this, opts.observerBehavior); } _setObserver$1.call(this); // Create and dispatch custom event this[EventName$h.ON_UPDATE] = new CustomEvent(EventName$h.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$h.ON_UPDATE]); return this; } /** * Remove the sticky. */; _proto.remove = function remove() { _teardownInstance$1.call(this); // remove this sticky reference from array of instances var index = stickies$1.indexOf(this); stickies$1.splice(index, 1); // Create and dispatch custom event this[EventName$h.ON_REMOVE] = new CustomEvent(EventName$h.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$h.ON_REMOVE]); } /** * Get an array of sticky instances. * @returns {Object[]} Array of sticky instances. */; OcrFixedSticky.getInstances = function getInstances() { return stickies$1; }; return OcrFixedSticky; }(); var $$1 = _export; var $findIndex = arrayIteration.findIndex; var addToUnscopables = addToUnscopables$4; var FIND_INDEX = 'findIndex'; var SKIPS_HOLES = true; // Shouldn't skip holes // eslint-disable-next-line es/no-array-prototype-findindex -- testing if (FIND_INDEX in []) Array(1)[FIND_INDEX](function () { SKIPS_HOLES = false; }); // `Array.prototype.findIndex` method // https://tc39.es/ecma262/#sec-array.prototype.findindex $$1({ target: 'Array', proto: true, forced: SKIPS_HOLES }, { findIndex: function findIndex(callbackfn /* , that = undefined */) { return $findIndex(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); } }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables addToUnscopables(FIND_INDEX); var instances$c = []; var DELAY_MS$4 = 100; /** * CSS class names. * @enum {string} */ var ClassName$9 = { TABLE: "ocr-table__table", WINDOW: "ocr-table__window", SUBHEADING: "ocr-table-row--subheading", COLUMN_SKU: "sku:not(:has(.sku))", CELL_CONTENT: "ocr-table-cell__content", TWO_COLUMN: "ocr-table--layout-cols-2", CONTROLS: "ocr-table__controls", STUCK: 'stuck', STUCK_SHOW_COLUMN_TITLE: 'ocr-table-row--stuck-show-column-title', STUCK_SHOW_HEAD_COLUMN_TITLE: 'ocr-table-row--stuck-show-head-column-title', PLACEHOLDER_ROW: 'ocr-table-row--placeholder', SHOW: 'show', STICKY_SKU_CLASSES: 'sku sku--style-sticky-header-row', TABLE_ROW_CSS_GRID_ALIGNMENT: 'ocr-table-row--sku-css-grid', STICKY_HEADING: "ocr-table-row--sticky-heading", COLLAPSE: 'collapse', BTN_COLLAPSE: 'btn-collapse' }; /** * CSS Selectors. * @enum {string} */ var Selector$f = { DATA_MOUNT: '[data-mount="ocr-table"]', TABLE: "." + ClassName$9.TABLE, SCROLL_WINDOW: "." + ClassName$9.WINDOW, COLUMN_SKU: "thead .ocr-table-cell__content ." + ClassName$9.COLUMN_SKU, TABLE_CELL_CONTENT: "td ." + ClassName$9.CELL_CONTENT, SUBHEADING: "." + ClassName$9.SUBHEADING, STICKY_HEADING: "." + ClassName$9.STICKY_HEADING, TWO_COLUMN: "." + ClassName$9.TWO_COLUMN, PREV_BUTTON: "." + ClassName$9.CONTROLS + " .carousel__arrow-prev", NEXT_BUTTON: "." + ClassName$9.CONTROLS + " .carousel__arrow-next", HEAD_ROW: "thead .ocr-table-row", HEAD_CELL: "thead th.ocr-table-cell", HEAD_CELL_CONTENT: "thead td .ocr-table-cell__content", HEAD_CELL_TEXT: "thead .ocr-table-row:first-of-type .ocr-table-cell__content h2", TABLE_ROW_HEAD_CELL_CONTENT: "th .ocr-table-cell__content", TABLE_ROW: "tbody tr", TABLE_BODY: "tbody", TABLE_THEAD: "thead", TABLE_CELL: "td", MODAL: '[data-mount="reimagine-modal"]', STICKY_MODAL_HEADER: '.modal-header.sticky', CSS_GRID_HEAD_ROW: "thead tr.ocr-table-row." + ClassName$9.TABLE_ROW_CSS_GRID_ALIGNMENT, TAB_PANEL: '.tab-panel', MULTI_COLLAPSE: '[data-mount="multi-collapse"]', H2: 'h2' }; /** * Elements to be cloned for sticky header. */ var STICKY_HEAD_CLONE_ELEMENTS = [{ selector: '.sku__title', containerClass: '' }, { selector: '.sku__pricing', containerClass: '' }, { selector: '.sku__detail-recurrence', containerClass: '' }, { selector: '.sku__note', containerClass: '' }, { selector: '.sku__unavailable', containerClass: '' }, { selector: '.button-group', containerClass: 'sku__buttons', createNewContainer: true }]; /** * HTML Attributes. * @enum {string} */ var Attributes$9 = { DISABLED: 'disabled', TABINDEX: 'tabindex', ID: 'id', ARIA_HIDDEN: 'aria-hidden', ARIA_EXPANDED: 'aria-expanded', DATA_TARGET: 'data-target', DATA_EXPAND: 'data-expand' }; /** * String constants. * @enum {string} */ var Strings$2 = { EMPTY: "" }; /** * JS event name. * @enum {string} */ var EventName$g = { CLICK_DATA_API: 'click', RESIZE_DATA_API: 'resize', SCROLL_DATA_API: 'scroll', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', ELEMENT_CLONED: 'elementCloned' }; /** * Get the current viewport size. * Returns true for VP3/4, false for VP1/2. * @returns {boolean} */ function _getIsLargeViewport() { var viewportWidth = window.innerWidth; return viewportWidth >= ViewPort.MD; } /** * This function adds the header column SKU to the sticky heading cell. * @param {HTMLTableElement} table * @param {HTMLTableRowElement} stickyHeading */ function _addColumnSKUInfoToStickyHeadingCell(table, stickyHeading) { var headerCells = table.querySelectorAll(Selector$f.COLUMN_SKU); var stickyHeadingCells = stickyHeading.querySelectorAll(Selector$f.TABLE_CELL_CONTENT); headerCells.forEach(function (headerCell, index) { var stickyCell = stickyHeadingCells[index]; if (!stickyCell) return; stickyCell.parentNode.removeAttribute(Attributes$9.ARIA_HIDDEN); var wrapperDiv = document.createElement('div'); wrapperDiv.className = ClassName$9.STICKY_SKU_CLASSES; STICKY_HEAD_CLONE_ELEMENTS.forEach(function (item) { var elementsToClone = headerCell.querySelectorAll(item.selector); elementsToClone.forEach(function (element) { var clone = element.cloneNode(true); if (item.createNewContainer) { var container = document.createElement('div'); container.className = item.containerClass; if (clone.getAttribute(Attributes$9.ID)) { clone.removeAttribute(Attributes$9.ID); } container.append(clone); wrapperDiv.append(container); } else { wrapperDiv.append(clone); } }); }); stickyCell.append(wrapperDiv); }); // post message to AEM to display the cloned elements and bind events window.postMessage(EventName$g.ELEMENT_CLONED); } /** * For the subheading, we need to hide the cells for accessibility. * @param {HTMLTableRowElement} subheading */ function _setAccessibilityAttributes(subheading) { var subheadingCells = subheading.querySelectorAll(Selector$f.TABLE_CELL); subheadingCells.forEach(function (cell) { cell.ariaHidden = true; }); } /** * This function returns an array of columns. * @param {HTMLTableElement} table * @returns {Array>} */ function _getTableColumns(table) { var columns = []; var headCells = []; var headCellsArr = table.querySelectorAll(Selector$f.HEAD_CELL); var headCellsContentArr = table.querySelectorAll(Selector$f.HEAD_CELL_CONTENT); if (headCellsArr.length === 0) { headCellsContentArr.forEach(function (cellContent, index) { // Since all table variant hides the first cell in table header, // we can skip the first cell in table header. if (index !== 0 && cellContent.parentNode) { headCells.push(cellContent.parentNode); } }); } else { headCells.push.apply(headCells, headCellsArr); } headCells.forEach(function (cell) { columns.push([cell]); }); var rows = table.querySelectorAll(Selector$f.TABLE_ROW); rows.forEach(function (row) { var cells = row.querySelectorAll(Selector$f.TABLE_CELL); cells.forEach(function (cell, index) { if (columns[index]) { columns[index].push(cell); } }); }); return columns; } /** * This function returns the column width and left from given columns. * @param {} column * @returns {{offsetLeft: number, offsetWidth: number}} */ function _getColumnRect(column) { // In somesitutation, the first three or four row cells have display:contents or display:none, // so we will find the cell that not using thoes style in order to get correct offset value. var cellIndex = 0; cellIndex = column.findIndex(function (cell) { return cell.style.display !== 'contents' && cell.style.display !== 'none'; }); var tableCell = column[cellIndex]; var offsetLeft = tableCell.offsetLeft, offsetWidth = tableCell.offsetWidth; return { offsetLeft: offsetLeft, offsetWidth: offsetWidth }; } /** * Table component */ var Table = /*#__PURE__*/function () { /** * Create a Table instance * @param {{el: HTMLDivElement}} opts - Options */ function Table(_ref) { var el = _ref.el; /** * Event bindings. * @type {{ el: Element, handler: (...args: unknown[]) => unknown, type: string}[]} */ this.events = []; /** * Observers. * @type {(ResizeObserver | IntersectionObserver | MutationObserver)[]} */ this.observers = []; this.el = el; this.isRTL = document.dir === 'rtl'; /** Only enable scroll in small viewport */ this.scrollable = !_getIsLargeViewport(); /** @type {HTMLDivElement} */ this.scrollWindow = this.el.querySelector(Selector$f.SCROLL_WINDOW); /** @type {HTMLTableElement} */ this.tableEl = this.el.querySelector(Selector$f.TABLE); var subheading = this.el.querySelector(Selector$f.SUBHEADING); if (subheading) { _setAccessibilityAttributes(subheading); } /** @type {HTMLTableRowElement | null} */ this.stickyHeading = this.el.querySelector(Selector$g.DATA_MOUNT); if (this.stickyHeading) { this._initStickyHeading(); } /** Only not 2 columns table enable scroll */ this.enableScroll = !this.el.classList.contains(ClassName$9.TWO_COLUMN); if (this.enableScroll) { this._initMobileScroll(); } /** When the table is be used in a tab pannel */ this._syncStickyHeadingWhenTableVisible(); /** Align SKU content in table head */ this._alignSkuContent(); // Set aria-expanded attribute to the collapse triggers and show the target elements this._updateCollapseTriggersAndShowTargets(); Util$1.addEvents(this.events); instances$c.push(this); } /** * Initialize the mobile scroll functionality. */ var _proto = Table.prototype; _proto._initMobileScroll = function _initMobileScroll() { /** @type {HTMLButtonElement} */ this.prevButton = this.el.querySelector(Selector$f.PREV_BUTTON); /** @type {HTMLButtonElement} */ this.nextButton = this.el.querySelector(Selector$f.NEXT_BUTTON); this.columns = _getTableColumns(this.el); this.isGridLayout = Boolean(this.el.querySelector(Selector$f.CSS_GRID_HEAD_ROW)); this.currentColumnIndex = 0; if (this.scrollable) { this._updateColumnIndex(0); this._adaptScrollingEndPadding(); } else { this._toggleScrollButtons(); } this.events.push({ el: this.prevButton, handler: this._handlePrevButtonClick.bind(this), type: EventName$g.CLICK_DATA_API }, { el: this.nextButton, handler: this._handleNextButtonClick.bind(this), type: EventName$g.CLICK_DATA_API }, { el: this.scrollWindow, handler: debounce(DELAY_MS$4, this._reCalculateColumnIndex.bind(this)), type: EventName$g.SCROLL_DATA_API }); var resizeObserver = new ResizeObserver(throttle(DELAY_MS$4, this._handleResize.bind(this))); resizeObserver.observe(this.scrollWindow); this.observers.push(resizeObserver); } /** * Adjusts the sticky heading cells style when the visibility of the table in tab pannel is toggled. */; _proto._syncStickyHeadingWhenTableVisible = function _syncStickyHeadingWhenTableVisible() { var _this = this; this.tabPanel = this.el.closest(Selector$f.TAB_PANEL); if (this.tabPanel) { var tableMutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === 'class' && _this.tabPanel.classList.contains(ClassName$9.SHOW)) { _this._adjustStuckStickyHeadingStyles(); } }); }); tableMutationObserver.observe(this.tabPanel, { attributes: true }); this.observers.push(tableMutationObserver); } } /** * Adaptation to scrolling leads to one side of the padding becoming ineffective. */; _proto._adaptScrollingEndPadding = function _adaptScrollingEndPadding() { var paddingInline = this._getPaddingInline(this.isRTL); var tableBody = this.el.querySelector(Selector$f.TABLE_BODY); var tableHead = this.el.querySelector(Selector$f.TABLE_THEAD); tableBody.style.paddingInlineEnd = paddingInline; if (tableHead) { tableHead.style.paddingInlineEnd = paddingInline; } } /** * Generate placeholder elements to address the issue with nested tag rules. */; _proto._generatePlaceholderElement = function _generatePlaceholderElement() { var placeholderRow = document.createElement('tr'); placeholderRow.setAttribute(Attributes$9.ARIA_HIDDEN, true); Array.from(this.stickyHeading.children).forEach(function (el) { var cellTagName = el.tagName === 'TH' ? 'th' : 'td'; var cloneCell = document.createElement(cellTagName); cloneCell.ariaHidden = true; cloneCell.style.display = 'none'; placeholderRow.append(cloneCell); }); return placeholderRow; } /** * Initialize the sticky heading functionality. */; _proto._initStickyHeading = function _initStickyHeading() { var _this$stickyHeading, _this2 = this, _this$modal; this.stickyInstance = this._getStickyInstance(); if (this.stickyHeading.classList.contains(ClassName$9.STUCK_SHOW_COLUMN_TITLE)) { _addColumnSKUInfoToStickyHeadingCell(this.el, this.stickyHeading); this.stickyInstance.update(); } if (this.stickyHeading.classList.contains(ClassName$9.STUCK_SHOW_HEAD_COLUMN_TITLE)) { _addColumnSKUInfoToStickyHeadingCell(this.el, this.stickyHeading); var tableHeadFirstCellText = this.el.querySelector(Selector$f.HEAD_CELL_TEXT); var stickyHeadingFirstCell = this.stickyHeading.querySelector(Selector$f.TABLE_ROW_HEAD_CELL_CONTENT); // clone table header first cell text to the first sticky heading cell if (tableHeadFirstCellText && stickyHeadingFirstCell) { stickyHeadingFirstCell.append(tableHeadFirstCellText.cloneNode(true)); stickyHeadingFirstCell.querySelector(Selector$f.H2).setAttribute(Attributes$9.ARIA_HIDDEN, true); } this.stickyInstance.update(); } this.isStickyHeaderGridLayout = Boolean((_this$stickyHeading = this.stickyHeading) == null ? void 0 : _this$stickyHeading.classList.contains(ClassName$9.TABLE_ROW_CSS_GRID_ALIGNMENT)); this.placeholderRow = this._generatePlaceholderElement(); this.placeholderRow.classList.add(ClassName$9.PLACEHOLDER_ROW); this.stickyHeading.parentElement.insertBefore(this.placeholderRow, this.stickyHeading); /** @type {HTMLDivElement | null} */ this.modal = this.el.closest(Selector$f.MODAL); if (this.modal) { // Although there are `shown` and `show` events for modal, // but the `show` is called too early, and the `shown` is called too late, // so we use mutation observer to detect the modal is shown or not. // If the modal is shown, adjust the sticky heading width to make it align with table. var modalMutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === 'class' && _this2.modal.classList.contains(ClassName$9.SHOW)) { _this2._adjustStuckStickyHeadingStyles(); } }); }); modalMutationObserver.observe(this.modal, { attributes: true, attributeFilter: ['class'] }); this.observers.push(modalMutationObserver); } /** @type {HTMLDivElement | null} */ this.stickyModalHeader = (_this$modal = this.modal) == null ? void 0 : _this$modal.querySelector(Selector$f.STICKY_MODAL_HEADER); if (this.stickyModalHeader) { // Use intersection observer to detect the sticky modal header is shown or not. // If the sticky modal header is shown, adjust the sticky heading sentinel position to make it stuck under the modal header. // Also, we need to set the sticky heading to unstuck state when the modal header is not shown. var modalHeaderIntersectionObserver = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { _this2._toggleFixedSticky(ObserverBehavior$1.SIZE_AWARE); _this2.stickyInstance.sentinel.style.position = 'relative'; _this2.stickyInstance.sentinel.style.top = "-" + _this2.stickyModalHeader.clientHeight + "px"; } else { _this2._toggleFixedSticky(ObserverBehavior$1.OFF); } }); }); modalHeaderIntersectionObserver.observe(this.stickyModalHeader); this.observers.push(modalHeaderIntersectionObserver); } /** * The IntersectionObserver is used to detect the sticky heading is in the scroll window or not. * The `fixed-sticky` will only set sticky header stuck when scroll from top to bottom, * The header will stuck based on the height of the heading and device even if we scroll down to out of the table. * Add this intersection observer to handle this case, * to trigger the stuck state manually. */ var intersectionObserver = new IntersectionObserver(function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { _this2._toggleFixedSticky(ObserverBehavior$1.SIZE_AWARE); } else { _this2._toggleFixedSticky(ObserverBehavior$1.OFF); } }); }); intersectionObserver.observe(this.scrollWindow); this.observers.push(intersectionObserver); /** * The MutationObserver is used to detect stuck state changes of the sticky heading. * The 'fixed-sticky' library provides 'ON_STUCK' and 'ON_UNSTUCK' events, * but these events will not trigger when scrolling from bottom to top, * which triggered by the intersection observer. * And the timing of the events and this observer is different, * so we need to listen both of them to avoid browser re-flow, * which will make sticky header flicker. */ var mutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === 'class') { var isStuck = _this2.stickyHeading.classList.contains(ClassName$9.STUCK); var firstStickyCellTitle = _this2.stickyHeading.querySelector(Selector$f.TABLE_ROW_HEAD_CELL_CONTENT + " " + Selector$f.H2); var collapseToggleButton = _this2.stickyHeading.querySelector(Selector$f.TABLE_ROW_HEAD_CELL_CONTENT + " ." + ClassName$9.BTN_COLLAPSE); _this2._togglePlaceHolderRowHeight(isStuck); _this2.stickyInstance.contentDivTarget.style.marginTop = Strings$2.EMPTY; if (_this2.stickyModalHeader) { _this2.stickyHeading.style.marginTop = isStuck ? _this2.stickyModalHeader.clientHeight + "px" : Strings$2.EMPTY; _this2.stickyHeading.style.paddingInlineEnd = isStuck ? _this2.modal.offsetWidth - _this2.modal.clientWidth + "px" : Strings$2.EMPTY; } _this2._syncStickyHeadingWidth(); if (isStuck) { _this2._syncStickyHeadingScrollPosition(); } // toggle aria-hidden attributes if (_this2.stickyHeading.classList.contains(ClassName$9.STUCK_SHOW_HEAD_COLUMN_TITLE)) { _this2._updateAriaHiddenAttributes(isStuck, firstStickyCellTitle, collapseToggleButton); } } }); }); mutationObserver.observe(this.stickyHeading, { attributes: true, attributeFilter: ['class'] }); this.observers.push(mutationObserver); this.events.push({ el: document.defaultView, handler: throttle(DELAY_MS$4, function () { _this2._adjustStuckStickyHeadingStyles(); _this2._syncStickyHeadingScrollPosition(); _this2._syncStickyHeadingWidth(); }), type: EventName$g.RESIZE_DATA_API }, { el: this.stickyHeading, handler: function handler() { _this2._adjustStuckStickyHeadingStyles(); _this2._togglePlaceHolderRowHeight(true); }, type: EventName$h.ON_STUCK }, { el: this.stickyHeading, handler: function handler() { _this2._togglePlaceHolderRowHeight(false); }, type: EventName$h.ON_UNSTUCK }, { el: this.scrollWindow, handler: function handler() { _this2._syncStickyHeadingScrollPosition(); }, type: EventName$g.SCROLL_DATA_API }); } /** * This function aligns the SKU content in the table header * @returns {void} */; _proto._alignSkuContent = function _alignSkuContent() { var tableHeaderCellsWithSku = this.tableEl.querySelectorAll('thead .ocr-table-cell:has(.sku)'); if (!tableHeaderCellsWithSku || tableHeaderCellsWithSku.length === 0) return; var isLargeViewport = _getIsLargeViewport(); var stickyHeader = this.el.querySelector(Selector$f.STICKY_HEADING); var tags = this.tableEl.querySelectorAll('thead .ocr-table-cell .tag'); // Handle sticky state if (stickyHeader != null && stickyHeader.classList.contains(ClassName$9.STUCK)) { tableHeaderCellsWithSku.forEach(function (cell) { var sku = cell.querySelector('.sku'); if (sku) { requestAnimationFrame(function () { sku.style.marginTop = '0px'; }); } }); return; } // Adjust for mobile: reset bottom margins for .tag elements if (!isLargeViewport) { tableHeaderCellsWithSku.forEach(function (cell) { var tag = cell.querySelector('.tag'); if (tag) { requestAnimationFrame(function () { tag.style.marginBottom = '0px'; }); } }); } // Calculate maximum height for .tag elements var maxHeight = 0; tags.forEach(function (tag) { var tagHeight = tag.offsetHeight; if (tagHeight > maxHeight) { maxHeight = tagHeight; } }); // Get the gap between .ocr-table-cell__content elements var cellContent = tableHeaderCellsWithSku[0].querySelector('.ocr-table-cell__content'); var gapComputedStyle = getComputedStyle(cellContent); var skuCellGapValue = gapComputedStyle.getPropertyValue('gap'); // Adjust alignment for .sku and .tag elements tableHeaderCellsWithSku.forEach(function (cell) { var tag = cell.querySelector('.tag'); if (tag) { requestAnimationFrame(function () { if (tag.offsetHeight < maxHeight) { var heightDiff = maxHeight - tag.offsetHeight; tag.style.marginBottom = heightDiff + "px"; } }); } else { var sku = cell.querySelector('.sku'); if (sku) { requestAnimationFrame(function () { var adjustedMarginTop = maxHeight + parseFloat(skuCellGapValue); sku.style.marginTop = adjustedMarginTop + "px"; }); } } }); } /** * Recalculate current column index, * based on the scroll position of the scroll window. * @returns {void} */; _proto._reCalculateColumnIndex = function _reCalculateColumnIndex() { var _this3 = this; var _this$scrollWindow = this.scrollWindow, scrollWindowLeft = _this$scrollWindow.scrollLeft, scrollWindowWidth = _this$scrollWindow.clientWidth; var scrollWindowPadding = parseFloat(getComputedStyle(this.scrollWindow).paddingInlineStart); var currentIndex = 0; this.columns.forEach(function (column, index) { var _getColumnRect2 = _getColumnRect(column), offsetLeft = _getColumnRect2.offsetLeft, offsetWidth = _getColumnRect2.offsetWidth; var isInScrollWindow = false; var precision = 1; if (_this3.isRTL) { // In RTL mode, the current column is the last column which left edge is in the scrollWindow. isInScrollWindow = offsetLeft - scrollWindowLeft + scrollWindowPadding >= -precision; } else { // In LTR mode, the current column is the last column which right edge is in the scrollWindow. isInScrollWindow = offsetLeft + offsetWidth - scrollWindowLeft - scrollWindowWidth <= precision; } if (isInScrollWindow) { currentIndex = index; } }); if (this.currentColumnIndex !== currentIndex) { this._updateColumnIndex(currentIndex); } } /** * Update current column index. * Will update the focus state of the column, * and toggle the disabled attribute of the scroll buttons. * @param {number} currentIndex */; _proto._updateColumnIndex = function _updateColumnIndex(currentIndex) { var _this4 = this; this.columns.forEach(function (column, index) { _this4._toggleColumnFocus(column, index === currentIndex); }); this.currentColumnIndex = currentIndex; this._toggleScrollButtons(); } /** * Get the document paddingInline value. * @param {isRTL} dir * @returns {String} */; _proto._getPaddingInline = function _getPaddingInline(isRTL) { var _this$tableEl$getBoun = this.tableEl.getBoundingClientRect(), left = _this$tableEl$getBoun.left, right = _this$tableEl$getBoun.right; return isRTL ? document.documentElement.clientWidth - right + "px" : left + "px"; } /** * Toggle buttons disabled attribute based on current column index. * @returns {void} */; _proto._toggleScrollButtons = function _toggleScrollButtons() { if (!this.prevButton || !this.nextButton) return; if (this.currentColumnIndex === 0) { this.prevButton.setAttribute(Attributes$9.DISABLED, true); } else { this.prevButton.removeAttribute(Attributes$9.DISABLED); } if (this.currentColumnIndex === this.columns.length - 1) { this.nextButton.setAttribute(Attributes$9.DISABLED, true); } else { this.nextButton.removeAttribute(Attributes$9.DISABLED); } } /** * Toggle column focusable state. * In small viewport, only the current column is focusable. * @param {HTMLElement[]} column * @param {boolean} enableFocus */; _proto._toggleColumnFocus = function _toggleColumnFocus(column, enableFocus) { column.forEach(function (cell) { Util$1.getTabbableElements(cell).forEach(function (el) { if (enableFocus) { el.removeAttribute(Attributes$9.TABINDEX); } else { el.setAttribute(Attributes$9.TABINDEX, -1); } }); }); } /** * Make all columns focusable. * In large viewport, all columns are focusable. * @returns {void} */; _proto._resetColumnFocus = function _resetColumnFocus() { Util$1.getTabbableElements(this.el).forEach(function (el) { el.removeAttribute(Attributes$9.TABINDEX); }); }; _proto._handlePrevButtonClick = function _handlePrevButtonClick() { var prevColumnIndex = this.currentColumnIndex - 1; if (prevColumnIndex < 0) return; this._updateColumnIndex(prevColumnIndex); this._handleScroll(); }; _proto._handleNextButtonClick = function _handleNextButtonClick() { var nextColumnIndex = this.currentColumnIndex + 1; if (nextColumnIndex >= this.columns.length) return; this._updateColumnIndex(nextColumnIndex); this._handleScroll(); }; _proto._handleScroll = function _handleScroll() { var targetColumn = this.columns[this.currentColumnIndex]; var _getColumnRect3 = _getColumnRect(targetColumn), offsetLeft = _getColumnRect3.offsetLeft, offsetWidth = _getColumnRect3.offsetWidth; var tablePadding = parseFloat(getComputedStyle(this.tableEl).paddingInlineStart); var offset = this.isRTL ? this.tableEl.offsetWidth - offsetWidth - tablePadding : tablePadding; this.scrollWindow.scrollTo({ behavior: 'smooth', left: offsetLeft - offset }); }; _proto._handleResize = function _handleResize() { var nextScrollable = !_getIsLargeViewport(); // Align SKU content in table head this._alignSkuContent(); if (nextScrollable) { this._reCalculateColumnIndex(); this._adaptScrollingEndPadding(); } if (nextScrollable === this.scrollable) { // If the viewport doesn't change from large to small or small to large, // no need to do the following. return; } this.scrollable = nextScrollable; if (!this.scrollable) { this._resetColumnFocus(); } } /** * Get the sticky instance. * @returns {FixedStickyExtension | null} */; _proto._getStickyInstance = function _getStickyInstance() { var _this5 = this; return OcrFixedSticky.getInstances().find(function (instance) { return instance.el === _this5.stickyHeading; }); } /** * Toggle the sticky heading sticky behavior. * @param {FixedStickyObserverBehavior} observerBehavior */; _proto._toggleFixedSticky = function _toggleFixedSticky(observerBehavior) { if (this.stickyInstance.observerBehavior !== observerBehavior) { this.stickyInstance.update({ observerBehavior: observerBehavior }); } } /** * Adjusts the sticky heading cells width. * If the sticky heading is stuck, * the width of the sticky heading cells should be the same as the normal row cells to align with the table. */; _proto._adjustStuckStickyHeadingStyles = function _adjustStuckStickyHeadingStyles() { var isLargeViewport = _getIsLargeViewport(); if (isLargeViewport) { var _this$tableEl$getBoun2 = this.tableEl.getBoundingClientRect(), left = _this$tableEl$getBoun2.left, right = _this$tableEl$getBoun2.right; this.stickyHeading.style.paddingInlineStart = (this.isRTL ? document.documentElement.clientWidth - right : left) + "px"; } else { var paddingInline = this._getPaddingInline(this.isRTL); this.stickyHeading.style.paddingInline = paddingInline; } var stickyHeadingCells = this.stickyHeading.children; var normalRowCells = this.stickyHeading.classList.contains(ClassName$9.STUCK_SHOW_HEAD_COLUMN_TITLE) ? this.el.querySelector(Selector$f.HEAD_ROW).children : this.stickyHeading.nextElementSibling.children; if (this.isStickyHeaderGridLayout) { var gridTemplateColumnsValue = Array.from(stickyHeadingCells).map(function (cell, index) { var normalRowCell = normalRowCells[index]; return !isLargeViewport && index === 0 ? '0px' : normalRowCell.offsetWidth + "px"; }).join(' '); this.stickyHeading.style.gridTemplateColumns = gridTemplateColumnsValue; } else { Array.from(stickyHeadingCells).forEach(function (cell, index) { var normalRowCell = normalRowCells[index]; cell.style.flexBasis = normalRowCell.offsetWidth + "px"; }); } } /** * Sync the sticky heading scroll position with the scroll window. */; _proto._syncStickyHeadingScrollPosition = function _syncStickyHeadingScrollPosition() { this.stickyHeading.scrollLeft = this.scrollWindow.scrollLeft; } /** * Synchronizes the width of the sticky heading with the width of the modal. * If the modal has scrollbar, * we need to adjust the sticky heading width to make it align with the modal. */; _proto._syncStickyHeadingWidth = function _syncStickyHeadingWidth() { if (this.modal) { this.stickyHeading.style.width = this.stickyInstance.isStuck ? Math.floor(this.modal.clientWidth) + "px" : Strings$2.EMPTY; } } /** * Toggle the placeholder row height, * We need a extra spacing in the table when sticky heading stuck, * the fixed-sticky is using margin-top to make this spacing, * but the margin not work for the table layout, * so we need adjust this extra element's height to make this spacing. * @param {boolean} isStuck */; _proto._togglePlaceHolderRowHeight = function _togglePlaceHolderRowHeight(isStuck) { this.placeholderRow.style.height = isStuck ? this.stickyInstance.stickyElementHeight + "px" : Strings$2.EMPTY; } /** * Update the ARIA hidden attributes for elements within the sticky heading. * When the sticky heading is stuck, the title becomes visible, and the collapse toggle button is hidden. * When the sticky heading is unstuck, the title is hidden, and the collapse toggle button becomes visible. * @param {boolean} isStuck - whether the sticky heading is currently stuck or not. * @param {HTMLElement} firstStickyCellTitle - The title text in the first sticky cell. * @param {HTMLElement} collapseToggleButton - The collapse toggle button element in the first sticky cell. */; _proto._updateAriaHiddenAttributes = function _updateAriaHiddenAttributes(isStuck, firstStickyCellTitle, collapseToggleButton) { if (firstStickyCellTitle) { if (isStuck) { firstStickyCellTitle.removeAttribute(Attributes$9.ARIA_HIDDEN); } else { firstStickyCellTitle.setAttribute(Attributes$9.ARIA_HIDDEN, true); } } if (collapseToggleButton) { if (isStuck) { collapseToggleButton.setAttribute(Attributes$9.ARIA_HIDDEN, true); } else { collapseToggleButton.removeAttribute(Attributes$9.ARIA_HIDDEN); } } } /** * Update the aria-expanded attributes for collapse triggers and show the target elements. */; _proto._updateCollapseTriggersAndShowTargets = function _updateCollapseTriggersAndShowTargets() { var collapseTriggers = this.el.querySelectorAll(Selector$f.MULTI_COLLAPSE); var targetIdSet = new Set(); collapseTriggers.forEach(function (trigger) { var _trigger$getAttribute; var expand = trigger.getAttribute(Attributes$9.DATA_EXPAND) || 'true'; if (expand) { trigger.setAttribute(Attributes$9.ARIA_EXPANDED, expand.toString()); } var targetIdsString = (_trigger$getAttribute = trigger.getAttribute(Attributes$9.DATA_TARGET)) == null ? void 0 : _trigger$getAttribute.replace(/#/g, ''); targetIdsString == null ? void 0 : targetIdsString.split(',').forEach(function (id) { targetIdSet.add([id.trim(), expand]); }); }); targetIdSet.forEach(function (_ref2) { var id = _ref2[0], expand = _ref2[1]; var targetElement = document.getElementById(id); if (targetElement) { targetElement.classList.add(ClassName$9.COLLAPSE); if (expand.toString() === 'true') { targetElement.classList.add(ClassName$9.SHOW); } else { targetElement.classList.remove(ClassName$9.SHOW); } } }); } /** * Update the instance. * Not currently used, but required by API standards. */; _proto.update = function update() { // Create and dispatch custom event this[EventName$g.ON_UPDATE] = new CustomEvent(EventName$g.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$g.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { this.observers.forEach(function (observer) { observer.disconnect(); }); Util$1.removeEvents(this.events); this[EventName$g.ON_REMOVE] = new CustomEvent(EventName$g.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$g.ON_REMOVE]); var index = instances$c.indexOf(this); instances$c.splice(index, 1); } /** * Get table instances. * @returns {Table[]} An array of instances */; Table.getInstances = function getInstances() { return instances$c; }; return Table; }(); var Selector$e = { DATA_MOUNT: "[data-mount='proactive-chat']", CLOSE_BUTTON: '.proactive-chat__header .btn', CANCEL_LINK: '.proactive-chat__body .link-inline', OPEN_CHAT_BUTTON: '.proactive-chat__body .btn', HEADER_TITLE: '.proactive-chat__header__title', BLOCK_FEATURE_TITLE: '.proactive-chat__body .block-feature__title' }; var Attributes$8 = { POPUP_DELAY: 'data-popup-delay' }; var EventName$f = { ON_REMOVE: 'onRemove', CLICK: 'click', KEYDOWN: 'keydown' }; /** * ProactiveChat instances */ var instances$b = []; /** * Filters through all the AIChatDrawer instances and returns the one that matches the one on the page * @returns {AIChatDrawer} - The AIChatDrawer instance that is closest to the ProactiveChat instance */ function _getAIChatDrawerInstance() { var _window$m, _window$m$AIChatDrawe; var aiChatDrawer = document.querySelector(Selector$j.DATA_MOUNT); // Filter through all the AIChatDrawer instances and return the one that matches var ocrAiChatDrawer = AIChatDrawer.getInstances().find(function (instance) { return instance.el === aiChatDrawer; }); if (ocrAiChatDrawer) return ocrAiChatDrawer; // If there is no reimagine AI Chat Drawer, check for an m365 one return (_window$m = window.m365) == null ? void 0 : (_window$m$AIChatDrawe = _window$m.AIChatDrawer) == null ? void 0 : _window$m$AIChatDrawe.getInstances().find(function (instance) { return instance.el === aiChatDrawer; }); } /** * Set the aria-controls attribute on the Proactive Chat's elements */ function _setAriaControls() { var aiChatDrawer = this.aiChatDrawer, openChatButton = this.openChatButton, cancelLink = this.cancelLink, closeButton = this.closeButton, el = this.el; // Set the aria-controls attribute openChatButton.setAttribute('aria-controls', aiChatDrawer.el.id); cancelLink.setAttribute('aria-controls', el.id); closeButton.setAttribute('aria-controls', el.id); } /** * Update the texts on the Proactive Chat in case they weren't initialized due to a CF error * Currently only supports Option 1 */ function _updateTexts() { var isOptionTwo = this.isOptionTwo, headerTitle = this.headerTitle, blockFeatureTitle = this.blockFeatureTitle, openChatButtonTextElement = this.openChatButtonTextElement, cancelLinkTextElement = this.cancelLinkTextElement, closeButton = this.closeButton, closeButtonAriaLabel = this.closeButtonAriaLabel; // Only option 1 is supported right now if (isOptionTwo) return; // Update the texts headerTitle.textContent = this.headerTitleText; blockFeatureTitle.textContent = this.blockFeatureTitleText; if (openChatButtonTextElement) openChatButtonTextElement.textContent = this.openChatButtonText; if (cancelLinkTextElement) cancelLinkTextElement.textContent = this.cancelLinkText; // Update aria-label closeButton.setAttribute('aria-label', closeButtonAriaLabel); } var ProactiveChat = /*#__PURE__*/function () { function ProactiveChat(opts) { var _this$cancelLink, _this$openChatButton, _this$blockFeatureTit, _this$cancelLinkTextE, _this$closeButton, _this$headerTitle, _this$openChatButtonT, _this = this; this.el = opts.el; // #region opts and properties this.aiChatDrawer = opts.aiChatDrawer || _getAIChatDrawerInstance.call(this); this.blockFeatureTitle = opts.blockFeatureTitle || this.el.querySelector(Selector$e.BLOCK_FEATURE_TITLE); this.cancelLink = opts.cancelLink || this.el.querySelector(Selector$e.CANCEL_LINK); this.cancelLinkTextElement = (_this$cancelLink = this.cancelLink) == null ? void 0 : _this$cancelLink.querySelector('.link__text'); this.closeButton = opts.closeButton || this.el.querySelector(Selector$e.CLOSE_BUTTON); this.headerTitle = opts.headerTitle || this.el.querySelector(Selector$e.HEADER_TITLE); this.isOptionTwo = this.el.classList.contains('proactive-chat--option-2'); this.popupDelay = this.el.getAttribute(Attributes$8.POPUP_DELAY) || 15000; this.openChatButton = opts.openChatButton || this.el.querySelector(Selector$e.OPEN_CHAT_BUTTON); this.openChatButtonTextElement = (_this$openChatButton = this.openChatButton) == null ? void 0 : _this$openChatButton.querySelector('.btn__text'); // #endregion // #region String Defaults // Get and set the texts this.blockFeatureTitleText = ((_this$blockFeatureTit = this.blockFeatureTitle) == null ? void 0 : _this$blockFeatureTit.textContent) || 'AI-powered assistant is available 24x7.'; this.cancelLinkText = ((_this$cancelLinkTextE = this.cancelLinkTextElement) == null ? void 0 : _this$cancelLinkTextE.textContent) || 'No thanks'; this.closeButtonAriaLabel = ((_this$closeButton = this.closeButton) == null ? void 0 : _this$closeButton.getAttribute('aria-label')) || 'Close this popup'; this.headerTitleText = ((_this$headerTitle = this.headerTitle) == null ? void 0 : _this$headerTitle.textContent) || 'Can we help you?'; this.openChatButtonText = ((_this$openChatButtonT = this.openChatButtonTextElement) == null ? void 0 : _this$openChatButtonT.textContent) || 'Chat now'; _updateTexts.call(this); // #endregion // Show the popup after the delay, but only if the drawer is not visually suppressed this.popupTimeout = setTimeout(function () { _this.showHidePopup(true); }, this.popupDelay); // Add event listeners this.events = [{ el: this.closeButton, type: EventName$f.CLICK, handler: function handler(e) { return _this.hidePopover(e); } }, { el: this.cancelLink, type: EventName$f.CLICK, handler: function handler(e) { return _this.hidePopover(e); } }, { el: this.cancelLink, type: EventName$f.KEYDOWN, handler: function handler(e) { return _this.hidePopover(e); } }, { el: this.openChatButton, type: EventName$f.CLICK, handler: function handler(e) { return _this.openChat(e); } }]; Util$1.addEvents(this.events); // Set the aria-controls attribute _setAriaControls.call(this); instances$b.push(this); } /** * Hides the popover and sets the cookie to never show the popup again * @param {Event} e */ var _proto = ProactiveChat.prototype; _proto.hidePopover = function hidePopover(e) { var aiChatDrawer = this.aiChatDrawer; // Check if the event type is keydown and the key is neither Spacebar nor Enter if (e.type === 'keydown' && e.key !== ' ' && e.key !== 'Enter') { return; } // Set the cookie to never show the popup again aiChatDrawer.updateAIChatDrawerCookie({ hideProactiveChat: true }); this.showHidePopup(false, e); } /** * Opens the chat and hides the popup */; _proto.openChat = function openChat(e) { var aiChatDrawer = this.aiChatDrawer; this.showHidePopup(false); aiChatDrawer.isInstantiatedByProactiveChat = true; aiChatDrawer.onAiChatButtonClick(e); } /** * Show or hides the popup based on the show parameter * and if the chat has been initialized, if proactive chat has been hidden, * and if the drawer is surpressed * @param {boolean} show * @param {Event} e - The event object */; _proto.showHidePopup = function showHidePopup(show, e) { var el = this.el, aiChatDrawer = this.aiChatDrawer; e == null ? void 0 : e.preventDefault(); e == null ? void 0 : e.stopPropagation(); // Get the hideProactiveChat cookie var cookie = aiChatDrawer.getAIChatDrawerCookieObject(); var hideProactiveChat = cookie == null ? void 0 : cookie.hideProactiveChat; // If the Drawer is visually suppressed; the Proactive Chat should also remain invisible. We do not want to allow the Proactive Chat to change the drawer's state via user interaction with Proactive Chat var isDrawerSuppressed = this.aiChatDrawer.getIsHidden(); // Only show if the chat has not been initialized, if the hideProactiveChat cookie is false, and if the chat drawer is not surpressed show = show && !aiChatDrawer.chatInitialized && !hideProactiveChat && !isDrawerSuppressed; // Show the popup and hide the chat button and vice-versa el.classList.toggle('d-none', !show); aiChatDrawer.showChatButton(!show); } /** * Remove the event handlers and the pagination instance */; _proto.remove = function remove() { // Remove event handlers, observers, etc. Util$1.removeEvents(this.events); clearTimeout(this.popupTimeout); // Remove this reference from the array of instances. var index = instances$b.indexOf(this); instances$b.splice(index, 1); // Create and dispatch custom event this[EventName$f.ON_REMOVE] = new CustomEvent(EventName$f.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$f.ON_REMOVE]); } /** * Update instance. Added for API consistency * @param opts - update options */; _proto.update = function update() {} /** * @returns {ProactiveChat[]} - All the ProactiveChat instances */; ProactiveChat.getInstances = function getInstances() { return instances$b; }; return ProactiveChat; }(); /** Breadcrumbs START */ var instances$a = []; /** * HTML Attributes. * @enum {string} */ var Attributes$7 = { ARIA_CURRENT: 'aria-current', ARIA_CURRENT_VALUE: 'page' }; /** * CSS Classes. * @enum {string} */ var ClassName$8 = { BREADCRUMBS_LIST: 'breadcrumbs__list', BREADCRUMBS_ITEMS: 'breadcrumbs__item', BREADCRUMBS_COLLAPSED: 'breadcrumbs--collapsed', BREADCRUMBS_COLLAPSED_ITEMS: 'breadcrumbs__collapsed-item', BREADCRUMBS_EXPAND: 'breadcrumbs__btn-expand', BREADCRUMBS_HIDE: 'breadcrumbs__item--d-none', BREADCRUMBS_LINK_TEXT: 'link__text', D_NONE: 'd-none' }; /** * JS event name. * @enum {string} */ var EventName$e = { CLICK_DATA_API: 'click', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; /** * CSS selector. * @enum {string} */ var Selector$d = { BREADCRUMBS_LIST: "." + ClassName$8.BREADCRUMBS_LIST, BREADCRUMBS_ITEMS: "." + ClassName$8.BREADCRUMBS_ITEMS, BREADCRUMBS_COLLAPSED_ITEMS: "." + ClassName$8.BREADCRUMBS_COLLAPSED_ITEMS, BREADCRUMBS_BTN_EXPAND: "." + ClassName$8.BREADCRUMBS_EXPAND + " .btn", DATA_MOUNT: "[data-mount=\"ocr-breadcrumbs\"]", LINK_TAG: "a", BREADCRUMBS_LINK_TEXT: "." + ClassName$8.BREADCRUMBS_LINK_TEXT, HERO_MEDIA_HAS_BREADCRUMBS: ".hero-media", HERO_MEDIA_MEDIA_SLOT: ".hero-media__media .media__slot", SECTION_MASTER_BREADCRUMBS_CONTAINER: ".section-master__breadcrumbs", HERO_ARTICLE_BREADCRUMBS_CONTAINER: ".hero-article__breadcrumbs" }; var MAX_BREADCRUMBS_BEFORE_COLLAPSE = 3; var MIN_COUNT_OF_NONEMPTYSTRING_LABEL = 2; var HERO_MEDIA_BREADCRUMBS_HEIGHT_VARIABLE = '--breadcrumbs-height'; var Breadcrumbs = /*#__PURE__*/function () { /** * Initializes a new instance of the Breadcrumbs component. * @param {{ el: HTMLElement }} opts Initialization options. */ function Breadcrumbs(opts) { /** * Breadcrumb's List Element. * @type {HTMLDivElement} */ this.breadcrumbsList = void 0; /** * Root element. * @type {HTMLElement} */ this.el = void 0; /** * resize observer * @type {ResizeObserver} */ this.resizeObserver = void 0; /** * Event bindings. * @type {{ el: Element, handler: (...args: unknown[]) => unknown, type: string}[]} */ this.events = []; this.el = opts.el; this.breadcrumbsList = this.el.querySelector(Selector$d.BREADCRUMBS_LIST); this.breadcrumbItems = this.breadcrumbsList.querySelectorAll(Selector$d.BREADCRUMBS_ITEMS); this.collapsedViewItems = this.breadcrumbsList.querySelectorAll(Selector$d.BREADCRUMBS_COLLAPSED_ITEMS); this.breadcrumbsBtnExpand = this.breadcrumbsList.querySelector(Selector$d.BREADCRUMBS_BTN_EXPAND); this.currentPageLink = this.breadcrumbItems[this.breadcrumbItems.length - 1].querySelector(Selector$d.LINK_TAG); this.currentPageLink.setAttribute(Attributes$7.ARIA_CURRENT, Attributes$7.ARIA_CURRENT_VALUE); this.events.push({ el: this.breadcrumbsBtnExpand, type: EventName$e.CLICK_DATA_API, handler: this.showAllBreadcrumbs.bind(this) }, { el: this.currentPageLink, type: EventName$e.CLICK_DATA_API, handler: function handler(e) { e.preventDefault(); } }); if (this.getCountOfNonEmptyStringLabel() > MAX_BREADCRUMBS_BEFORE_COLLAPSE) { this.createCollapsedView(); } this.setBreadcrumbHrefs(); var heroMedia = this.el.closest(Selector$d.HERO_MEDIA_HAS_BREADCRUMBS); if (heroMedia) { this.resizeObserver = new ResizeObserver(this.handleResizeObserver.bind(this)); this.resizeObserver.observe(this.el); } if (this.getCountOfNonEmptyStringLabel() < MIN_COUNT_OF_NONEMPTYSTRING_LABEL) { this.hideBreadcrumbs(); this.hideBreadcrumbs(Selector$d.SECTION_MASTER_BREADCRUMBS_CONTAINER); this.hideBreadcrumbs(Selector$d.HERO_ARTICLE_BREADCRUMBS_CONTAINER); if (heroMedia) { heroMedia.style.setProperty(HERO_MEDIA_BREADCRUMBS_HEIGHT_VARIABLE, '0px'); } } Util$1.addEvents(this.events); instances$a.push(this); } /** * resizeObserverCallback * @param {ResizeObserverEntry[]} entries */ var _proto = Breadcrumbs.prototype; _proto.handleResizeObserver = function handleResizeObserver(entries) { if (entries && entries.length > 0) { for (var _iterator = _createForOfIteratorHelperLoose(entries), _step; !(_step = _iterator()).done;) { var entry = _step.value; if (entry.contentRect) { var heroMedia = entry.target.closest(Selector$d.HERO_MEDIA_HAS_BREADCRUMBS); if (heroMedia && !entry.target.classList.contains(ClassName$8.D_NONE)) { var breadcrumbsComputedStyle = window.getComputedStyle(entry.target); var breadcrumbsHeight = this.computeElementContentHeightValue(breadcrumbsComputedStyle); heroMedia.style.setProperty(HERO_MEDIA_BREADCRUMBS_HEIGHT_VARIABLE, breadcrumbsHeight + 'px'); } } } // Other logic can put here } } /** * * @param {CSSStyleDeclaration} computedStyle */; _proto.computeElementContentHeightValue = function computeElementContentHeightValue(computedStyle) { if (computedStyle.boxSizing === 'border-box') { return parseInt(computedStyle.height, 10); } var height = computedStyle.height, paddingTop = computedStyle.paddingTop, paddingBottom = computedStyle.paddingBottom, borderTop = computedStyle.borderTop, borderBottom = computedStyle.borderBottom; return parseInt(height, 10) + parseInt(paddingTop, 10) + parseInt(borderTop, 10) + parseInt(paddingBottom, 10) + parseInt(borderBottom, 10); } /** * Set target breadcrumbs to display: none using d-none classname and customized selector * @param {String} selector */; _proto.hideBreadcrumbs = function hideBreadcrumbs(selector) { if (selector === void 0) { selector = Selector$d.DATA_MOUNT; } var breadcrumbs = document.querySelector(selector); if (breadcrumbs && !breadcrumbs.classList.contains(ClassName$8.D_NONE)) { breadcrumbs.classList.add(ClassName$8.D_NONE); } } /** * We have logic in AEM that adding d-none class for Empty Label */; _proto.getCountOfNonEmptyStringLabel = function getCountOfNonEmptyStringLabel() { var breadcrumbItems = this.breadcrumbItems; if (!breadcrumbItems) { return 0; } return Array.from(breadcrumbItems).filter(function (item) { return !item.classList.contains(ClassName$8.D_NONE); }).length; }; _proto.createCollapsedView = function createCollapsedView() { var el = this.el, breadcrumbItems = this.breadcrumbItems, collapsedViewItems = this.collapsedViewItems; breadcrumbItems.forEach(function (item, index) { if (index < breadcrumbItems.length - 2) { item.classList.add(ClassName$8.BREADCRUMBS_HIDE); } }); collapsedViewItems.forEach(function (item) { item.classList.remove(ClassName$8.BREADCRUMBS_HIDE); }); el.classList.add(ClassName$8.BREADCRUMBS_COLLAPSED); } /** * Set HREFs for all breadcrumb items on load. */; _proto.setBreadcrumbHrefs = function setBreadcrumbHrefs(currentPageURL) { if (currentPageURL === void 0) { currentPageURL = window.location.href; } var splitURL = currentPageURL.split('?')[0].split('/'); if (splitURL[splitURL.length - 1] === '') { splitURL.pop(); } for (var i = this.breadcrumbItems.length - 1; i >= 0; i--) { var indexOffset = this.breadcrumbItems.length - 1 - i; var link = this.breadcrumbItems[i].querySelector(Selector$d.LINK_TAG); if (link && splitURL.length - indexOffset >= 0) { link.href = splitURL.slice(0, splitURL.length - indexOffset).join('/'); } } } /* * Show all breadcrumbs on click */; _proto.showAllBreadcrumbs = function showAllBreadcrumbs(e) { var _this = this; if (e) { e.preventDefault(); } this.collapsedViewItems.forEach(function (item) { item.classList.add(ClassName$8.BREADCRUMBS_HIDE); }); this.breadcrumbItems.forEach(function (item, index) { if (index < _this.breadcrumbItems.length - 2) { item.classList.remove(ClassName$8.BREADCRUMBS_HIDE); } }); this.el.classList.remove(ClassName$8.BREADCRUMBS_COLLAPSED); this.breadcrumbItems[1].querySelector(Selector$d.LINK_TAG).focus(); } /** * Update the instance. * Not currently used, but required by API standards. */; _proto.update = function update() { this.el.dispatchEvent(this[EventName$e.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { if (this.resizeObserver) { this.resizeObserver.disconnect(); } Util$1.removeEvents(this.events); var index = instances$a.indexOf(this); instances$a.splice(index, 1); this[EventName$e.ON_REMOVE] = new CustomEvent(EventName$e.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$e.ON_REMOVE]); } /** * Get Breadcrumbs instances. * @returns {Breadcrumbs[]} An array of Breadcrumbs instances */; Breadcrumbs.getInstances = function getInstances() { return instances$a; }; return Breadcrumbs; }(); /** Breadcrumbs END */ var instances$9 = []; /** * CSS selector. * @enum {string} */ var Selector$c = { DATA_MOUNT: '[data-mount="oc-rolling-text"]', ROLL_TEXT_SR_ONLY: '.rolling-text__sr-only', ROLLING_TEXT_AFTER: '.block-heading__rolling-text--after', ROLLING_TEXT_BEFORE: '.block-heading__rolling-text--before', ROLLING_TEXT_BUTTON: '.block-heading__rolling-text-button button', ROLLING_TEXT_CONTAINER: '.block-heading__rolling-text--dynamic-container', ROLLING_TEXT_ELEMENTS: '.block-heading__rolling-text--dynamic', ROLLING_TEXT_STATIC: '.block-heading__rolling-text--static' }; /** * CSS Classes. * @enum {string} */ var ClassName$7 = { ICON_PLAY_SOLID: 'glyph-prepend-play-solid', ICON_PAUSE_SOLID: 'glyph-prepend-pause', ROLL_TEXT_SR_ONLY: 'rolling-text__sr-only', ROLLING_TEXT_AFTER: 'block-heading__rolling-text--after', ROLLING_TEXT_BEFORE: 'block-heading__rolling-text--before', ROLLING_TEXT_CONTAINER: 'block-heading__rolling-text--dynamic-container', ROLLING_TEXT_ELEMENT: 'block-heading__rolling-text--dynamic', ROLLING_TEXT_GRADIENT: "fg--special-strong-gradient-1", ROLLING_TEXT_STATIC: 'block-heading__rolling-text--static' }; /** * JS event name. * @enum {string} */ var EventName$d = { ON_CLICK: 'click', ON_INIT: 'onInit', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove' }; /** * HTML Attributes. * @enum {string} */ var Attributes$6 = { ARIA_SELECTED: 'aria-selected', DATA_PAUSE_ARIA_LABEL: 'data-pause-aria-label', DATA_PLAY_ARIA_LABEL: 'data-play-aria-label', DATA_ROLLING_TEXT: 'data-rolling-text', DISABLED: 'disabled', TABINDEX: 'tabindex' }; var RollingText = /*#__PURE__*/function () { /** * Initializes a new instance of the Dynamic Content component. * @param {{ el: HTMLDivElement }} opts Initialization options. */ function RollingText(opts) { this.el = opts.el; this.rollingTextString = this.escapeHtmlTags(this.el.getAttribute(Attributes$6.DATA_ROLLING_TEXT) || ''); this.rollingTextContainer = this.el.querySelector(Selector$c.ROLLING_TEXT_CONTAINER); this.rollingTextElements = []; this.screenReaderRollingTextHelper = this.el.querySelector(Selector$c.ROLL_TEXT_SR_ONLY); // Parse the rolling text string and create dynamic elements this.parseRollingTextString(); this.animationControl = RollingText.AnimationControls.PLAYING; this.animationTimeout = null; this.currentElementIndex = 0; this.rollingTextContainerFocused = false; this.buttonDisabled = false; // Store bound event handlers for proper cleanup this.boundHandlePlayPauseClick = this.handlePlayPauseClick.bind(this); this.boundHandleFocusIn = this.handleFocusIn.bind(this); this.boundHandleBlur = this.handleBlur.bind(this); // Find the matched play/pause button for this component by the component's ID. this.playPauseButton = this.el.querySelector(Selector$c.ROLLING_TEXT_BUTTON); if (this.playPauseButton) { this.playPauseButtonIcon = this.playPauseButton.querySelector('span'); // Get aria-label values from data attributes this.playAriaLabel = this.el.getAttribute(Attributes$6.DATA_PLAY_ARIA_LABEL) || 'Play rolling text'; this.pauseAriaLabel = this.el.getAttribute(Attributes$6.DATA_PAUSE_ARIA_LABEL) || 'Pause rolling text'; // Initialize button state this.playPauseButton.setAttribute('data-state', 'play'); // Set initial icon to pause (since animation starts playing) this.updateButtonIcon('pause'); } else { console.warn('No play/pause button found for this rolling text component.'); this.animationControl = RollingText.AnimationControls.PAUSED; // Default to paused if no button } // Bind event listeners this.bindEvents(); // Start animations this.startAnimation(); // Add this instance to the instances array instances$9.push(this); } /** * Escape HTML tags from a string, leaving only the text content * @param {string} str - The string that may contain HTML tags * @returns {string} The string with HTML tags removed */ var _proto = RollingText.prototype; _proto.escapeHtmlTags = function escapeHtmlTags(str) { if (!str) return ''; // Create a temporary DOM element to parse and extract text content var tempDiv = document.createElement('div'); tempDiv.innerHTML = str; return tempDiv.textContent || tempDiv.innerText || ''; } /** * Parse the rolling text string and create dynamic elements */; _proto.parseRollingTextString = function parseRollingTextString() { var _this = this; if (!this.rollingTextString || !this.rollingTextContainer) { return; } // Find all semicolon positions var semicolonPositions = []; for (var i = 0; i < this.rollingTextString.length; i++) { if (this.rollingTextString[i] === ';') { semicolonPositions.push(i); } } if (semicolonPositions.length === 0) { // No semicolons found, treat entire string as start text this.createStaticElement('before', this.rollingTextString.trim()); return; } // Extract start text (everything before first semicolon) var startText = this.rollingTextString.slice(0, semicolonPositions[0]).trim(); if (startText) { this.createStaticElement('before', startText); } // Extract end text (everything after last semicolon) var endText = this.rollingTextString.slice(semicolonPositions[semicolonPositions.length - 1] + 1).trim(); if (endText) { this.createStaticElement('after', endText); } // Extract rolling text elements (text between semicolons) var rollingTexts = []; // Determine how many pairs we can process var pairCount = Math.floor(semicolonPositions.length / 2); // Warn if we have an odd number of semicolons if (semicolonPositions.length % 2 !== 0) { console.warn('Odd number of semicolons detected in rolling text string. The last unpaired semicolon will be ignored.'); } // Process all complete pairs for (var _i = 0; _i < pairCount; _i++) { var startPos = semicolonPositions[_i * 2] + 1; var endPos = semicolonPositions[_i * 2 + 1]; var rollingText = this.rollingTextString.slice(startPos, endPos).trim(); if (rollingText) { rollingTexts.push(rollingText); } } // Create rolling text elements rollingTexts.forEach(function (text, index) { _this.createRollingTextElement(text, index); }); } /** * Create a static text element (before or after) * @param {string} position - 'before' or 'after' * @param {string} text - The text content */; _proto.createStaticElement = function createStaticElement(position, text) { var staticElement = document.createElement('div'); staticElement.className = ClassName$7.ROLLING_TEXT_STATIC + " " + (position === 'before' ? ClassName$7.ROLLING_TEXT_BEFORE : ClassName$7.ROLLING_TEXT_AFTER); staticElement.textContent = text; if (position === 'before') { this.rollingTextContainer.parentNode.insertBefore(staticElement, this.rollingTextContainer); } else { this.rollingTextContainer.parentNode.insertBefore(staticElement, this.rollingTextContainer.nextSibling); } } /** * Create a rolling text element * @param {string} text - The text content */; _proto.createRollingTextElement = function createRollingTextElement(text) { var rollingElement = document.createElement('div'); rollingElement.className = ClassName$7.ROLLING_TEXT_ELEMENT; rollingElement.classList.add(ClassName$7.ROLLING_TEXT_GRADIENT); rollingElement.textContent = text; rollingElement.setAttribute('aria-hidden', 'true'); this.rollingTextContainer.append(rollingElement); this.rollingTextElements.push(rollingElement); } /** * Bind event listeners */; _proto.bindEvents = function bindEvents() { if (this.playPauseButton) { this.playPauseButton.addEventListener('click', this.boundHandlePlayPauseClick); } if (this.rollingTextContainer) { this.rollingTextContainer.addEventListener('focusin', this.boundHandleFocusIn); this.rollingTextContainer.addEventListener('blur', this.boundHandleBlur); } } /** * Handle play/pause button click */; _proto.handlePlayPauseClick = function handlePlayPauseClick() { // Ignore clicks if button is disabled if (this.buttonDisabled) { return; } switch (this.animationControl) { case RollingText.AnimationControls.PLAYING: { this.disableButton(); this.playPauseButton.setAttribute('data-state', 'pause'); this.updateButtonIcon('play'); this.pauseAnimation(); break; } case RollingText.AnimationControls.PAUSED: { this.disableButton(); this.playPauseButton.setAttribute('data-state', 'play'); this.updateButtonIcon('pause'); this.resumeAnimation(); break; } } } /** * Handle focus in event on rolling text container */; _proto.handleFocusIn = function handleFocusIn() { this.rollingTextContainerFocused = true; // Set aria-live for screen reader if (this.screenReaderRollingTextHelper) { this.screenReaderRollingTextHelper.setAttribute('aria-live', 'polite'); } this.pauseAnimation(); } /** * Handle blur event on rolling text container */; _proto.handleBlur = function handleBlur() { var _this2 = this; this.rollingTextContainerFocused = false; // Remove aria-live for screen reader if (this.screenReaderRollingTextHelper) { this.screenReaderRollingTextHelper.removeAttribute('aria-live'); } // Only resume if the play/pause button is in 'play' state. var buttonState = this.playPauseButton ? this.playPauseButton.getAttribute('data-state') : 'pause'; if (buttonState === 'play' && this.animationControl === RollingText.AnimationControls.PAUSING) { // Timing fix: The Animation System is "PAUSING", so we can't immediately resume. // Wait for the animation to finish before resuming this.animationTimeout = setTimeout(function () { _this2.resumeAnimation(); }, 750); } else if (buttonState === 'play') { this.resumeAnimation(); } } /** * Start the animation system */; _proto.startAnimation = function startAnimation() { if (this.rollingTextElements.length === 0) return; this.animationControl = RollingText.AnimationControls.PLAYING; this.animateNext(); } /** * Animate to the next element */; _proto.animateNext = function animateNext() { var _this3 = this; if (this.animationControl !== RollingText.AnimationControls.PLAYING && this.animationControl !== RollingText.AnimationControls.PAUSING) { return; } var buttonState = this.playPauseButton ? this.playPauseButton.getAttribute('data-state') : 'pause'; // Clear animation classes from all elements this.clearAllAnimationClasses(); var currentElement = this.rollingTextElements[this.currentElementIndex]; // We paused the animation due to focus or button state if (this.animationControl === RollingText.AnimationControls.PAUSING && (this.rollingTextContainerFocused || buttonState === 'pause')) { // Add animate-in class and set to paused currentElement.classList.add('animate-in'); // Update screen reader with current text this.updateScreenReaderText(currentElement.textContent); this.animationTimeout = setTimeout(function () { _this3.animationControl = RollingText.AnimationControls.PAUSED; _this3.enableButton(); }, 400); // animate-in duration } else { // If we were "PAUSING" due to container focus state, but are no longer focused, reset state if (this.animationControl === RollingText.AnimationControls.PAUSING && !this.rollingTextContainerFocused && buttonState === 'play') { this.animationControl = RollingText.AnimationControls.PLAYING; } // Add animate-full class and continue to next element currentElement.classList.add('animate-full'); // Update screen reader with current text this.updateScreenReaderText(currentElement.textContent); this.animationTimeout = setTimeout(function () { _this3.moveToNextElement(); _this3.animateNext(); }, 1500); // animate-full duration } } /** * Move to the next element in the sequence */; _proto.moveToNextElement = function moveToNextElement() { this.currentElementIndex = (this.currentElementIndex + 1) % this.rollingTextElements.length; } /** * Pause the animation system */; _proto.pauseAnimation = function pauseAnimation() { if (this.animationControl === RollingText.AnimationControls.PLAYING) { this.animationControl = RollingText.AnimationControls.PAUSING; // The actual pausing logic is handled in animateNext() } } /** * Resume the animation system */; _proto.resumeAnimation = function resumeAnimation() { var _this4 = this; if (this.animationControl === RollingText.AnimationControls.PAUSED) { this.animationControl = RollingText.AnimationControls.RESUMING; var currentElement = this.rollingTextElements[this.currentElementIndex]; this.clearAnimationClasses(currentElement); currentElement.classList.add('animate-out'); this.animationTimeout = setTimeout(function () { _this4.clearAnimationClasses(currentElement); _this4.moveToNextElement(); _this4.animationControl = RollingText.AnimationControls.PLAYING; _this4.enableButton(); _this4.animateNext(); }, 400); // animate-out duration } } /** * Remove animation classes from all rolling text elements. */; _proto.clearAllAnimationClasses = function clearAllAnimationClasses() { var _this5 = this; this.rollingTextElements.forEach(function (element) { _this5.clearAnimationClasses(element); }); } /** * Remove animation classes from the given element. * @param {HTMLElement} element */; _proto.clearAnimationClasses = function clearAnimationClasses(element) { element.classList.remove('animate-in', 'animate-full', 'animate-out'); } /** * Disable the play/pause button */; _proto.disableButton = function disableButton() { this.buttonDisabled = true; if (this.playPauseButton) { this.playPauseButton.disabled = true; } } /** * Enable the play/pause button */; _proto.enableButton = function enableButton() { this.buttonDisabled = false; if (this.playPauseButton) { this.playPauseButton.disabled = false; } } /** * Update the button icon based on the current state * @param {string} state - 'play' or 'pause' */; _proto.updateButtonIcon = function updateButtonIcon(state) { if (!this.playPauseButtonIcon) return; // Remove existing icon classes this.playPauseButtonIcon.classList.remove(ClassName$7.ICON_PLAY_SOLID, ClassName$7.ICON_PAUSE_SOLID); // Add the appropriate icon class and update aria-label if (state === 'play') { this.playPauseButtonIcon.classList.add(ClassName$7.ICON_PLAY_SOLID); this.playPauseButton.setAttribute('aria-label', this.playAriaLabel); } else if (state === 'pause') { this.playPauseButtonIcon.classList.add(ClassName$7.ICON_PAUSE_SOLID); this.playPauseButton.setAttribute('aria-label', this.pauseAriaLabel); } } /** * Update the screen reader helper with the current text * @param {string} text - The text to announce to screen readers */; _proto.updateScreenReaderText = function updateScreenReaderText(text) { if (this.screenReaderRollingTextHelper && text) { this.screenReaderRollingTextHelper.textContent = text.trim(); } } /** * Update the instance. * Not currently used, but required by API standards. */; _proto.update = function update() { // no-op; Included for API completeness this.el.dispatchEvent(new CustomEvent(EventName$d.ON_UPDATE, { bubbles: true })); } /** * Remove the instance */; _proto.remove = function remove() { // Clear any running timeouts if (this.animationTimeout) { clearTimeout(this.animationTimeout); } // Remove event listeners if (this.playPauseButton) { this.playPauseButton.removeEventListener('click', this.boundHandlePlayPauseClick); } if (this.rollingTextContainer) { this.rollingTextContainer.removeEventListener('focusin', this.boundHandleFocusIn); this.rollingTextContainer.removeEventListener('blur', this.boundHandleBlur); } var index = instances$9.indexOf(this); if (index > -1) { instances$9.splice(index, 1); } this.el.dispatchEvent(new CustomEvent(EventName$d.ON_REMOVE, { bubbles: true })); } /** * Get instances. * @returns {RollingText[]} An array of instances */; RollingText.getInstances = function getInstances() { return instances$9; }; return RollingText; }(); RollingText.AnimationControls = { PLAYING: 'playing', PAUSING: 'pausing', PAUSED: 'paused', RESUMING: 'resuming' }; var instances$8 = []; var Selector$b = { DATA_MOUNT: '[data-mount="selector-slider"]', RANGE_SLIDER: '.selector-slider__input', DRAG_PILL: 'selector-slider__drag-pill', INDICATOR_WRAPPER: 'selector-slider__indicators-wrapper', INDICATOR: 'selector-slider__indicator', MAXTEXT: 'maxtext', MINTEXT: 'mintext', VALUETEXT: 'valuetext', DRAG_PILL_COUNT: '--selector-slider-item-count' }; /** * JS event name. * @enum {string} */ var EventName$c = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', ON_INPUT: 'input', ON_CHANGE: 'change', ON_RESIZE: 'resize', ON_SELECTOR_SLIDER_CHANGE: 'onSelectorSliderChange' }; /** * Returns the value text based on the current value of the selector slider. * If the value is equal to the minimum or maximum value, it returns the corresponding text. * Otherwise, it returns the value text or the value itself if no value text is provided. * * @param {string|number} value - The current value of the selector slider. * @returns {string} - The value text. */ function _getValueText(value) { var templates = _getValueTextTemplates.call(this); if (this.selectorSlider.value === this.selectorSlider.min && templates[Selector$b.MINTEXT]) { return Util$1.interpolateString(templates[Selector$b.MINTEXT], { value: value }); } if (this.selectorSlider.value === this.selectorSlider.max && templates[Selector$b.MAXTEXT]) { return Util$1.interpolateString(templates[Selector$b.MAXTEXT], { value: value }); } if (templates[Selector$b.VALUETEXT]) { return Util$1.interpolateString(templates[Selector$b.VALUETEXT], { value: value }); } return value; } /** * Returns an object containing the value text templates for the minimum, maximum, and value text. * * @returns {Object} - An object containing the value text templates. */ function _getValueTextTemplates() { var templates = {}; templates[Selector$b.VALUETEXT] = this.selectorSlider.dataset[Selector$b.VALUETEXT] || null; templates[Selector$b.MINTEXT] = this.selectorSlider.dataset[Selector$b.MINTEXT] || null; templates[Selector$b.MAXTEXT] = this.selectorSlider.dataset[Selector$b.MAXTEXT] || null; return templates; } /** * Handles changes to the value of the selector slider. * If a value is provided, this function updates the 'aria-valuetext' attribute * of the selector slider with the new value. It also creates and dispatches a * custom event to signal that the value of the selector slider has changed. * * @param {string|number} value - The new value of the selector slider. */ function _valueChanged(value, index) { if (value) { this.selectorSlider.setAttribute('aria-valuetext', _getValueText.call(this, value)); // Create and dispatch custom event to signal value change this[EventName$c.ON_SELECTOR_SLIDER_CHANGE] = new CustomEvent(EventName$c.ON_SELECTOR_SLIDER_CHANGE, { bubbles: true, detail: { value: value, index: index } }); this.selectorSlider.dispatchEvent(this[EventName$c.ON_SELECTOR_SLIDER_CHANGE]); } } /** * Creates a draggable pill element and appends it to the selector slider. * * @returns {Object} - An object containing the wrapper and span elements of the draggable pill. */ function _createDragPill() { var wrapper = document.createElement('div'); var span = document.createElement('span'); wrapper.classList.add(Selector$b.DRAG_PILL); wrapper.setAttribute('aria-hidden', 'true'); wrapper.append(span); this.selectorSlider.before(wrapper); return { wrapper: wrapper, span: span }; } /** * Updates the draggable pill based on the current value of the selector slider. * It sets the active class for the corresponding indicator, updates the text content of the draggable pill, * and adjusts its position. */ var _updateDragPill = debounce(200, function () { var _this = this; // set indicator active class var indicators = this.el.querySelectorAll("." + Selector$b.INDICATOR); var indicatorWrapper = this.el.querySelector("." + Selector$b.INDICATOR_WRAPPER); indicators.forEach(function (indicator, i) { if (i !== _this.selectorSlider.value - 1) { indicator.classList.remove('active'); } }); indicators[this.selectorSlider.value - 1].classList.add('active'); var ratio = (this.selectorSlider.value - this.selectorSlider.min) / (this.selectorSlider.max - this.selectorSlider.min); var thumbWidth = 64; // Shadow DOM var inputWidth = this.selectorSlider.offsetWidth; this.dragPill.span.textContent = this.stepValueList.children[this.selectorSlider.value - 1].innerHTML; _valueChanged.call(this, this.stepValueList.children[this.selectorSlider.value - 1].innerHTML, this.selectorSlider.value - 1); var spanWidth = this.dragPill.span.offsetWidth; var offset = ratio * (inputWidth - thumbWidth) - spanWidth / 2 + thumbWidth / 2; var direction = Util$1.isBiDirectional() ? 'right' : 'left'; this.dragPill.span.style[direction] = offset + "px"; indicatorWrapper.style.width = offset + thumbWidth + (ratio === 1 ? 0 : 4) + "px"; if (this.selectorSlider.hasAttribute('disabled')) { this.selectorSlider.parentElement.classList.add('disabled'); } else { this.selectorSlider.parentElement.classList.remove('disabled'); } }); /** * Creates slider indicators and appends them to the selector slider. * * @returns {HTMLElement} - The wrapper element containing the slider indicators. */ function _createSliderIndicators() { var wrapper = document.createElement('div'); wrapper.classList.add(Selector$b.INDICATOR_WRAPPER); wrapper.setAttribute('aria-hidden', 'true'); var sliderStop = (this.selectorSlider.max - this.selectorSlider.min) / this.selectorSlider.step; for (var i = 0; i < sliderStop + 1; i++) { var indicatorSpan = document.createElement('span'); indicatorSpan.classList.add(Selector$b.INDICATOR); wrapper.append(indicatorSpan); } this.selectorSlider.before(wrapper); return wrapper; } /** * Updates the positions of the slider indicators based on the current value of the selector slider. * It also calls the _updateDragPill function to update the draggable pill. */ function _updateSliderIndicators() { var sliderStop = (this.selectorSlider.max - this.selectorSlider.min) / this.selectorSlider.step; var indicators = this.el.querySelectorAll("." + Selector$b.INDICATOR); for (var i = 0; i < sliderStop + 1; i++) { var ratio = (i + 1 - this.selectorSlider.min) / (this.selectorSlider.max - this.selectorSlider.min); var thumbWidth = 24; // Shadow DOM var inputWidth = this.selectorSlider.offsetWidth; var indicatorWidth = 6; // 6px of indicator width var boundaryIndicatorOffset = 0; // move boundary indicators to the center of the thumb if (i === 0) { boundaryIndicatorOffset = 16; } else if (i === sliderStop) { boundaryIndicatorOffset = -16; } var offset = ratio * (inputWidth - thumbWidth) - indicatorWidth / 2 + thumbWidth / 2 + boundaryIndicatorOffset; var direction = Util$1.isBiDirectional() ? 'right' : 'left'; indicators[i].style[direction] = offset + "px"; } _updateDragPill.call(this); } /** * Constructor for the SelectorSlider class. * Initializes the SelectorSlider instance with the provided options and sets up event handlers. * * @param {Object} opts - The options for initializing the SelectorSlider instance. */ var SelectorSlider = /*#__PURE__*/function () { function SelectorSlider(opts) { this.el = opts.el; this.selectorSlider = opts.selectorSlider || this.el.querySelector(Selector$b.RANGE_SLIDER); this.stepValueList = opts.stepValueList || this.el.querySelector("#" + this.selectorSlider.id + "-step-values"); this.sliderIndicators = opts.sliderIndicators || _createSliderIndicators.call(this); this.onInput = opts.onInput || _updateDragPill.bind(this); this.dragPill = opts.dragPill || _createDragPill.call(this); this.updateSliderIndicators = opts.updateSliderIndicators || _updateSliderIndicators.bind(this); // Set drag pill count variable for setting the width of the slider in CSS this.el.style.setProperty(Selector$b.DRAG_PILL_COUNT, this.sliderIndicators.querySelectorAll("." + Selector$b.INDICATOR).length); if (this.dragPill) { // Perform initial DragPill setup this.updateSliderIndicators(); // Add dragPill event handlers this.selectorSliderEvents = { inputEvent: { el: this.el, type: EventName$c.ON_INPUT, handler: this.onInput }, changeEvent: { el: this.el, type: EventName$c.ON_CHANGE, handler: this.onInput }, // Required for iOS/VoiceOver windowEvent: { el: window, type: EventName$c.ON_RESIZE, handler: throttle(200, this.updateSliderIndicators) } }; var observer = new IntersectionObserver(this.updateSliderIndicators); observer.observe(this.el); Util$1.addEvents(Object.values(this.selectorSliderEvents)); } instances$8.push(this); } /** * Update the selector slider. * @param {Object} [opts] - The slider options. * @param {Function} [opts.onInput] - Function to override the slider input handler. * @param {Function} [opts.updateSliderIndicators] - Function that udpates the slider indicators. * @param {Function} [opts.updateSliderIndicators] - Function that udpates the slider drag pill. * @param {Object} [opts.dragPill] - Object containing references to two Nodes: the drag pill wrapper and span (text container). */ var _proto = SelectorSlider.prototype; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } // Only update the input event handler if the drag pill exists if (opts.onInput && this.dragPill) { Util$1.removeEvents(Object.values(this.selectorSliderEvents)); this.onInput = opts.onInput; this.selectorSliderEvents = { inputEvent: { el: this.el, type: EventName$c.ON_INPUT, handler: this.onInput }, changeEvent: { el: this.el, type: EventName$c.ON_CHANGE, handler: this.onInput }, // Required for iOS/VoiceOver windowEvent: { el: window, type: EventName$c.ON_RESIZE, handler: throttle(200, this.updateSliderIndicators) } }; Util$1.addEvents(Object.values(this.selectorSliderEvents)); } if (opts.selectorSlider) { this.selectorSlider = opts.selectorSlider; } if (opts.stepValueList) { this.stepValueList = opts.stepValueList; } if (opts.dragPill === null || opts.dragPill) { if (opts.dragPill === null) { // Remove the drag pill DOM node and event listeners this.dragPill.wrapper.remove(); Util$1.removeEvents(Object.values(this.selectorSliderEvents)); } this.dragPill = opts.dragPill; } if (opts.sliderIndicators === null || opts.sliderIndicators) { if (opts.sliderIndicators === null) { // Remove the drag pill DOM node and event listeners this.sliderIndicators.wrapper.remove(); Util$1.removeEvents(Object.values(this.selectorSliderEvents)); } this.sliderIndicators = opts.sliderIndicators; } if (this.dragPill) { // Min and max may have changed, perform drag pill setup again this.updateSliderIndicators(); } // Set the initial aria-valuetext _valueChanged.call(this); // Create and dispatch custom event this[EventName$c.ON_UPDATE] = new CustomEvent(EventName$c.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$c.ON_UPDATE]); } /** * Remove the slider. */; _proto.remove = function remove() { if (this.dragPill) { Util$1.removeEvents(Object.values(this.selectorSliderEvents)); } var index = instances$8.indexOf(this); instances$8.splice(index, 1); // Create and dispatch custom event this[EventName$c.ON_REMOVE] = new CustomEvent(EventName$c.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$c.ON_REMOVE]); }; SelectorSlider.getInstances = function getInstances() { return instances$8; }; return SelectorSlider; }(); var instances$7 = []; var Selector$a = { DATA_MOUNT: '[data-mount="card-stat"]', RANGE_SLIDER: '.selector-slider__input', DROPDOWN_RADIO_BTN: '.dropdown-bar .menu-list__list-item .ocr-input__input[type="radio"]', DROPDOWN_MENULIST_BTN: '.dropdown-bar .menu-list__item-radio', DROPDOWN_LABEL: '.dropdown-bar .button-dropdown-item--label', STAT: '.card-horizontal__content .block-feature__title' }; /** * JS event name. * @enum {string} */ var EventName$b = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', ON_SELECTOR_SLIDER_CHANGE: 'onSelectorSliderChange', ON_CHECKBOX_CHECKED: 'onCheckboxChecked', ON_CHECKBOX_UNCHECKED: 'onCheckboxUnchecked', ON_RADIO_BUTTON_SELECTED: 'radioButtonSelected', ON_CLICK: 'click', KEY_DOWN: 'keydown' }; /** * Element Attribute name. * @enum {string} */ var Attributes$5 = { LI_VALUE: 'value', ARIA_CHECKED: 'aria-checked', UNSELECTED_DISABLED: 'unselected-disabled' }; /** * String constants. * @enum {string} */ var Strings$1 = { EMPTY: '' }; /** * CSS classes. * @enum {string} */ var Classes$1 = { SELECTED: 'selected' }; /** * Constructor for the CardStat class. * Initializes the CardStat instance with the provided options and sets up event handlers. * * @param {Object} opts - The options for initializing the CardStat instance. */ var CardStat = /*#__PURE__*/function () { function CardStat(opts) { var _this = this; /** * Updates the stat. * Calculates the new stat value based on the slider value and the dropdown value, and updates the stat element's text. */ this.updateStat = debounce(200, function () { // check if the dropdown value has commar or not // if yes, get the stat value in the dropdown values with the index if (this.dropdownValue.includes(',')) { var dropdownValues = this.dropdownValue.split(','); this.statValue = parseInt(parseFloat(dropdownValues[this.selectorSliderIndex]), 10); } // else, calculate the stat value as the slider value * dropdown value else { this.statValue = parseInt(parseFloat(this.selectorSliderValue) * parseFloat(this.dropdownValue), 10); } this.statElement.innerHTML = this.statValue.toLocaleString() + " " + this.statSuffix; }); this.events = []; this.el = opts.el; this.selectorSlider = document.getElementById(this.el.dataset.selectorSliderId); this.dropdownRadioBtns = this.el.querySelectorAll(Selector$a.DROPDOWN_RADIO_BTN); this.dropdownMenulistBtns = this.el.querySelectorAll(Selector$a.DROPDOWN_MENULIST_BTN); this.statElement = this.el.querySelector(Selector$a.STAT); this.statValue = null; this.selectorSliderValue = null; this.selectorSliderIndex = null; this.dropdownValue = null; this.dropdownLabel = this.el.querySelector(Selector$a.DROPDOWN_LABEL); this.statSuffix = this.el.dataset.statSuffix; if (this.selectorSlider) { this.events.push({ el: this.selectorSlider, handler: this.getStatSliderValue.bind(this), type: EventName$b.ON_SELECTOR_SLIDER_CHANGE }); if (this.dropdownRadioBtns && this.dropdownRadioBtns.length > 0) { this.dropdownRadioBtns.forEach(function (radioButton) { _this.events.push({ el: radioButton, handler: _this.getStatRadioValue.bind(_this), type: EventName$b.ON_RADIO_BUTTON_SELECTED }); }); if (!this.dropdownValue) { this.initializeStat(); } } else if (this.dropdownMenulistBtns) { this.dropdownMenulistBtns.forEach(function (li) { li.setAttribute(Attributes$5.UNSELECTED_DISABLED, Strings$1.EMPTY); if (li.hasAttribute(Attributes$5.LI_VALUE)) { _this.events.push({ el: li, handler: _this.getStatMenulistItemValue.bind(_this), type: EventName$b.ON_CLICK }, { el: li, handler: _this.getStatMenulistItemValue.bind(_this), type: EventName$b.KEY_DOWN }); } }); if (!this.dropdownValue) { this.initializeStatWithMenuList(); } } } Util$1.addEvents(this.events); instances$7.push(this); } /** * Initializes the stat. * Sets the dropdown value to the first radio button's value, sets the dropdown label to the first radio button's label, * checks the first radio button, and sets the stat element to be an aria-live region. */ var _proto = CardStat.prototype; _proto.initializeStat = function initializeStat() { this.dropdownValue = this.dropdownRadioBtns[0].value; this.dropdownRadioBtns[0].checked = true; this.dropdownLabel.textContent = this.dropdownRadioBtns[0].nextElementSibling.textContent; this.updateStat(); } /** * Initializes the stat. * Sets the dropdown value to the first menu list item's value, sets the dropdown label to the first menu list item's label, * checks the first menu list item, and sets the stat element to be an aria-live region. */; _proto.initializeStatWithMenuList = function initializeStatWithMenuList() { this.dropdownValue = this.dropdownMenulistBtns[0].getAttribute(Attributes$5.LI_VALUE); this.dropdownMenulistBtns[0].setAttribute(Attributes$5.ARIA_CHECKED, 'true'); this.dropdownMenulistBtns[0].classList.add(Classes$1.SELECTED); this.dropdownLabel.textContent = this.dropdownMenulistBtns[0].textContent; this.updateStat(); } /** * Handles the change event of the slider. * Sets the slider value to the new value and updates the stat. * * @param {Event} event - The change event. */; _proto.getStatSliderValue = function getStatSliderValue(event) { this.selectorSliderValue = event.detail.value; this.selectorSliderIndex = event.detail.index; this.updateStat(); } /** * Handles the change event of the radio buttons. * Sets the dropdown value to the new value, sets the dropdown label to the label of the selected radio button, * and updates the stat. * * @param {Event} event - The change event. */; _proto.getStatRadioValue = function getStatRadioValue(event) { this.dropdownValue = event.detail; this.dropdownLabel.innerHTML = event.currentTarget.nextElementSibling.innerHTML; this.updateStat(); } /** * Handles the change event of the menu list items. * Sets the dropdown value to the new value, sets the dropdown label to the label of the selected menu list item, * and updates the stat. * * @param {Event} event - The change event. */; _proto.getStatMenulistItemValue = function getStatMenulistItemValue(event) { if (event.type === EventName$b.ON_CLICK) { event.currentTarget.focus(); this.dropdownValue = event.currentTarget.getAttribute(Attributes$5.LI_VALUE); this.dropdownLabel.textContent = event.currentTarget.textContent; this.updateStat(); } else if (event.type === EventName$b.KEY_DOWN) { event.currentTarget.focus(); if (event.keyCode === 13 || event.keyCode === 32) { this.dropdownValue = event.currentTarget.getAttribute(Attributes$5.LI_VALUE); this.dropdownLabel.textContent = event.currentTarget.textContent; this.updateStat(); } } }; /** * Dispatches the update event. */ _proto.update = function update() { this.el.dispatchEvent(CardStat[EventName$b.ON_UPDATE]); } /** * Removes the CardStat instance. * Removes the event handlers, removes the instance from the instances array, and dispatches the remove event. */; _proto.remove = function remove() { var index = this.constructor.getInstances().indexOf(this); Util$1.removeEvents(this.events); this.constructor.getInstances().splice(index, 1); this.el.dispatchEvent(CardStat[EventName$b.ON_REMOVE]); }; CardStat.getInstances = function getInstances() { return instances$7; }; return CardStat; }(); var tabs = []; var EventName$a = { HIDE: 'onHide', HIDDEN: 'onHidden', SHOW: 'onShow', SHOWN: 'onShown', CLICK_DATA_API: 'click', KEYDOWN_DATA_API: 'keydown', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', POP_STATE: 'popstate', FOCUS: 'focus', BLUR: 'blur', MOUSE_ENTER: 'mouseenter', MOUSE_LEAVE: 'mouseleave', RESIZE: 'resize' }; var Attribute$2 = { HIDDEN: 'hidden', SHARED_LABEL_CONTAINER: 'data-shared-label-container' }; var ClassName$6 = { DROPDOWN_MENU: 'dropdown-menu', ACTIVE: 'active', DISABLED: 'disabled', FADE: 'fade', SHOW: 'show' }; var Selector$9 = { NAV_LIST_GROUP: '.nav, .list-group, .tab-group', ACTIVE: '.active', ACTIVE_UL: 'li .active', DATA_MOUNT: '[data-mount="ocr-tabs"]', BACK_TO_TABS: '[data-focus="back-to-tabs"]', ROLE_TAB: '[role="tab"]', TAB_CONTENT: '.tab-content, .tab-panel-group', TAB_LABEL: '[data-tab-label]', UMP_VIDEO: 'universal-media-player', TAB_BADGES: '.tabs__slider.tabs--type-badge', CONTAINER: '.container' }; var DELAY_MS$3 = 100; // Private /** * Activate tab. * @param {HTMLElement} element - Tab element. * @param {HTMLElement} container - Tab container element. * @param {Function} callback - Function to run after transition ends. * @this OcrTab */ function _activate(element, container, callback) { var _this = this, _this$el$querySelecto; var activeElements; if (container && (container.nodeName === 'UL' || container.nodeName === 'OL')) { activeElements = container.querySelector(Selector$9.ACTIVE_UL); } else { // make sure that any selected tab panel .active element is a direct descendant of the tab panel container activeElements = [].slice.call(container.children).filter(function (e) { return e.classList.contains(ClassName$6.ACTIVE); }); } var active = activeElements[0]; var isTransitioning = callback && active && active.classList.contains(ClassName$6.FADE); var complete = function complete() { return _transitionComplete.call(_this, element, active, callback); }; if (active && isTransitioning) { var transitionDuration = Util$1.getTransitionDurationFromElement(active); active.classList.remove(ClassName$6.SHOW); active.addEventListener(Util$1.TRANSITION_END, complete, { once: true }); Util$1.emulateTransitionEnd(active, transitionDuration); } else { complete(); } _setSharedLabel(this.sharedLabelEl, (_this$el$querySelecto = this.el.querySelector(Selector$9.TAB_LABEL)) == null ? void 0 : _this$el$querySelecto.textContent); // Due to what appears to be a bug in MWF, active contains the active element for normal tabs // but activeElements contains the active element for list tabs. if (active) { _pauseVideos$1(active); } else { _pauseVideos$1(activeElements); } } function _getSharedLabelEl() { var targetSelector = this.listGroup.hasAttribute(Attribute$2.SHARED_LABEL_CONTAINER) && this.listGroup.dataset.sharedLabelContainer; var target; if (targetSelector) target = document.querySelector("#" + targetSelector); return target; } function _setSharedLabel(sharedLabel, input) { if (sharedLabel && input) { sharedLabel.textContent = input; } } /** * Pauses all videos playing in the tab. * @param {HTMLElement} tabElement - The element for the tab that is having its video paused. */ function _pauseVideos$1(tabElement) { var videos = tabElement.querySelectorAll(Selector$9.UMP_VIDEO); if (videos) { for (var _iterator = _createForOfIteratorHelperLoose(videos), _step; !(_step = _iterator()).done;) { var video = _step.value; video.pause(); } } } /** * Callback for completed tab transitions. * @param {HTMLElement} element - Newly selected tab element. * @param {HTMLElement} active - Previously active tab element. * @param {Function} callback - Function to run after transition ends. * @this OcrTab */ function _transitionComplete(element, active, callback) { if (active) { active.classList.remove(ClassName$6.ACTIVE); if (active.getAttribute('role') === 'tab') { active.setAttribute('aria-selected', 'false'); active.setAttribute('tabindex', '-1'); } else if (active.getAttribute('role') === 'tabpanel') { active.hidden = true; } } element.classList.add(ClassName$6.ACTIVE); if (element.getAttribute('role') === 'tab') { element.setAttribute('aria-selected', 'true'); element.setAttribute('tabindex', '0'); } else if (element.getAttribute('role') === 'tabpanel') { element.removeAttribute(Attribute$2.HIDDEN); // Scroll back to top of panel if necessary var activePanelTop = element.getBoundingClientRect().top; var documentElementNode = document.documentElement; var documentScrollPaddingTop = 0; if (documentElementNode.style.scrollPaddingTop) { documentScrollPaddingTop = parseInt(documentElementNode.style.scrollPaddingTop, 10); } if (activePanelTop < 0) { var scrollOffset = activePanelTop - documentElementNode.getBoundingClientRect().top - documentScrollPaddingTop; window.scrollTo(0, scrollOffset); } if (this.backToTabs && this.backToTabs instanceof HTMLAnchorElement) { var _this$backToTabs$focu; (_this$backToTabs$focu = this.backToTabs.focusControls) == null ? void 0 : _this$backToTabs$focu.remove(); this.backToTabs.href = "#" + element.id + "-tab"; this.backToTabs.focusControls = new Util$1.FocusControls({ el: this.backToTabs }); } } Util$1.reflow(element); if (element.classList.contains(ClassName$6.FADE)) { element.classList.add(ClassName$6.SHOW); } if (callback) { callback(); } } /** * Callback function for all key events on tabs. * Facilitates left <-> right focus movement between tabs recommended by W3C: https://www.w3.org/TR/wai-aria-practices-1.1/examples/tabs/tabs-2/tabs.html * @param {KeyboardEvent} event - Keyboard event. * @this OcrTab */ function _onKeycodeEvent(event) { var keycode = Util$1.getKeyCode(event); switch (keycode) { case Util$1.keyCodes.SPACE: case Util$1.keyCodes.ENTER: { event.preventDefault(); this.show(event); break; } case Util$1.keyCodes.HOME: { event.preventDefault(); this.listNodeList[0].focus(); break; } case Util$1.keyCodes.END: { event.preventDefault(); this.listNodeList[this.listNodeList.length - 1].focus(); break; } case Util$1.keyCodes.ARROW_LEFT: { // stop default "scroll" behavior in overflowed containers event.preventDefault(); if (this.isRTL) { _onKeycodeRight.call(this); } else { _onKeycodeLeft.call(this); } break; } case Util$1.keyCodes.ARROW_RIGHT: { // stop default "scroll" behavior in overflowed containers event.preventDefault(); if (this.isRTL) { _onKeycodeLeft.call(this); } else { _onKeycodeRight.call(this); } break; } } } /** * Callback function for arrow-left key. * @this OcrTab */ function _onKeycodeLeft() { var lastTab = this.listNodeList[this.listNodeList.length - 1]; var previousTab = this.listNodeList[this.tabIndex - 1]; if (this.tabIndex === 0) { return lastTab.focus(); } return previousTab.focus(); } /** * Callback function for arrow-right key. * @this OcrTab */ function _onKeycodeRight() { var firstTab = this.listNodeList[0]; var nextTab = this.listNodeList[this.tabIndex + 1]; if (this.tabIndex === this.listNodeList.length - 1) { return firstTab.focus(); } return nextTab.focus(); } function _onFocus() { var _this$el$querySelecto2; var input = (_this$el$querySelecto2 = this.el.querySelector(Selector$9.TAB_LABEL)) == null ? void 0 : _this$el$querySelecto2.textContent; if (this.sharedLabelEl && input) { _setSharedLabel(this.sharedLabelEl, input); } } function _onBlur() { var _this$listGroup, _this$listGroup$query, _this$listGroup$query2; // check if active tab has shared label input var input = (_this$listGroup = this.listGroup) == null ? void 0 : (_this$listGroup$query = _this$listGroup.querySelector(Selector$9.ACTIVE)) == null ? void 0 : (_this$listGroup$query2 = _this$listGroup$query.querySelector(Selector$9.TAB_LABEL)) == null ? void 0 : _this$listGroup$query2.textContent; if (this.sharedLabelEl && input) { _setSharedLabel(this.sharedLabelEl, input); } } function _onPopState() { var _this2 = this; var hash = window.location.hash; // Check if hash matches the id of the tab panel or a tab panel child and show. // If no hash assume the default Tab panel should be shown. if (hash) { if (hash === "#" + this.tabPanel.id) { this.show(); this.tabContent.addEventListener(Util$1.TRANSITION_END, function () { _this2.el.scrollIntoView(true); _this2.el.focus(); }, { once: true }); } else { var tabPanelChild = this.tabPanel.querySelector("[id=\"" + hash.slice(1) + "\"]"); if (tabPanelChild) { this.show(); this.tabContent.addEventListener(Util$1.TRANSITION_END, function () { tabPanelChild.scrollIntoView(true); tabPanelChild.focus(); }, { once: true }); } } } else if (this.tabIndex === this.defaultTabIndex) { this.show(); } } var OcrTab = /*#__PURE__*/function () { /** * Create an OcrTab instance * @param {Object} opts - Tab options. * @param {HTMLElement} opts.el - Tab element. * @param {(HTMLElement|null)} [opts.sharedLabelEl] - Element tabs will target for shared label variant. * @param {Boolean} [opts.addUrlToHistory=false] - Use pushState instead of replaceState, defaults to false. * @param {Number} [opts.defaultTabIndex=0] - Index of default tab in list group. Defaults to first tab with class active or 0. */ function OcrTab(_ref) { var el = _ref.el, _ref$sharedLabelEl = _ref.sharedLabelEl, sharedLabelEl = _ref$sharedLabelEl === void 0 ? null : _ref$sharedLabelEl, _ref$addUrlToHistory = _ref.addUrlToHistory, addUrlToHistory = _ref$addUrlToHistory === void 0 ? false : _ref$addUrlToHistory, _ref$defaultTabIndex = _ref.defaultTabIndex, defaultTabIndex = _ref$defaultTabIndex === void 0 ? 0 : _ref$defaultTabIndex; this.el = el; this.listGroup = this.el.closest(Selector$9.NAV_LIST_GROUP); this.targetSelector = Util$1.getSelectorFromElement(this.el); this.tabPanel = document.querySelector(this.targetSelector); this.tabContent = this.tabPanel.closest(Selector$9.TAB_CONTENT); this.isRTL = document.dir === 'rtl'; this.backToTabs = [].concat(Array.from(this.tabContent.children), Array.from(this.tabContent.parentNode.children)).find(function (el) { return el.dataset.focus === 'back-to-tabs'; }); this.sharedLabelEl = sharedLabelEl || _getSharedLabelEl.call(this); // set back to tab href to active tab's id if (this.el.classList.contains(ClassName$6.ACTIVE) && this.backToTabs && this.backToTabs instanceof HTMLAnchorElement) { this.backToTabs.href = "#" + this.el.id; this.backToTabs.focusControls = new Util$1.FocusControls({ el: this.backToTabs }); } // prevents error if tab is not within a list group if (this.listGroup) { this.listNodeList = this.listGroup.querySelectorAll(Selector$9.ROLE_TAB) || []; this.nodeListArray = [].slice.call(this.listNodeList); this.tabIndex = this.nodeListArray.indexOf(this.el); this.addUrlToHistory = addUrlToHistory || this.listGroup.dataset.addUrlToHistory !== undefined; var activeTab = this.listGroup.querySelector(Selector$9.ACTIVE); var activeIndex = this.nodeListArray.indexOf(activeTab) > -1 ? this.nodeListArray.indexOf(activeTab) : null; this.defaultTabIndex = defaultTabIndex || activeIndex || 0; } // enable deep linking _onPopState.call(this); if (this.sharedLabelEl && this.el.classList.contains(ClassName$6.ACTIVE)) { var _this$el$querySelecto3; _setSharedLabel(this.sharedLabelEl, (_this$el$querySelecto3 = this.el.querySelector(Selector$9.TAB_LABEL)) == null ? void 0 : _this$el$querySelecto3.textContent); } // attach event listeners this.events = [{ el: this.el, type: EventName$a.CLICK_DATA_API, handler: this.show.bind(this) }, { el: this.el, type: EventName$a.KEYDOWN_DATA_API, handler: _onKeycodeEvent.bind(this) }, { el: this.el, type: EventName$a.FOCUS, handler: _onFocus.bind(this) }, { el: this.el, type: EventName$a.MOUSE_ENTER, handler: _onFocus.bind(this) }, { el: this.el, type: EventName$a.MOUSE_LEAVE, handler: _onBlur.bind(this) }, { el: this.el, type: EventName$a.BLUR, handler: _onBlur.bind(this) }, { el: window, type: EventName$a.POP_STATE, handler: _onPopState.bind(this) }]; // tab badges resize dealing var tabBadges = this.el.closest(Selector$9.TAB_BADGES); if (tabBadges) { this.handleBadgeResize(); this.events.push({ el: window, type: EventName$a.RESIZE, handler: throttle(DELAY_MS$3, this.handleBadgeResize.bind(this)) }); } // add event listeners Util$1.addEvents(this.events); tabs.push(this); } // Public /** * Shows a tab panel based on the tab clicked and hides other panels. * @param {Event} [event] - Event trigger. * @this OcrTab */ var _proto = OcrTab.prototype; _proto.show = function show(event) { var _this3 = this; if (event) { event.preventDefault(); } var hasParentEl = this.el.parentNode && this.el.parentNode.nodeType === Node.ELEMENT_NODE; var isActive = this.el.classList.contains(ClassName$6.ACTIVE); var isDisabled = this.el.classList.contains(ClassName$6.DISABLED); if (hasParentEl && isActive || isDisabled) { return; } var target = this.tabPanel; var previous; var listElement = this.listGroup || this.el.closest(Selector$9.NAV_LIST_GROUP); if (listElement) { var isList = listElement.nodeName === 'UL' || listElement.nodeName === 'OL'; var itemSelector = isList ? Selector$9.ACTIVE_UL : Selector$9.ACTIVE; previous = this.el.parentNode.querySelector(itemSelector); } var hideEvent = new CustomEvent(EventName$a.HIDE, { detail: { relatedTarget: this.el } }); var showEvent = new CustomEvent(EventName$a.SHOW, { detail: { relatedTarget: previous } }); if (previous) { previous.dispatchEvent(hideEvent); } this.el.dispatchEvent(showEvent); if (showEvent.defaultPrevented || hideEvent.defaultPrevented) { return; } _activate.call(this, this.el, listElement); var complete = function complete() { var hiddenEvent = new CustomEvent(EventName$a.HIDDEN, { detail: { relatedTarget: _this3.el } }); var shownEvent = new CustomEvent(EventName$a.SHOWN, { detail: { relatedTarget: previous } }); if (previous) { previous.dispatchEvent(hiddenEvent); } _this3.el.dispatchEvent(shownEvent); var hash = window.location.hash; var url = "#" + _this3.tabPanel.id; var _document = document, title = _document.title; var state = window.history.state; var noHashAndNotOnDefaultTab = !hash && _this3.tabIndex !== _this3.defaultTabIndex; var notChild = hash && !_this3.tabPanel.querySelector(hash); var notSelf = hash !== url; if (noHashAndNotOnDefaultTab || notChild && notSelf) { if (_this3.addUrlToHistory) { window.history.pushState(state, title, url); } else { window.history.replaceState(state, title, url); } } }; if (target) { _activate.call(this, target, target.parentNode, complete); } else { complete(); } } /** * Handle resizing for Tabs * apply padding-inline depending on the window width */; _proto.handleBadgeResize = function handleBadgeResize() { var tabBadges = this.el.closest(Selector$9.TAB_BADGES); var container = this.el.closest(Selector$9.CONTAINER); if (!container || !tabBadges) { return; } var tabGroupWidth = this.listGroup.offsetWidth; var containerPaddingLeft = parseInt(window.getComputedStyle(container).paddingLeft, 10); var containerPaddingRight = parseInt(window.getComputedStyle(container).paddingRight, 10); var totalWidth = containerPaddingLeft + tabGroupWidth + containerPaddingRight; if (window.innerWidth - totalWidth >= 0) { // the tab group is not overflowing, no need to add padding tabBadges.style.paddingInlineStart = "0px"; } else { tabBadges.removeAttribute('style'); } } /** * Remove event handlers. * @this OcrTab */; _proto.remove = function remove() { Util$1.removeEvents(this.events); // remove this reference from array of instances var index = tabs.indexOf(this); tabs.splice(index, 1); // Create and dispatch custom event this[EventName$a.ON_REMOVE] = new CustomEvent(EventName$a.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$a.ON_REMOVE]); } /** * Update Tab * @param {Object} [opts] - Tab options. * @param {Boolean} [opts.addUrlToHistory] Use pushState instead of replaceState. * @param {(HTMLElement|null)} [opts.sharedLabelEl] Element tabs will target for shared label variant. */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } if (typeof opts.addUrlToHistory === 'boolean') { this.addUrlToHistory = opts.addUrlToHistory; } if (opts.sharedLabelEl !== undefined) { this.sharedLabelEl = opts.sharedLabelEl; } // Create and dispatch custom event this[EventName$a.ON_UPDATE] = new CustomEvent(EventName$a.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$a.ON_UPDATE]); } /** * Get instances. * @returns {OcrTab[]} Array of tab instances. */; OcrTab.getInstances = function getInstances() { return tabs; }; return OcrTab; }(); var Selector$8 = { DATA_MOUNT: '[data-mount="ocr-accordion"]', FEATURE: '.multi-feature-feature', ACCORDION: '.accordion', UMP_VIDEO: 'universal-media-player video' }; var EventName$9 = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; var ClassName$5 = { DISPLAY: { BLOCK: 'block', NONE: 'd-none' } }; var instances$6 = []; /** * Pause video when collapse is collapsed * @param {HTMLElement} collapse - The collapse element * */ function _pauseVideos(collapse) { var videos = collapse.querySelectorAll(Selector$8.UMP_VIDEO); if (videos) { for (var _iterator = _createForOfIteratorHelperLoose(videos), _step; !(_step = _iterator()).done;) { var video = _step.value; video.pause(); } } } // Set accordion height so it is never taller than the shortest feature function _setAccordionHeight() { var _this = this; if (this.inCustomViewport()) { // Wait for any images to load before calculating height imagesLoaded(this.el, function () { var maxAccordionHeight; var firstCollapseHeight; _this.collapses.forEach(function (c, i) { // Save current styles var display = c.el.style.display; var dNone = c.feature.classList.contains(ClassName$5.DISPLAY.NONE); // Set visible styles c.el.style.display = ClassName$5.DISPLAY.BLOCK; if (dNone) { c.feature.classList.remove(ClassName$5.DISPLAY.NONE); } // Calculate heights var featureHeight = c.feature.offsetHeight; if (!maxAccordionHeight || featureHeight < maxAccordionHeight) { maxAccordionHeight = featureHeight; } if (i === 0) { firstCollapseHeight = c.el.offsetHeight + c.triggerElement.offsetHeight; } // Reset styles to original state c.el.style.display = display; if (dNone) { c.feature.classList.add(ClassName$5.DISPLAY.NONE); } }); // set a min height equal to the height of the first collapse while open, plus a peek of the second collapse button _this.accordionElement.style.minHeight = firstCollapseHeight + 32 + "px"; if (maxAccordionHeight) { _this.accordionElement.style.height = maxAccordionHeight + "px"; _this.accordionElement.style.overflowY = 'auto'; } }); } else { this.accordionElement.style.minHeight = ''; this.accordionElement.style.height = ''; this.accordionElement.style.overflowY = ''; } } // Calculate height of absolute positioned content function _setMultiFeatureHeight() { var _this$open, _this$open$feature; var featureHeight = (_this$open = this.open) == null ? void 0 : (_this$open$feature = _this$open.feature) == null ? void 0 : _this$open$feature.offsetHeight; if (this.inCustomViewport() && featureHeight) { this.el.style.height = featureHeight + "px"; } else { this.el.style.height = ''; } } /** * @this {MultiFeature} */ function _onShown(collapse) { this.open = collapse; if (this.inCustomViewport()) { var _this$open$feature2; (_this$open$feature2 = this.open.feature) == null ? void 0 : _this$open$feature2.classList.remove(ClassName$5.DISPLAY.NONE); _setMultiFeatureHeight.call(this); } } /** * @this {MultiFeature} */ function _onHide(e) { var otherOpen = this.collapses.some(function (collapse) { var notTarget = collapse.el !== e.target; var open = !collapse.isCollapsed && !collapse.isTransitioning && notTarget; var transitioningOpen = collapse.isCollapsed && collapse.isTransitioning && notTarget; return open || transitioningOpen; }); if (otherOpen) { _pauseVideos(this.open.el); } if (this.inCustomViewport()) { if (otherOpen) { var _this$open$feature3; (_this$open$feature3 = this.open.feature) == null ? void 0 : _this$open$feature3.classList.add(ClassName$5.DISPLAY.NONE); } else { e.preventDefault(); } } else if (!otherOpen) { this.open = undefined; } } /** * @this {MultiFeature} */ function _onResize() { _setAccordionHeight.call(this); _setMultiFeatureHeight.call(this); if (this.inCustomViewport()) { if (!this.open && this.collapses.length) { this.collapses[0].toggle(); this.open = this.collapses[0]; } } else { this.collapses.forEach(function (collapse) { collapse.feature.classList.remove(ClassName$5.DISPLAY.NONE); }); } } function _generateEvents$1() { var _this2 = this; var events = [{ el: window, type: 'resize', handler: debounce(300, _onResize.bind(this)), options: { passive: true } }]; this.collapses.forEach(function (collapse) { events.push({ el: collapse.el, type: EventName$o.SHOWN, handler: function handler() { _onShown.call(_this2, collapse); } }, { el: collapse.el, type: EventName$o.HIDE, handler: function handler(e) { _onHide.call(_this2, e); } }); }); return events; } /** * @this {MultiFeature} */ function _setupCollapse(collapse) { collapse.feature = collapse.el.querySelector(Selector$8.FEATURE); collapse.parent = "#" + this.accordionElement.id; if (collapse.isCollapsed === false) { this.open = collapse; } } var OcrAccordion = /*#__PURE__*/function () { /** * Create a MultiFeature instance * @param {Object} opts - The multi feature options. * @param {HTMLElement} opts.el - The multi feature DOM node. * @param {HTMLElement} [opts.accordion] - The accordion DOM node. * @param {Collapse[]} [opts.collapses=[]] - The list of Collapse instances. * @param {Array} [opts.customViewports] - The list of viewports with custom accordion logic. */ function OcrAccordion(_ref) { var _this3 = this; var el = _ref.el, accordion = _ref.accordion, _ref$collapses = _ref.collapses, collapses = _ref$collapses === void 0 ? [] : _ref$collapses, customViewports = _ref.customViewports; this.el = el; this.accordionElement = accordion || this.el.querySelector(Selector$8.ACCORDION); this.collapses = collapses; this.customViewports = customViewports || ['lg', 'xl']; // Manual initialization with collapses option if (this.collapses.length) { // Set up each Collapse passed in as opts this.collapses.forEach(function (collapse) { _setupCollapse.call(_this3, collapse); }); // Auto initialization OR manual initialization without collapses } else { // Find all Collapse triggers and instances var collapseTriggers = this.el.querySelectorAll(Selector$q.DATA_MOUNT); var collapseInstances = CollapseExtension.getInstances(); // Get matching Collapses, set them up, and put them in the Collapse array collapseTriggers.forEach(function (el) { var collapseInstance = collapseInstances.find(function (collapse) { return collapse.triggerElement === el; }); _setupCollapse.call(_this3, collapseInstance); _this3.collapses.push(collapseInstance); }); } _setAccordionHeight.call(this); if (!this.open && this.collapses.length) { this.collapses[0].toggle(); this.open = this.collapses[0]; } this.events = _generateEvents$1.call(this); Util$1.addEvents(this.events); instances$6.push(this); } /** * Check if current viewport is in custom viewport list * @returns {Boolean} */ var _proto = OcrAccordion.prototype; _proto.inCustomViewport = function inCustomViewport() { var viewport = Util$1.detectViewport(); return this.customViewports.indexOf(viewport) > -1; } /** * Update instance. * @param {Object} opts - The multi feature options * @param {HTMLElement} [opts.accordionElement] - The accordion DOM node. * @param {Array} [opts.collapses] - The list of Collapse instances. * @param {Array} [opts.customViewports] - The list of viewports with custom accordion logic. */; _proto.update = function update(opts) { var _this4 = this; if (opts === void 0) { opts = {}; } // Remove event handlers Util$1.removeEvents(this.events); if (opts.accordionElement) { this.accordionElement = opts.accordionElement; } if (opts.customViewports) { this.customViewports = opts.customViewports; } if (opts.collapses) { this.open = null; this.collapses = opts.collapses; this.collapses.forEach(function (collapse) { _setupCollapse.call(_this4, collapse); }); } _setAccordionHeight.call(this); if (!this.open && this.collapses.length) { this.collapses[0].toggle(); this.open = this.collapses[0]; } // Add event handlers this.events = _generateEvents$1.call(this); Util$1.addEvents(this.events); // Trigger event this[EventName$9.ON_UPDATE] = new CustomEvent(EventName$9.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$9.ON_UPDATE]); } /** * Remove the multi feature. */; _proto.remove = function remove() { // Remove event handlers Util$1.removeEvents(this.events); // remove this multi feature reference from array of instances var index = instances$6.indexOf(this); instances$6.splice(index, 1); // Trigger event this[EventName$9.ON_REMOVE] = new CustomEvent(EventName$9.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$9.ON_REMOVE]); } /** * Get an array of multi feature instances. * @returns {Object[]} Array of multi feature instances. */; OcrAccordion.getInstances = function getInstances() { return instances$6; }; return OcrAccordion; }(); var instances$5 = []; /** * HTML Attributes. * @enum {string} */ var Attributes$4 = { ARIA_LABEL: 'aria-label', ARIA_LIVE: 'aria-live', ARIA_EXPANDED: 'aria-expanded', ARIA_CONTROLS: 'aria-controls', ID: 'id', TABINDEX: 'tabindex', DATA_EXPANDED_ARIA_LABEL: 'data-expanded-aria-label', DATA_COLLAPSED_ARIA_LABEL: 'data-collapsed-aria-label', DATA_MULTI_CARD_LAYOUT: 'data-multi-card-layout' }; /** * CSS Classes. * @enum {string} */ var ClassName$4 = { D_NONE: 'd-none', POSITION_ABSOLUTE: 'position-absolute', POSITION_RELATIVE: 'position-relative', WIDTH_100: 'w-100', INVISIBLE: 'invisible', GLYPH_ADD: 'glyph-append-add', GLYPH_REMOVE: 'glyph-append-remove' }; /** * JS event name. * @enum {string} */ var EventName$8 = { CLICK: 'click', RESIZE: 'resize', ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; /** * CSS selector. * @enum {string} */ var Selector$7 = { DATA_MOUNT: '[data-mount="card-interactive"]', BLOCK_FEATURE_PARAGRAPH: '.block-feature__paragraph', BLOCK_FEATURE_TITLE: '.block-feature__title', BLOCK_FEATURE_EYEBROW: '.block-feature__eyebrow', INTERACTIVE_BTN_WRAPPER: '.card__interactive-btn-wrapper', INTERACTIVE_BTN: '.interactive-btn', GLYPH_SPAN: '.glyph-append', GROUPED_CARD_CONTAINER: '.grouped-card-container', // Selector for the cards container, will be a different component FEATURED_CARDS: '.featured-cards' // Selector for the parent component, when used within the featured cards component }; var DELAY_MS$2 = 500; var CardInteractive = /*#__PURE__*/function () { /** * Initializes a new instance of the Card Interactive Feature. * @param {{ el: HTMLElement }} opts Initialization options. */ function CardInteractive(opts) { /** * Root element. * @type {HTMLElement} */ this.el = void 0; /** * Event bindings. * @type {{ el: Element, handler: (...args: unknown[]) => unknown, type: string}[]} */ this.events = []; /** * Observers. * @type {(ResizeObserver | IntersectionObserver | MutationObserver)[]} */ this.observers = []; /** * Only for Multi Card Layout, if the card is part of a grouped card container. * @type {HTMLElement | null} */ this.groupedCardContainer = void 0; /** * Only for Multi Card Layout, an array of all cards. * @type {Node[] | null} */ this.cards = void 0; this.el = opts.el; this.isMultiCardLayout = this.el.getAttribute(Attributes$4.DATA_MULTI_CARD_LAYOUT) === 'true'; this.isCardExpanded = false; this.disableInteractiveFeatureInMobile = false; this.isInteractiveFeatureDisabledInMobile(); this.isDesktop = window.matchMedia("(min-width: " + ViewPort.MD + "px)"); this.isInitialized = false; /** * The content that will be shown/hidden. */ this.toggleableContent = this.el.querySelector(Selector$7.BLOCK_FEATURE_PARAGRAPH); this.blockFeatureTitle = this.el.querySelector(Selector$7.BLOCK_FEATURE_TITLE); this.blockFeatureEyebrow = this.el.querySelector(Selector$7.BLOCK_FEATURE_EYEBROW); this.interactiveBtnWrapper = this.el.querySelector(Selector$7.INTERACTIVE_BTN_WRAPPER); /** * The button that will toggle the content. */ this.interactiveBtn = this.el.querySelector(Selector$7.INTERACTIVE_BTN); if (this.interactiveBtn && this.toggleableContent) { this.btnCollapsedAriaLabel = this.interactiveBtn.getAttribute(Attributes$4.DATA_COLLAPSED_ARIA_LABEL); this.btnExpandedAriaLabel = this.interactiveBtn.getAttribute(Attributes$4.DATA_EXPANDED_ARIA_LABEL); this.glyphSpan = this.interactiveBtn.querySelector(Selector$7.GLYPH_SPAN); this.initObservers(); this.events.push({ el: this.interactiveBtn, type: EventName$8.CLICK, handler: this.toggleInteractive.bind(this) }, { el: document.defaultView, handler: debounce(DELAY_MS$2, this.handleResize.bind(this)), type: EventName$8.RESIZE }); } if (this.events.length) { Util$1.addEvents(this.events); } this.isIntersecting = false; var observer = new IntersectionObserver(this.handleIntersection.bind(this)); observer.observe(this.el); instances$5.push(this); } /** * Initialize observers. * @returns {void} * */ var _proto = CardInteractive.prototype; _proto.initObservers = function initObservers() { var _this = this; // Add a mutation observer to the interactive button to look for aria-expanded attribute changes var interactiveBtnMutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === Attributes$4.ARIA_EXPANDED) { var target = mutation.target; _this.updateCardStatus(target); } }); }); // add muitation observer to the interactive button interactiveBtnMutationObserver.observe(this.interactiveBtn, { attributes: true }); this.observers.push(interactiveBtnMutationObserver); } /** * Initialize the interactive layout. */; _proto.init = function init() { if (this.isInitialized || !this.isDesktop.matches && this.disableInteractiveFeatureInMobile) return; this.isInitialized = true; // Generate a unique ID for ARIA controls var id = this.generateUniqueId('ocr-bf-interactive-'); if (this.isMultiCardLayout) { this.initMultiCardLayout(); } // Initialize layout heights and visibility for interactive elements this.toggleableContentHeight = this.toggleableContent.offsetHeight; this.interactiveBtnWrapper.classList.remove(ClassName$4.D_NONE); this.expandedCardHeight = this.el.offsetHeight; this.toggleableContent.classList.add(ClassName$4.D_NONE); this.collapsedCardHeight = this.el.offsetHeight; this.el.style.height = this.collapsedCardHeight + "px"; if (this.blockFeatureTitle) { this.blockFeatureTitleHeight = this.blockFeatureTitle.offsetHeight; } if (this.blockFeatureEyebrow) { this.blockFeatureEyebrowHeight = this.blockFeatureEyebrow.offsetHeight; } // Make the interactive button visible and set ARIA attributes for accessibility this.toggleableContent.parentElement.setAttribute(Attributes$4.ARIA_LIVE, 'polite'); this.toggleableContent.parentElement.setAttribute(Attributes$4.ID, id); this.interactiveBtn.setAttribute(Attributes$4.ARIA_CONTROLS, id); } /** * Initialize the multi card layout. * @returns {void} * */; _proto.initMultiCardLayout = function initMultiCardLayout() { // get the closest parent container which is the grouped card container this.groupedCardContainer = this.el.closest(Selector$7.GROUPED_CARD_CONTAINER); if (this.groupedCardContainer) { // get all cards in the grouped card container this.cards = this.groupedCardContainer.querySelectorAll(Selector$7.DATA_MOUNT); // loop through all cards and find toggleable content & interactive button this.cards.forEach(function (card) { var toggleableContent = card.querySelector(Selector$7.BLOCK_FEATURE_PARAGRAPH); if (toggleableContent) { toggleableContent.classList.add(ClassName$4.D_NONE); } var interactiveBtnWrapper = card.querySelector(Selector$7.INTERACTIVE_BTN_WRAPPER); if (interactiveBtnWrapper) { interactiveBtnWrapper.classList.remove(ClassName$4.D_NONE); } }); } // remove the d-none class to get the height of the content. Applicable for multi card layout if (this.toggleableContent.classList.contains(ClassName$4.D_NONE)) { this.toggleableContent.classList.remove(ClassName$4.D_NONE); } } /** * Check if the interactive feature needs to be disabled in mobile. * This is used to disable the interactive feature in mobile for certain components. * @returns {void} * */; _proto.isInteractiveFeatureDisabledInMobile = function isInteractiveFeatureDisabledInMobile() { if (this.el.closest(Selector$7.FEATURED_CARDS)) { this.disableInteractiveFeatureInMobile = true; } } /** * Update the card status. * @param {HTMLElement} target The target element. * @returns {void} * */; _proto.updateCardStatus = function updateCardStatus(target) { this.isCardExpanded = target.getAttribute(Attributes$4.ARIA_EXPANDED) === 'true'; } /** * Toggle the interactive feature. */; _proto.toggleInteractive = function toggleInteractive() { var _this2 = this; var isExpanded = this.toggleableContent.classList.contains(ClassName$4.D_NONE); var targetHeight = isExpanded ? this.expandedCardHeight : this.collapsedCardHeight; var ariaExpanded = isExpanded ? 'true' : 'false'; var ariaLabel = isExpanded ? this.btnExpandedAriaLabel : this.btnCollapsedAriaLabel; var glyphToRemove = isExpanded ? ClassName$4.GLYPH_ADD : ClassName$4.GLYPH_REMOVE; var glyphToAdd = isExpanded ? ClassName$4.GLYPH_REMOVE : ClassName$4.GLYPH_ADD; if (this.isMultiCardLayout && isExpanded) { this.collapseOtherExpandedCards(isExpanded); } // Set initial styles and attributes this.el.style.height = targetHeight + "px"; this.interactiveBtn.setAttribute(Attributes$4.ARIA_EXPANDED, ariaExpanded); this.interactiveBtn.setAttribute(Attributes$4.ARIA_LABEL, ariaLabel); this.glyphSpan.classList.remove(glyphToRemove); this.glyphSpan.classList.add(glyphToAdd); if (!isExpanded) { this.toggleableContent.classList.add(ClassName$4.D_NONE); } setTimeout(function () { // Toggle visibility of content _this2.toggleableContent.classList.toggle(ClassName$4.D_NONE, !isExpanded); if (!_this2.isMultiCardLayout) { _this2.el.style.height = 'unset'; // Recalculate and set the height based on current state var newHeight = _this2.el.offsetHeight; _this2.el.style.height = newHeight + "px"; // Update height properties to reflect the new state if (isExpanded) { _this2.expandedCardHeight = newHeight; } else { _this2.collapsedCardHeight = newHeight; } } }, DELAY_MS$2); } /** * Initializes and sizes cards as they come into view. * This is because all height calculations require the card to not be hidden. * @param {IntersectionObserverEntry[]} entries Array of entries observed by the IntersectionObserver. */; _proto.handleIntersection = function handleIntersection(entries) { var _this3 = this; entries.forEach(function (entry) { if (!entry.isIntersecting) { _this3.isIntersecting = false; return; } _this3.isIntersecting = true; _this3.init(); _this3.handleResize(); }); } /** * Handle the resize event. */; _proto.handleResize = function handleResize() { if (!this.isIntersecting) return; if (!this.isDesktop.matches && this.disableInteractiveFeatureInMobile) { this.unsetCardHeight(); } else { this.init(); var newHeight = this.getNewCardHeight(); this.collapsedCardHeight = newHeight.collapsedHeight; this.expandedCardHeight = newHeight.expandedHeight; this.el.style.height = (this.isCardExpanded ? this.expandedCardHeight : this.collapsedCardHeight) + "px"; this.setExpandedCardHeightDataset(); } } /** * Get the new card height after the resize event. * @returns {Object} The new card height. * */; _proto.getNewCardHeight = function getNewCardHeight() { var _this$blockFeatureTit, _this$blockFeatureEye; this.el.style.height = 'unset'; var expandedHeight = this.expandedCardHeight; var previousToggleableContentHeight = this.toggleableContentHeight; var previousBlockFeatureTitleHeight = (_this$blockFeatureTit = this.blockFeatureTitleHeight) != null ? _this$blockFeatureTit : 0; var previousBlockFeatureEyebrowHeight = (_this$blockFeatureEye = this.blockFeatureEyebrowHeight) != null ? _this$blockFeatureEye : 0; if (this.isCardExpanded) { this.toggleableContent.classList.add(ClassName$4.D_NONE); } var collapsedHeight = this.el.offsetHeight; if (this.isCardExpanded) { this.toggleableContent.classList.remove(ClassName$4.D_NONE); } this.blockFeatureTitleHeight = this.blockFeatureTitle ? this.blockFeatureTitle.offsetHeight : 0; this.blockFeatureEyebrowHeight = this.blockFeatureEyebrow ? this.blockFeatureEyebrow.offsetHeight : 0; if (this.isMultiCardLayout) { var largestTitleHeight = 0; var largestEyebrowHeight = 0; this.cards.forEach(function (card) { var blockFeatureTitle = card.querySelector(Selector$7.BLOCK_FEATURE_TITLE); var blockFeatureEyebrow = card.querySelector(Selector$7.BLOCK_FEATURE_EYEBROW); if (blockFeatureTitle) { largestTitleHeight = Math.max(largestTitleHeight, blockFeatureTitle.offsetHeight); } if (blockFeatureEyebrow) { largestEyebrowHeight = Math.max(largestEyebrowHeight, blockFeatureEyebrow.offsetHeight); } }); if (largestTitleHeight > 0) { collapsedHeight = collapsedHeight - this.blockFeatureTitleHeight + largestTitleHeight; } if (largestEyebrowHeight > 0) { collapsedHeight = collapsedHeight - this.blockFeatureEyebrowHeight + largestEyebrowHeight; } } if (!this.isCardExpanded && this.toggleableContent.classList.contains(ClassName$4.D_NONE)) { // Temporarily make the content visible but not affecting the layout to measure its height this.makeContentVisibleButNotAffectingLayout(); // Update the toggleable content height with the new measurement this.toggleableContentHeight = this.toggleableContent.offsetHeight; // Revert the content to its original hidden state this.revertContentToOriginalState(); // Recalculate the expanded height based on the new content height // Need to be calculated separately for each card in the grouped card container // to account for different content heights. Exapnded state deosn't affect the height of the other cards // so we need to calculate the height of the card based on the content of the card expandedHeight = expandedHeight - previousToggleableContentHeight + this.toggleableContentHeight; expandedHeight = expandedHeight - previousBlockFeatureTitleHeight + this.blockFeatureTitleHeight; expandedHeight = expandedHeight - previousBlockFeatureEyebrowHeight + this.blockFeatureEyebrowHeight; } else { this.toggleableContentHeight = this.toggleableContent.offsetHeight; expandedHeight = this.el.offsetHeight; } return { collapsedHeight: collapsedHeight, expandedHeight: expandedHeight }; } /** * Collapse other expanded cards in the grouped card container. * @param {boolean} isExpanded The current state of the card. * @returns {void} * */; _proto.collapseOtherExpandedCards = function collapseOtherExpandedCards(isExpanded) { var _this4 = this; if (isExpanded) { var expandedBtn = this.groupedCardContainer.querySelector("[" + Attributes$4.ARIA_EXPANDED + "=\"true\"]"); if (expandedBtn) { var expandedCard = expandedBtn.closest(Selector$7.DATA_MOUNT); if (expandedCard) { var toggleableContent = expandedCard.querySelector(Selector$7.BLOCK_FEATURE_PARAGRAPH); if (toggleableContent) { var glyphSpan = expandedBtn.querySelector(Selector$7.GLYPH_SPAN); // Set initial styles and attributes expandedBtn.setAttribute(Attributes$4.ARIA_EXPANDED, 'false'); expandedBtn.setAttribute(Attributes$4.ARIA_LABEL, this.btnCollapsedAriaLabel); glyphSpan.classList.remove(ClassName$4.GLYPH_REMOVE); glyphSpan.classList.add(ClassName$4.GLYPH_ADD); expandedCard.style.height = this.collapsedCardHeight + "px"; toggleableContent.classList.add(ClassName$4.D_NONE); } } } } this.cards.forEach(function (card) { var toggleableContent = card.querySelector(Selector$7.BLOCK_FEATURE_PARAGRAPH); if (toggleableContent && !toggleableContent.classList.contains(ClassName$4.D_NONE)) { var interactiveBtn = card.querySelector(Selector$7.INTERACTIVE_BTN); var _glyphSpan = interactiveBtn.querySelector(Selector$7.GLYPH_SPAN); var glyphToRemove = ClassName$4.GLYPH_ADD; var glyphToAdd = ClassName$4.GLYPH_REMOVE; // Set initial styles and attributes interactiveBtn.setAttribute(Attributes$4.ARIA_EXPANDED, 'false'); interactiveBtn.setAttribute(Attributes$4.ARIA_LABEL, _this4.btnCollapsedAriaLabel); _glyphSpan.classList.remove(glyphToRemove); _glyphSpan.classList.add(glyphToAdd); toggleableContent.classList.add(ClassName$4.D_NONE); } }); } /** * Unset the card height. * @returns {void} * */; _proto.unsetCardHeight = function unsetCardHeight() { this.el.style.height = 'unset'; } /** * Make the content visible but not affecting layout. * This is used to calculate the height of the card when the content is expanded. * The content is then reverted to its original state. * @returns {void} * */; _proto.makeContentVisibleButNotAffectingLayout = function makeContentVisibleButNotAffectingLayout() { this.toggleableContent.parentElement.classList.add(ClassName$4.POSITION_RELATIVE); this.toggleableContent.parentElement.classList.add(ClassName$4.WIDTH_100); this.toggleableContent.classList.add(ClassName$4.POSITION_ABSOLUTE, ClassName$4.INVISIBLE); this.toggleableContent.classList.remove(ClassName$4.D_NONE); } /** * Revert the content to its original state. * @returns {void} * */; _proto.revertContentToOriginalState = function revertContentToOriginalState() { this.toggleableContent.parentElement.classList.remove(ClassName$4.POSITION_RELATIVE); this.toggleableContent.parentElement.classList.remove(ClassName$4.WIDTH_100); this.toggleableContent.classList.add(ClassName$4.D_NONE); this.toggleableContent.classList.remove(ClassName$4.POSITION_ABSOLUTE, ClassName$4.INVISIBLE); } /** * Update the card height. * @param {number} newHeight The new height of the card. * @returns {void} * */; _proto.updateCardHeight = function updateCardHeight(newHeight) { this.el.style.height = 'unset'; newHeight = this.el.offsetHeight; this.el.style.height = newHeight + "px"; } /** * Set the data-expanded-card-height attribute. * DO NOT CALL THIS FUNCTION FROM init(). USE handleResize() INSTEAD. * handleResize() is called on page load from handleIntersection() and on resize event. * @returns {void} * */; _proto.setExpandedCardHeightDataset = function setExpandedCardHeightDataset() { this.el.dataset.expandedCardHeight = this.expandedCardHeight; } /** * Generate an ID. * @param {string} prefix The prefix to use. * @returns {string} The generated ID. */; _proto.generateUniqueId = function generateUniqueId(prefix) { if (prefix === void 0) { prefix = 'ocr-'; } var generateId = function generateId() { return "" + prefix + Math.random().toString(36).slice(2, 11); }; var id = generateId(); var attempts = 0; var maxAttempts = 20; // Loop to ensure the generated ID is unique by checking if it already exists in the DOM while (document.getElementById(id) && attempts < maxAttempts) { id = generateId(); // Generate a new ID if the previous one exists attempts++; } return id; } /** * Update the instance. * Not currently used, but required by API standards. */; _proto.update = function update() { this.el.dispatchEvent(this[EventName$8.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { Util$1.removeEvents(this.events); // Remove this reference from the array of instances. var index = instances$5.indexOf(this); instances$5.splice(index, 1); // Create and dispatch custom event this[EventName$8.ON_REMOVE] = new CustomEvent(EventName$8.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$8.ON_REMOVE]); } /** * Get Card Interactive instances. * @returns {Card[]} An array of Card Interactive instances */; CardInteractive.getInstances = function getInstances() { return instances$5; }; return CardInteractive; }(); /** Card Interactive END */ var instances$4 = []; /** * HTML Attributes. * @enum {string} */ var Attributes$3 = { ARIA_EXPANDED: 'aria-expanded', DATA_EXPANDED_CARD_HEIGHT: 'data-expanded-card-height' }; /** * CSS Classes. * @enum {string} */ var ClassName$3 = { D_NONE: 'd-none' }; /** * JS event name. * @enum {string} */ var EventName$7 = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', RESIZE: 'resize' }; /** * CSS selector. * @enum {string} */ var Selector$6 = { DATA_MOUNT: '[data-mount="featured-cards-interactive"]', FEATURED_CARDS: '.featured-cards', INTERACTIVE_BTN: '.interactive-btn', CARD_MEDIA: '.featured-cards__card-media', FEATURED_CARDS_CONTAINER: '.featured-cards__cards', CARD_INTERACTIVE: '[data-mount="card-interactive"]', FEATURED_CARDS_DEFAULT_MEDIA: '.featured-cards__default-media' }; var DELAY_MS$1 = 500; var FeaturedCardsInteractive = /*#__PURE__*/function () { /** * Initializes a new instance of the Featured Cards Interactive Feature. * @param {{ el: HTMLElement }} opts Initialization options. */ function FeaturedCardsInteractive(opts) { /** * Root element. * @type {HTMLElement} */ this.el = void 0; /** * Event bindings. * @type {{ el: Element, handler: (...args: unknown[]) => unknown, type: string}[]} */ this.events = []; /** * Observers. * @type {(ResizeObserver | IntersectionObserver | MutationObserver)[]} */ this.observers = []; this.el = opts.el; this.isDesktop = window.matchMedia("(min-width: " + ViewPort.MD + "px)"); this.isLargeDesktop = window.matchMedia("(min-width: " + ViewPort.XL + "px)"); /** * The list of buttons that will toggle the content. */ this.interactiveBtnList = this.el.querySelectorAll(Selector$6.INTERACTIVE_BTN); this.cardMediaList = this.el.querySelectorAll(Selector$6.CARD_MEDIA); this.cardsContainer = this.el.querySelector(Selector$6.FEATURED_CARDS_CONTAINER); this.interactiveCards = this.el.querySelectorAll(Selector$6.CARD_INTERACTIVE); this.cardsCount = this.interactiveCards.length; this.cardCounter = 0; this.currentHeight = 0; this.timeoutId = null; this.featuredCardsDefaultMedia = this.el.querySelector(Selector$6.FEATURED_CARDS_DEFAULT_MEDIA); this.featuredCardsDefaultMediaImgElem = this.featuredCardsDefaultMedia ? this.featuredCardsDefaultMedia.querySelector('img') : null; this.initObservers(); this.init(); this.events.push({ el: document.defaultView, handler: debounce(DELAY_MS$1, this.handleResize.bind(this)), type: EventName$7.RESIZE }); instances$4.push(this); if (this.events.length) { Util$1.addEvents(this.events); } } /** * Initialize observers. * @returns {void} * */ var _proto = FeaturedCardsInteractive.prototype; _proto.initObservers = function initObservers() { var _this = this; // Add a mutation observer to all the interactive buttons to look for aria-expanded attribute changes var interactiveBtnMutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === Attributes$3.ARIA_EXPANDED) { var target = mutation.target; _this.updateImage(target); } }); }); // add mutation observer to each of the interactive button this.interactiveBtnList.forEach(function (btn) { interactiveBtnMutationObserver.observe(btn, { attributes: true }); _this.observers.push(interactiveBtnMutationObserver); }); // Add a mutation observer to all the interactive cards to look for data-expanded-card-height attribute changes var interactiveCardsMutationObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { if (mutation.attributeName === Attributes$3.DATA_EXPANDED_CARD_HEIGHT) { var target = mutation.target; _this.setTheHeightOfDefaultImage(target); } }); }); // add mutation observer to each of the interactive cards this.interactiveCards.forEach(function (card) { interactiveCardsMutationObserver.observe(card, { attributes: true }); _this.observers.push(interactiveCardsMutationObserver); }); } /** * Initialize the layout. * @returns {void} * */; _proto.init = function init() { var _this2 = this; // Set the padding of the parent container to 0 this.el.closest(Selector$6.FEATURED_CARDS).style.padding = '0'; if (this.cardsContainer) { // Wait for the cards to get initialized and then align them to the bottom setTimeout(function () { _this2.setCardContainerFlexLayout(); }, 1000); } } /** * Update the image based on the aria-expanded attribute * @param {HTMLElement} target The target element * @returns {void} * */; _proto.updateImage = function updateImage(target) { var isExpanded = target.getAttribute(Attributes$3.ARIA_EXPANDED) === 'true'; // get the index of the button that was clicked var index = Array.from(this.interactiveBtnList).indexOf(target); if (!this.featuredCardsDefaultMediaImgElem || !this.cardMediaList[index]) return; // hide or show the image based on the aria-expanded attribute if (isExpanded) { this.cardMediaList[index].classList.remove(ClassName$3.D_NONE); this.featuredCardsDefaultMedia.style.opacity = 0; } else { this.cardMediaList[index].classList.add(ClassName$3.D_NONE); this.featuredCardsDefaultMedia.style.opacity = 1; } } /** * Handle the resize event. */; _proto.handleResize = function handleResize() { this.setCardContainerFlexLayout(); this.updateDefaultImageOnMobile(); } /** * Set the flex layout of the card container based on the screen size. */; _proto.setCardContainerFlexLayout = function setCardContainerFlexLayout() { if (!this.cardsContainer) return; if (this.isDesktop.matches) { this.cardsContainer.style.alignItems = 'flex-end'; } else { this.cardsContainer.style.alignItems = 'unset'; } } /** * Reset the opacity & height of default image on mobile. */; _proto.updateDefaultImageOnMobile = function updateDefaultImageOnMobile() { if (!this.featuredCardsDefaultMediaImgElem) return; if (!this.isDesktop.matches) { this.featuredCardsDefaultMedia.style.opacity = 1; this.featuredCardsDefaultMediaImgElem.style.height = 'auto'; } } /** * Set the height of the default image based on the expanded card height * @returns {void} * */; _proto.setTheHeightOfDefaultImage = function setTheHeightOfDefaultImage(target) { var _this3 = this; // provided by design team, this will make sure there is enough space above the expanded card var imageSafePadding = this.isLargeDesktop.matches ? 400 : 300; this.cardCounter++; // if the cardCounter is 1, set a timeout to reset the card counter and current height // mostly to handle any unexpected behavior, in case the obesrver doesn't run for all the interactive cards // the conditon `this.cardCounter === this.cardsCount` will never execute, if the observer doesn't run for all the interactive cards if (this.cardCounter === 1) { this.timeoutId = setTimeout(function () { _this3.cardCounter = 0; _this3.currentHeight = 0; }, 5000); } if (this.featuredCardsDefaultMediaImgElem) { var expandedCardHeight = parseInt(target.getAttribute(Attributes$3.DATA_EXPANDED_CARD_HEIGHT), 10); if (expandedCardHeight && expandedCardHeight > this.currentHeight) { this.currentHeight = expandedCardHeight; } } // update the height of the default image, once all the interactive cards have been observed if (this.cardCounter === this.cardsCount) { this.featuredCardsDefaultMediaImgElem.style.height = this.currentHeight + imageSafePadding + "px"; this.cardCounter = 0; this.currentHeight = 0; clearTimeout(this.timeoutId); } } /** * Update the instance. * Not currently used, but required by API standards. */; _proto.update = function update() { this.el.dispatchEvent(this[EventName$7.ON_UPDATE]); } /** * Remove the instance */; _proto.remove = function remove() { Util$1.removeEvents(this.events); // Remove this reference from the array of instances. var index = instances$4.indexOf(this); instances$4.splice(index, 1); // Create and dispatch custom event this[EventName$7.ON_REMOVE] = new CustomEvent(EventName$7.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$7.ON_REMOVE]); } /** * Get Featured Card instances. * @returns {Card[]} An array of Card Interactive instances */; FeaturedCardsInteractive.getInstances = function getInstances() { return instances$4; }; return FeaturedCardsInteractive; }(); /** Featured Card Interactive END */ var $ = _export; var createHTML = createHtml; var forcedStringHTMLMethod = stringHtmlForced; // `String.prototype.link` method // https://tc39.es/ecma262/#sec-string.prototype.link $({ target: 'String', proto: true, forced: forcedStringHTMLMethod('link') }, { link: function link(url) { return createHTML(this, 'a', 'href', url); } }); var instances$3 = []; var Selector$5 = { DATA_MOUNT: '[data-mount="clipboard-share"]', LINK: '.link', LINK_TEXT: '.link__text', ICON: '.ocr-icon .glyph-prepend' }; /** * JS event name. * @enum {string} */ var EventName$6 = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate', ON_CLICK: 'click', ON_KEYDOWN: 'keydown' }; /** * Element Attribute name. * @enum {string} */ var Attributes$2 = { ROLE: 'role' }; /** * CSS classes. * @enum {string} */ var Classes = { INITIAL_GLYPH: 'glyph-prepend-copy', COPIED_GLYPH: 'glyph-prepend-check-mark' }; /** * Constructor for the ClipboardShare class. * Initializes the ClipboardShare instance with the provided options and sets up event handlers. * * @param {Object} opts - The options for initializing the ClipboardShare instance. */ var ClipboardShare = /*#__PURE__*/function () { function ClipboardShare(opts) { this.events = []; this.el = opts.el; this.link = this.el.querySelector(Selector$5.LINK); this.authoredText = ''; if (this.link) { this.linkText = this.link.querySelector(Selector$5.LINK_TEXT); this.icon = this.link.querySelector(Selector$5.ICON); this.link.setAttribute(Attributes$2.ROLE, 'button'); } this.events.push({ el: this.el, handler: this.handleClick.bind(this), type: EventName$6.ON_CLICK }, { el: this.el, handler: this.handleKeyDown.bind(this), type: EventName$6.ON_KEYDOWN }); Util$1.addEvents(this.events); instances$3.push(this); } var _proto = ClipboardShare.prototype; _proto.handleKeyDown = function handleKeyDown(e) { if (Util$1.getKeyCode(e) === Util$1.keyCodes.SPACE) { this.handleClick(e); } }; _proto.handleClick = function handleClick(e) { var _this = this; e.preventDefault(); // save the original authored text and prevent overwriting by multiple clicks in a short time if (this.authoredText === '') { this.authoredText = this.linkText.textContent; } if (navigator.clipboard && this.linkText && this.icon) { try { var url = window.location.href; navigator.clipboard.writeText(url.split('#')[0]); this.icon.classList.remove(Classes.INITIAL_GLYPH); this.icon.classList.add(Classes.COPIED_GLYPH); this.linkText.textContent = this.el.dataset.copiedText; this.link.ariaLabel = this.el.dataset.copiedText; // Clear any existing reset timer if (this.resetTimer) { clearTimeout(this.resetTimer); } // Reset after 30 seconds this.resetTimer = setTimeout(function () { _this.icon.classList.remove(Classes.COPIED_GLYPH); _this.icon.classList.add(Classes.INITIAL_GLYPH); _this.linkText.textContent = _this.authoredText; _this.link.ariaLabel = _this.authoredText; // reset the authored text to empty _this.authoredText = ''; }, 30000); } catch (_unused) { this.linkText.textContent = this.el.dataset.copiedErrorText; } } else { this.linkText.textContent = this.el.dataset.copiedErrorText; } } /** * Dispatches the update event. */; _proto.update = function update() { this.el.dispatchEvent(ClipboardShare[EventName$6.ON_UPDATE]); } /** * Removes the ClipboardShare instance. * Removes the event handlers, removes the instance from the instances array, and dispatches the remove event. */; _proto.remove = function remove() { var index = this.constructor.getInstances().indexOf(this); Util$1.removeEvents(this.events); this.constructor.getInstances().splice(index, 1); this.el.dispatchEvent(ClipboardShare[EventName$6.ON_REMOVE]); }; ClipboardShare.getInstances = function getInstances() { return instances$3; }; return ClipboardShare; }(); var Selector$4 = { DATA_MOUNT: '[data-mount="sticky"]', DATA_COMPONENT_ID: '[data-component-id]', DATA_BLADE_TYPE: '[data-ocr-type="blade"]', DROPDOWN_ITEM: '.menu-list__item-link', ANCHOR: '.anchor', DROPDOWN_DATA_MOUNT: '[data-mount="m365-dropdown"]', DROPDOWN_MENU: '.dropdown-menu', SECONDARY_NAV: '.secondary-nav', NAV_TAG: '.secondary-sticky-nav nav', JUMPLINKS: '.jumplinks-item__link', SECONDARY_NAV_CONTAINER: '.container', NAV_TITLE: '.block-feature__title', STICKY_NAV: 'nav.container', LIST_ITEM_INNER: '.list-item__inner' }; var Attribute$1 = { HREF: 'href', ARIA_CURRENT: 'aria-current', ARIA_EXPANDED: 'aria-expanded', ARIA_LABEL: 'aria-label', ROLE: 'role', TABINDEX: 'tabindex', CLASS: 'class', ID: 'id', DATA_GENERATE_REGION_SR_TEXT: 'data-generate-region-sr-text', DATA_MOUNT: 'data_mount', DATA_TARGET: 'data-target', DATA_ACTIVE_CLASS: 'data-active-class', ARIA_LABELLED_BY: 'aria-labelledby' }; var AttributeValue = { SCROLLSPY: 'ocr-scrollspy' }; var EventName$5 = { ON_SHOW: 'onShow' }; var ClassName$2 = { SHOW: 'show', ACTIVE: 'active', SELECTED: 'selected', STICKY_CONTAINED: 'sticky--contained', STICKY_NAV_CONTAINED: 'sticky-nav--contained' }; var instances$2 = []; // setup scrollspy for updating item sections on scroll event function _setScrollSpy() { if (!document.querySelector(Selector$4.NAV_TAG)) { return; } var bodyElement = document.querySelector('body'); // set scrollspy on body bodyElement.setAttribute(Attribute$1.DATA_MOUNT, AttributeValue.SCROLLSPY); bodyElement.setAttribute(Attribute$1.DATA_TARGET, "#" + document.querySelector(Selector$4.NAV_TAG).getAttribute(Attribute$1.ID)); bodyElement.setAttribute(Attribute$1.DATA_ACTIVE_CLASS, ClassName$2.SELECTED); var scrollspyInstance = new OcrScrollspy({ el: bodyElement }); scrollspyInstance.update(); } function _getNextSibling(elem, selector) { // Get the next sibling element var sibling = elem.nextElementSibling; // If there's no selector, return the first sibling if (!selector) return sibling; // If the sibling matches our selector, use it // If not, jump to the next sibling and continue the loop while (sibling) { if (sibling.matches(selector)) return sibling; sibling = sibling.nextElementSibling; } } function _getClosestSiblingBlade(authoredElemWithId) { var closestDataComponent = authoredElemWithId.closest(Selector$4.DATA_COMPONENT_ID); var closestAnchor = authoredElemWithId.closest(Selector$4.ANCHOR); if (closestDataComponent) { return _getNextSibling(closestDataComponent, Selector$4.DATA_BLADE_TYPE); } // If the authored element with id is an AEM anchor link outside the blade. if (closestAnchor) { return _getNextSibling(closestAnchor, Selector$4.DATA_BLADE_TYPE); } } function _setIdToComponentContainer() { for (var i = 0; i < this.dropdownItems.length; i++) { var item = this.dropdownItems[i]; var targetHref = item.getAttribute(Attribute$1.HREF); var screenReaderText = item.getAttribute(Attribute$1.ARIA_LABEL) || item.textContent.trim(); if (targetHref) { var targetId = targetHref.split('#')[1]; var authoredElemWithId = document.getElementById(targetId); if (authoredElemWithId) { var spanElem = document.createElement('span'); spanElem.setAttribute(Attribute$1.CLASS, 'sr-only'); spanElem.textContent = screenReaderText; var closestBladeCtn = authoredElemWithId.closest(Selector$4.DATA_BLADE_TYPE); var targetRole = authoredElemWithId.getAttribute(Attribute$1.ROLE); if (!closestBladeCtn) { // this is a special case where the authored element with id is an AEM anchor link outside the blade. closestBladeCtn = _getClosestSiblingBlade(authoredElemWithId); } if (closestBladeCtn) { _setAttributesAndPrependElement(closestBladeCtn, spanElem, targetId, this.generateRegionSRTextFromStickyNav); authoredElemWithId.removeAttribute(Attribute$1.ID); } else { _setAttributesAndPrependElement(authoredElemWithId, spanElem, null, this.generateRegionSRTextFromStickyNav); } if (authoredElemWithId.tagName !== 'SECTION' && targetRole !== null && targetRole !== 'region') { authoredElemWithId.setAttribute(Attribute$1.ROLE, 'region'); } } } } var dropDownExts = DropdownExtension.getInstances(); if (dropDownExts.length) { dropDownExts.forEach(function (dropDownExt) { dropDownExt.update(); }); } } function _setAttributesAndPrependElement(element, spanElem, targetId, generateRegionSRTextFromStickyNav) { if (!element) return; if (targetId) { element.setAttribute(Attribute$1.ID, targetId); } element.setAttribute(Attribute$1.TABINDEX, '-1'); if (generateRegionSRTextFromStickyNav) { element.prepend(spanElem); } } function _updateFlyoutPosition() { var _this = this; var dropdown = this.el.querySelector(Selector$4.DROPDOWN_DATA_MOUNT); var dropdownMenu = this.el.querySelector(Selector$4.DROPDOWN_MENU); var stickyNav = this.el.querySelector(Selector$4.STICKY_NAV); var viewports = ['sm', 'xs']; if (!dropdown) { return; } if (viewports.includes(DetectionUtil.detectViewport())) { if (stickyNav) { stickyNav.style = ''; stickyNav.classList.remove(ClassName$2.STICKY_NAV_CONTAINED); } if (this.dropdownList && this.dropdownList.length > 0) { this.dropdownList.forEach(function (dropDownExt) { dropdownMenu.style.minWidth = 'initial'; dropDownExt.update(); dropDownExt.parent = _this.el; }); dropdownMenu.classList.remove(ClassName$2.SHOW); } } else if (dropdownMenu) { dropdownMenu.style.cssText = ''; } } function _setAriaLabelledBy() { var _this$el$closest; var title = (_this$el$closest = this.el.closest(Selector$4.SECONDARY_NAV_CONTAINER)) == null ? void 0 : _this$el$closest.querySelector(Selector$4.NAV_TITLE); if (title) { title.setAttribute(Attribute$1.ID, this.el.getAttribute(Attribute$1.ARIA_LABELLED_BY)); } } /** * Class to handle sticky component. */ var OcrSticky = /*#__PURE__*/function () { function OcrSticky(opts) { var _this2 = this; this.el = opts.el; _setScrollSpy.call(this); _setAriaLabelledBy.call(this); this.dropdownItems = this.el.querySelectorAll(Selector$4.DROPDOWN_ITEM); if (this.dropdownItems.length === 0) { this.dropdownItems = this.el.querySelectorAll(Selector$4.JUMPLINKS); } this.generateRegionSRTextFromStickyNav = this.el.getAttribute(Attribute$1.DATA_GENERATE_REGION_SR_TEXT) === 'true'; this.viewport = DetectionUtil.detectViewport(); _setIdToComponentContainer.call(this); instances$2.push(this); new Sticky({ el: this.el }); var dropDownExts = DropdownExtension.getInstances(); this.dropdownList = []; if (dropDownExts.length) { dropDownExts.forEach(function (dropDownExt) { var secondaryNav = dropDownExt.el.closest(Selector$4.SECONDARY_NAV); if (secondaryNav) { dropDownExt.show = function () { this[EventName$5.ON_SHOW] = new CustomEvent(EventName$5.ON_SHOW, { bubbles: true, cancelable: true }); this.el.dispatchEvent(this[EventName$5.ON_SHOW]); if (this[EventName$5.ON_SHOW].defaultPrevented) { return; } var windowWidth = document.body.clientWidth; this.shown = true; this.el.classList.add(ClassName$2.ACTIVE); if (this.menu) { this.menu.classList.add(ClassName$2.SHOW); // Store the coordinates of the associated elements for ease of reuse now that the menu has layout this.boundingRect = { el: this.el.getBoundingClientRect(), menu: this.menu.getBoundingClientRect(), parent: this.parent.getBoundingClientRect(), window: { width: windowWidth } }; this.positionMenu(); } this.el.setAttribute(Attribute$1.ARIA_EXPANDED, this.shown); }; _this2.dropdownList.push(dropDownExt); } }); } // Checks to see if the SecondaryNav is the Contained variant if (this.el.classList.contains(ClassName$2.STICKY_CONTAINED)) { var navItems = Array.from(this.dropdownItems); var dropdown = this.el.querySelector(Selector$4.DROPDOWN_DATA_MOUNT); var stickyNav = this.el.querySelector(Selector$4.STICKY_NAV); var trigger = this.el.querySelector(Selector$4.LIST_ITEM_INNER); var dropdownMenu = this.el.querySelector(Selector$4.DROPDOWN_MENU); var viewports = new Set(['sm', 'xs']); if (!stickyNav || !trigger || !dropdownMenu) return; navItems.forEach(function (navItem) { navItem.classList.add('btn', 'btn--circle', 'btn--ghost'); }); var handleDropdownTrigger = function handleDropdownTrigger(event) { var isEnterKey = event.type === 'keydown' && event.key === 'Enter'; var isSpaceKey = event.type === 'keydown' && event.key === ' '; var isClick = event.type === 'click'; if ((isEnterKey || isClick || isSpaceKey) && viewports.has(DetectionUtil.detectViewport())) { event.stopPropagation(); stickyNav.classList.toggle(ClassName$2.STICKY_NAV_CONTAINED); requestAnimationFrame(function () { dropdownMenu.style = ''; if (stickyNav.classList.contains(ClassName$2.STICKY_NAV_CONTAINED)) { dropdownMenu.classList.add(ClassName$2.SHOW); dropdown.setAttribute(Attribute$1.ARIA_EXPANDED, 'true'); var dropdownMenuHeight = dropdownMenu.getBoundingClientRect().height; dropdownMenu.style.top = "-" + (dropdownMenuHeight - 100) + "px"; stickyNav.style.marginBlockStart = "-" + (dropdownMenuHeight - 28) + "px"; } else { dropdownMenu.classList.remove(ClassName$2.SHOW); dropdown.setAttribute(Attribute$1.ARIA_EXPANDED, 'false'); stickyNav.removeAttribute('style'); } }); } }; var handleDropdownMenu = function handleDropdownMenu(event) { var isEnterKey = event.type === 'keydown' && event.key === 'Enter'; var isClick = event.type === 'click'; if ((isEnterKey || isClick) && viewports.has(DetectionUtil.detectViewport())) { stickyNav.classList.remove(ClassName$2.STICKY_NAV_CONTAINED); stickyNav.removeAttribute('style'); } }; trigger.addEventListener('click', handleDropdownTrigger); dropdown.addEventListener('keydown', handleDropdownTrigger); dropdownMenu.addEventListener('click', handleDropdownMenu); dropdownMenu.addEventListener('keydown', handleDropdownMenu); this.el.style.top = 'var(--sticky-contained-top)'; } this.events = [{ el: window, type: 'resize', handler: throttle(200, _updateFlyoutPosition.bind(this)) }]; Util$1.addEvents(this.events); } /** * Get sticky instances. * @returns {Object[]} An array of dropdown instances */ OcrSticky.getInstances = function getInstances() { return instances$2; }; return OcrSticky; }(); var _EventName$ON_REMOVE, _EventName$ON_UPDATE; /** * Initialization options. * @typedef {Object} InitOpts * @property {HTMLElement} el Root element. */ /** * Event handler. * @callback EventHandler * @param {...unknown} args * @returns {unknown} */ /** * Event binding. * @typedef {Object} EventBinding * @property {HTMLElement} el Element to bind the event for. * @property {EventHandler} handler Event handler. * @property {string} type Event name. */ /** * JS event name. * @enum {string} */ var EventName$4 = { ON_REMOVE: 'onRemove', ON_UPDATE: 'onUpdate' }; /** Component base class. */ _EventName$ON_REMOVE = EventName$4.ON_REMOVE; _EventName$ON_UPDATE = EventName$4.ON_UPDATE; var ComponentBase = /*#__PURE__*/function () { /** * Initializes a new instance of the component. * @param {InitOpts} opts Initialization options. * @param {EventBinding[]} [events] Event bindings. */ function ComponentBase(opts, events) { /** * Root element. * @type {HTMLElement} */ this.el = void 0; /** * Event bindings. * @type {EventBinding[]} */ this.events = []; if (this.constructor === ComponentBase.prototype.constructor) { throw new Error("Abstract class ComponentBase can't be instantiated."); } this.el = opts.el; if (events) { this.events = this.events.concat(events); } Util$1.addEvents(this.events); this.constructor.getInstances().push(this); } /** * Update the instance. */ var _proto = ComponentBase.prototype; _proto.update = function update() { this.el.dispatchEvent(ComponentBase[EventName$4.ON_UPDATE]); } /** * Remove the instance. */; _proto.remove = function remove() { var index = this.constructor.getInstances().indexOf(this); Util$1.removeEvents(this.events); this.constructor.getInstances().splice(index, 1); this.el.dispatchEvent(ComponentBase[EventName$4.ON_REMOVE]); } /** * Get component instances. * @returns {ComponentBase[]} An array of component instances. */; ComponentBase.getInstances = function getInstances() { throw new Error('Abstract method getInstances() must be implemented.'); }; return ComponentBase; }(); /** onRemove event. */ ComponentBase[_EventName$ON_REMOVE] = new CustomEvent(EventName$4.ON_REMOVE, { bubbles: true, cancelable: true }); /** onUpdate event. */ ComponentBase[_EventName$ON_UPDATE] = new CustomEvent(EventName$4.ON_UPDATE, { bubbles: true, cancelable: true }); /** * HTML attribute name. * @enum {string} */ var AttributeName = { DATA_PARENT: 'data-parent' }; /** * CSS selector. * @enum {string} */ var Selector$3 = { DATA_MOUNT: '[data-mount="accordion-stepper"]', DATA_MOUNT_COLLAPSE: '[data-mount="collapse"]', ACCORDION_BODY: '.accordion-body', COLLAPSE: '.collapse', SHOW: '.show', COLLAPSE_ACTIVE: '.collapse.show', SECTION_MASTER: '.section-master', LOGO_GRID: '.logo-grid', LOGO_GRID_ITEM: '.logo-grid__item', LOGO_GRID_ITEM_TAB: '.logo-grid__item-tab', LOGO_GRID_ITEM_CONTENT: '.logo-grid__item-content', LOGO_GRID_CONTENT_CONTAINER: '.logo-grid__content-container', CONTAINER: '.container', LOGO_IMG: '.logo-grid__item-tab img' }; /** * Event name. * @enum {string} */ var EventName$3 = { CLICK: 'click', RESIZE: 'resize', LOAD: 'load', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove' }; /** * Class name. * @enum {string} */ var ClassName$1 = { SHOW: 'show', COLLAPSED: 'collapsed' }; /** * Attribute name. * @enum {string} */ var Attributes$1 = { EXPANDED: 'aria-expanded', DISABLED: 'disabled' }; /** * String constants. * @enum {string} */ var Strings = { EMPTY: '', TRUE: 'true', FALSE: 'false' }; /** * Delay in milliseconds. */ var DELAY_MS = 200; /** * Logo Grid Extension instances. * @type {LogoGrid[]} */ var instances$1 = []; /** * Prevents hide functionality on the Collapse elements. * @param {HTMLElement[]} collapseElems Collapse component elements. * @param {CustomEvent} event Hide custom event. */ function _handleCollapseHide(collapseElems, event) { // If Popover component is targeted, don't prevent hide functionality. if (!collapseElems.includes(event.target)) { return; } var activeCollapses = 0; for (var i = 0; i < collapseElems.length && activeCollapses < 2; i++) { if (collapseElems[i].matches(Selector$r.ACTIVES)) { activeCollapses++; } } if (activeCollapses < 2) { event.preventDefault(); } } /** * Get the Logo Grid's is stacked or not. * @returns {boolean} True if Logo Grid is stacked, false otherwise. */ function _getLogoGridIsStacked() { return window.innerWidth < ViewPort.MD; } /** * Adjusts height of Logo Grid based on active tab content * @param {MouseEvent} event Click event. */ function _handleTabContentResize(event) { var isStacked = _getLogoGridIsStacked(); if (isStacked) { event.preventDefault(); return; } var activeTab = event.target.closest(Selector$3.LOGO_GRID_ITEM_TAB); var activeCollapse = activeTab.nextElementSibling; var _activeCollapse$getBo = activeCollapse.getBoundingClientRect(), height = _activeCollapse$getBo.height; var logoGrid = activeCollapse.closest(Selector$3.LOGO_GRID); logoGrid.style.height = 'auto'; // Set height to auto so we can get its original height. logoGrid.style.height = logoGrid.clientHeight + height + "px"; // Add the Logo Grid's height to the original height. } /** * Generates all events for the Logo Grid Extension. * @param {HTMLElement} el Accordion stepper element. * @param {Object[]} accordionChildren All children of this accordion, containing the Collapse and child Tab Content. * @returns {EventBinding[]} An array of event listeners to attach. */ function _generateEvents(el, accordionChildren) { var collapseElements = accordionChildren.map(function (child) { return child.collapse.el; }); var events = []; var tabElements = el.querySelectorAll(Selector$3.LOGO_GRID_ITEM_TAB); // Add collapse handler. for (var _iterator = _createForOfIteratorHelperLoose(accordionChildren), _step; !(_step = _iterator()).done;) { var child = _step.value; events.push({ el: child.collapse.el, type: EventName$o.HIDE, handler: _handleCollapseHide.bind(null, collapseElements) }); } // Add tab content handler. for (var _iterator2 = _createForOfIteratorHelperLoose(tabElements), _step2; !(_step2 = _iterator2()).done;) { var tab = _step2.value; events.push({ el: tab, type: EventName$3.CLICK, handler: _handleTabContentResize.bind(null) }); } return events; } /** * Initializes the given Collapse. * @param {HTMLElement} el Accordion stepper element. * @param {Collapse} collapse The given collapse object to initialize. * @returns {Object} The accordion child object for the Collapse and its Tab Content. */ function _initializeCollapse(el, collapse) { // Get data-parent id from Collapse. var parentId = collapse.el.getAttribute(AttributeName.DATA_PARENT); var itemContents = el.querySelectorAll(Selector$3.LOGO_GRID_CONTENT_CONTAINER); // If the parent is this accordion, add the collapse to array. if (parentId === "#" + el.id) { var tabContent = itemContents.forEach(function (item) { return item.el === collapse.el.querySelector(Selector$3.LOGO_GRID_ITEM_CONTENT); }); return { collapse: collapse, tabContent: tabContent }; } } /** * Handles resizing of the Section Master by adjusting to the size of the targeted Collapse element. * @param {ResizeObserverEntry[]} entries An array of size changes from the resizeObserver. */ function _handleCollapseContentsResize(entries) { for (var _iterator3 = _createForOfIteratorHelperLoose(entries), _step3; !(_step3 = _iterator3()).done;) { var entry = _step3.value; if (!entry.target.parentElement.classList.contains(ClassName$1.SHOW)) { continue; } _updateLogoGridHeight(entry.target); } } /** * Updates the height of the Logo Grid after logo images load complete. * @param {HTMLElement[]} items The items to update the height of the Logo Grid. */ var _updateLogoGridHeightAfterImageLoaded = debounce(DELAY_MS, function (items) { for (var _iterator4 = _createForOfIteratorHelperLoose(items), _step4; !(_step4 = _iterator4()).done;) { var item = _step4.value; if (!item.parentElement.classList.contains(ClassName$1.SHOW)) { continue; } _updateLogoGridHeight(item); } }); /** * Updates the height of the Logo Grid. * @param {HTMLElement} item The item to update the height of the Logo Grid. */ function _updateLogoGridHeight(item) { var isStacked = _getLogoGridIsStacked(); var parentCollapse = item.closest(Selector$3.COLLAPSE); var _parentCollapse$getBo = parentCollapse.getBoundingClientRect(), height = _parentCollapse$getBo.height; var logoGrid = item.closest(Selector$3.LOGO_GRID); logoGrid.style.height = 'auto'; // Set height to auto so we can get its original height. logoGrid.style.height = logoGrid.clientHeight + height + "px"; // Add the Logo Grid's height to the original height. // When Logo Grid becomes stacked, subtract Logo Grid Content Container's margin-bottom from Logo Grid. if (isStacked) { var contentContainerEl = item.closest(Selector$3.LOGO_GRID_CONTENT_CONTAINER); var contentContainerMb = window.getComputedStyle(contentContainerEl).getPropertyValue('margin-bottom'); var marginBottomNum = parseInt(contentContainerMb, 10); logoGrid.style.height = 'auto'; logoGrid.style.height = logoGrid.clientHeight - marginBottomNum + "px"; } } /** * Handles resizing of the Section Master by adjusting to the collapse status of the targeted Collapse element. * @param {ResizeObserverEntry[]} entries An array of size changes from the resizeObserver. */ function _handleCollapseButtonsResize(entries) { var isStacked = _getLogoGridIsStacked(); entries.forEach(function (entry) { if (isStacked) { // If Logo Grid is stacked, set all buttons aria-expanded to true. entry.target.setAttribute(Attributes$1.EXPANDED, Strings.TRUE); entry.target.setAttribute(Attributes$1.DISABLED, Strings.EMPTY); return; } // Otherwise, set aria-expanded according to collapse status. if (entries.length !== 1) { var collapsed = entry.target.classList.contains(ClassName$1.COLLAPSED); entry.target.setAttribute(Attributes$1.EXPANDED, collapsed ? Strings.FALSE : Strings.TRUE); entry.target.removeAttribute(Attributes$1.DISABLED); } }); } /** Logo Grid component. */ var LogoGrid = /*#__PURE__*/function (_ComponentBase) { _inheritsLoose(LogoGrid, _ComponentBase); /** * Initializes a new instance of the Stepper component. * @param {InitOpts} opts Initialization options. */ function LogoGrid(opts) { var _this; var el = opts.el; // Get and initialize children of this accordion. var accordionChildren = []; if (window.mwf) { // Should only skip in tests. window.mwf.Collapse.getInstances().forEach(function (collapse) { return accordionChildren.push(_initializeCollapse(el, collapse)); }); // Filter out undefined accordionChildren from other step containers. accordionChildren.splice.apply(accordionChildren, [0, accordionChildren.length].concat(accordionChildren.filter(function (ac) { return ac !== undefined; }))); } // Generate events. var events = _generateEvents(el, accordionChildren); _this = _ComponentBase.call(this, opts, events) || this; // Assign all properties. /** * Accordion stepper element. * @type {HTMLElement} */ _this.el = void 0; /** * All children of this accordion, containing the Collapse and its Tab Content. * @type {Object[]} */ _this.accordionChildren = void 0; /** * Resize observer for handles resizing of the Section Master by adjusting to the size of the targeted Collapse element. * @type {ResizeObserver | null} */ _this.collapseContentsResizeObserver = null; /** * Resize observer for handles collapse status of the targeted Collapse button element. * @type {ResizeObserver | null} */ _this.collapseButtonsResizeObserver = null; _this.el = el; _this.accordionChildren = accordionChildren; var itemContents = el.querySelectorAll(Selector$3.LOGO_GRID_CONTENT_CONTAINER); var collapseButtons = el.querySelectorAll(Selector$3.LOGO_GRID_ITEM_TAB + " button" + Selector$3.DATA_MOUNT_COLLAPSE); if (collapseButtons.length === 1) { // If there is only one collapse button, set its disabled attribute. collapseButtons[0].setAttribute(Attributes$1.EXPANDED, Strings.TRUE); collapseButtons[0].setAttribute(Attributes$1.DISABLED, Strings.EMPTY); } // Add event listeners for logo tab images. document.querySelectorAll(Selector$3.LOGO_IMG).forEach(function (logoImage) { logoImage.addEventListener(EventName$3.LOAD, function () { _updateLogoGridHeightAfterImageLoaded(itemContents); }, false); }); // Create and attach observer. Should only skip in tests. if (window.ResizeObserver) { var contentsResizeObserver = new ResizeObserver(_handleCollapseContentsResize); for (var _iterator5 = _createForOfIteratorHelperLoose(itemContents), _step5; !(_step5 = _iterator5()).done;) { var itemContent = _step5.value; contentsResizeObserver.observe(itemContent); } _this.collapseContentsResizeObserver = contentsResizeObserver; var buttonsResizeObserver = new ResizeObserver(_handleCollapseButtonsResize); for (var _iterator6 = _createForOfIteratorHelperLoose(collapseButtons), _step6; !(_step6 = _iterator6()).done;) { var collapseButton = _step6.value; buttonsResizeObserver.observe(collapseButton); } _this.collapseButtonsResizeObserver = buttonsResizeObserver; } return _this; } /** * Updates the options of the Stepper instance with those in opts. * @param {InitOpts} opts - Stepper options. * @this {LogoGrid} The Stepper being updated. */ var _proto = LogoGrid.prototype; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } if (opts.el) { this.el = opts.el; } // Create and dispatch custom event this[EventName$3.ON_UPDATE] = new CustomEvent(EventName$3.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$3.ON_UPDATE]); } /** * Removes all event listeners and references to the Stepper instance. * @this {LogoGrid} The Stepper being removed. */; _proto.remove = function remove() { var _this$collapseContent, _this$collapseButtons; Util$1.removeEvents(this.events); (_this$collapseContent = this.collapseContentsResizeObserver) == null ? void 0 : _this$collapseContent.disconnect(); (_this$collapseButtons = this.collapseButtonsResizeObserver) == null ? void 0 : _this$collapseButtons.disconnect(); // Remove this reference from array of instances. var index = instances$1.indexOf(this); instances$1.splice(index, 1); // Create and dispatch custom event. this[EventName$3.ON_REMOVE] = new CustomEvent(EventName$3.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$3.ON_REMOVE]); } /** * Gets Logo Grid component extension instances. * @returns {LogoGrid[]} */; LogoGrid.getInstances = function getInstances() { return instances$1; }; return LogoGrid; }(ComponentBase); var instances = []; var Selector$2 = { DATA_MOUNT: '[data-mount="checkbox-dropdown"]', LIST: '.checkbox-dropdown__list', PARENT_CHECKBOX: '.checkbox-dropdown__header input[type="checkbox"]', CHECKBOXES: '.checkbox-dropdown__list input[type="checkbox"]', GLYPH: '.glyph-append', INPUT: '.ocr-input', HEADER_BUTTON: '.checkbox-dropdown__header a' }; /** * JS event name. * @enum {string} */ var EventName$2 = { ON_INIT: 'onInit', ON_REMOVE: 'onRemove', ON_SELECT: 'onSelect', ON_UPDATE: 'onUpdate', CLICK: 'click', CHANGE: 'change', KEY_DOWN: 'keydown', ON_CHECKBOX_CHECKED: 'onCheckboxChecked', ON_CHECKBOX_UNCHECKED: 'onCheckboxUnchecked' }; var GLYPHS = { UP: 'glyph-append-chevron-up', DOWN: 'glyph-append-chevron-down' }; var handleKeyPress = function handleKeyPress(keys, func) { return function (event) { for (var _iterator = _createForOfIteratorHelperLoose(keys), _step; !(_step = _iterator()).done;) { var key = _step.value; if (event.keyCode === key) { func(); event.preventDefault(); break; } } }; }; var CheckboxDropdown = /*#__PURE__*/function () { function CheckboxDropdown(_ref) { var _this = this; var el = _ref.el; this.el = el; this.events = []; this.dropdownList = this.el.querySelector(Selector$2.LIST); this.checkboxes = this.el.querySelectorAll(Selector$2.CHECKBOXES); this.parentCheckbox = this.el.querySelector(Selector$2.PARENT_CHECKBOX); this.button = this.el.querySelector(Selector$2.HEADER_BUTTON); this.parentCheckbox.id = Util.NewElementUID(); var inputs = this.el.querySelectorAll(Selector$2.INPUT); var ids = []; for (var _iterator2 = _createForOfIteratorHelperLoose(inputs), _step2; !(_step2 = _iterator2()).done;) { var input = _step2.value; var checkbox = input.querySelector('input'); var label = input.querySelector('label'); var id = Util.NewElementUID(); checkbox.id = id; label.setAttribute('for', id); ids.push(id); } this.parentCheckbox.setAttribute('aria-controls', ids.map(function (x) { return "" + x; }).join(' ')); for (var _iterator3 = _createForOfIteratorHelperLoose(this.checkboxes), _step3; !(_step3 = _iterator3()).done;) { var _checkbox = _step3.value; this.events.push({ el: _checkbox, handler: this.onChildCheckboxChanged.bind(this), type: EventName$2.CHANGE }); } this.hideDropdownButtonForEmptyList(); this.events.push({ el: this.parentCheckbox, handler: this.onParentCheckboxChanged.bind(this), type: EventName$2.CHANGE }, { el: this.button, handler: this.onButtonClick.bind(this), type: EventName$2.CLICK }, { el: this.button, handler: handleKeyPress([Util$1.keyCodes.SPACE], function () { _this.button.click(); }), type: EventName$2.KEY_DOWN }); Util$1.addEvents(this.events); instances.push(this); } var _proto = CheckboxDropdown.prototype; _proto.hideDropdownButtonForEmptyList = function hideDropdownButtonForEmptyList() { var dropdownList = this.dropdownList; var childDivs = Array.from(dropdownList.children).filter(function (child) { return child.tagName === 'DIV'; }); if (childDivs.length === 0) { this.button.style.visibility = 'hidden'; } }; _proto.onButtonClick = function onButtonClick() { var isExpanded = this.button.getAttribute('aria-expanded') === 'true'; var icon = this.button.querySelector(Selector$2.GLYPH); if (isExpanded) { icon.classList.remove(GLYPHS.DOWN); icon.classList.add(GLYPHS.UP); } else { icon.classList.remove(GLYPHS.UP); icon.classList.add(GLYPHS.DOWN); } }; _proto.onParentCheckboxChanged = function onParentCheckboxChanged() { var isEnabled = this.parentCheckbox.checked; for (var _iterator4 = _createForOfIteratorHelperLoose(this.checkboxes), _step4; !(_step4 = _iterator4()).done;) { var checkbox = _step4.value; checkbox.checked = isEnabled; } this.parentCheckbox.indeterminate = false; }; _proto.onChildCheckboxChanged = function onChildCheckboxChanged(event) { var checked = 0; for (var _iterator5 = _createForOfIteratorHelperLoose(this.checkboxes), _step5; !(_step5 = _iterator5()).done;) { var checkbox = _step5.value; if (checkbox.checked) checked++; } if (checked === 0) { this.parentCheckbox.checked = false; this.parentCheckbox.indeterminate = false; } else if (checked === this.checkboxes.length) { this.parentCheckbox.checked = true; this.parentCheckbox.indeterminate = false; } else { this.parentCheckbox.checked = false; this.parentCheckbox.indeterminate = true; } this.el.dispatchEvent(new CustomEvent(EventName$2.CLICK, { cancelable: true, bubbles: true, detail: { name: event.target.value, enabled: event.target.checked } })); }; _proto.update = function update() {}; _proto.remove = function remove() { Util$1.removeEvents(this.events); var index = instances.indexOf(this); instances.splice(index, 1); }; CheckboxDropdown.getInstances = function getInstances() { return instances; }; return CheckboxDropdown; }(); var JS_INITIALIZED = 'oneCloudReimagineIntialized'; function initializeComponents() { Util$1.initializeComponent(Selector$N.DATA_MOUNT, function (el) { return new VideoExtension({ el: el }); }); Util$1.initializeComponent(Selector$I.DATA_MOUNT, function (el) { return new DropdownExtension({ el: el }); }); Util$1.initializeComponent(Selector$q.DATA_MOUNT, function (el) { return new CollapseExtension({ el: el }); }); Util$1.initializeComponent(Selector$o.DATA_MOUNT, function (el) { return new CollapseControlsExtension({ el: el }); }); Util$1.initializeComponent(Selector$h.DATA_MOUNT, function (el) { return new AlertExtension({ el: el }); }); Util$1.initializeComponent(Selector$G.DATA_MOUNT, function (el) { return new SnapCarousel({ el: el }); }); Util$1.initializeComponent(Selector$G.DATA_MOUNT_OLD, function (el) { return new SnapCarousel({ el: el }); }); Util$1.initializeComponent(Selector$J.DATA_MOUNT, function (el) { return new OcrScrollspy({ el: el }); }); Util$1.initializeComponent(Selector$4.DATA_MOUNT, function (el) { return new OcrSticky({ el: el }); }); Util$1.initializeComponent(Selector$F.DATA_MOUNT, function (el) { return new DynamicContent({ el: el }); }); Util$1.initializeComponent(Selector$z.DATA_MOUNT, function (el) { return new FilterPanelItem({ el: el }); }); Util$1.initializeComponent(Selector$D.DATA_MOUNT, function (el) { return new Filters({ el: el }); }); Util$1.initializeComponent(Selector$C.DATA_MOUNT, function (el) { return new EventFinder({ el: el }); }); Util$1.initializeComponent(Selector$y.DATA_MOUNT, function (el) { return new Pagination({ el: el }); }); Util$1.initializeComponent(Selector$E.DATA_MOUNT, function (el) { return new DropdownFilter({ el: el }); }); Util$1.initializeComponent(Selector$v.DATA_MOUNT, function (el) { return new DynamicallyAddedFilters({ el: el }); }); Util$1.initializeComponent(Selector$u.DATA_MOUNT, function (el) { return new SolutionCenter({ el: el }); }); Util$1.initializeComponent(Selector$B.DATA_MOUNT, function (el) { return new TabSlider({ el: el }); }); Util$1.initializeComponent(Selector$A.DATA_MOUNT, function (el) { return new Modal({ el: el }); }); Util$1.initializeComponent(Selector$3.DATA_MOUNT, function (el) { return new LogoGrid({ el: el }); }); Util$1.initializeComponent(Selector$t.DATA_MOUNT, function (el) { return new Icon({ el: el }); }); Util$1.initializeComponent(Selector$2.DATA_MOUNT, function (el) { return new CheckboxDropdown({ el: el }); }); Util$1.initializeComponent(Selector$l.DATA_MOUNT, function (el) { return new ContactSales({ el: el }); }); Util$1.initializeComponent(Selector$n.DATA_MOUNT, function (el) { return new MultiCollapse({ el: el }); }); Util$1.initializeComponent(Selector$m.DATA_MOUNT, function (el) { return new MultiCollapseControls({ el: el }); }); Util$1.initializeComponent(Selector$s.DATA_MOUNT, function (el) { return new Effects({ el: el }); }); Util$1.initializeComponent(Selector$k.DATA_MOUNT, function (el) { return new AISearchForm({ el: el }); }); Util$1.initializeComponent(Selector$j.DATA_MOUNT, function (el) { return new AIChatDrawer({ el: el }); }); Util$1.initializeComponent(Selector$e.DATA_MOUNT, function (el) { return new ProactiveChat({ el: el }); }); Util$1.initializeComponent(Selector$g.DATA_MOUNT, function (el) { return new OcrFixedSticky({ el: el }); }); Util$1.initializeComponent(Selector$f.DATA_MOUNT, function (el) { return new Table({ el: el }); }); Util$1.initializeComponent(Selector$d.DATA_MOUNT, function (el) { return new Breadcrumbs({ el: el }); }); Util$1.initializeComponent(Selector$c.DATA_MOUNT, function (el) { return new RollingText({ el: el }); }); Util$1.initializeComponent(Selector$x.DATA_MOUNT, function (el) { return new SingleSelect({ el: el }); }); Util$1.initializeComponent(Selector$b.DATA_MOUNT, function (el) { return new SelectorSlider({ el: el }); }); Util$1.initializeComponent(Selector$w.DATA_MOUNT, function (el) { return new TimeSlider({ el: el }); }); Util$1.initializeComponent(Selector$a.DATA_MOUNT, function (el) { return new CardStat({ el: el }); }); Util$1.initializeComponent(Selector$9.DATA_MOUNT, function (el) { return new OcrTab({ el: el }); }); Util$1.initializeComponent(Selector$8.DATA_MOUNT, function (el) { return new OcrAccordion({ el: el }); }); Util$1.initializeComponent(Selector$7.DATA_MOUNT, function (el) { return new CardInteractive({ el: el }); }); Util$1.initializeComponent(Selector$6.DATA_MOUNT, function (el) { return new FeaturedCardsInteractive({ el: el }); }); Util$1.initializeComponent(Selector$5.DATA_MOUNT, function (el) { return new ClipboardShare({ el: el }); }); } var Selector$1 = { DATA_MOUNT: '[data-mount="fixed-sticky"]', SHOW_STUCK: '.sticky-show-stuck', HIDE_STUCK: '.sticky-hide-stuck' }; var ClassName = { STICKY: 'fixed-sticky', SENTINEL: 'sticky-sentinel', STUCK: 'stuck', GET_HEIGHT: 'get-height', STICKY_TOP: 'sticky-direction-top', STICKY_BOTTOM: 'sticky-direction-bottom' }; var Attribute = { DATA_DIRECTION: 'data-direction', DATA_OBSERVER_BEHAVIOR: 'data-observer-behavior', DATA_SMOOTH_TRANSITION: 'data-smooth-transition' }; var Direction = { TOP: 'top', BOTTOM: 'bottom' }; var EventName$1 = { ON_STUCK: 'onSticky', ON_UNSTUCK: 'onStatic', ON_UPDATE: 'onUpdate', ON_REMOVE: 'onRemove', FOCUS_IN: 'focusin', RESIZE: 'resize' }; var Default = { DIRECTION: 'top' }; /** * @enum {string} */ var ObserverBehavior = { ALWAYS: 'always', OFF: 'off', SIZE_AWARE: 'size-aware' }; var stickies = []; /** * Private functions. */ /** * Check for the `data-smooth-transition` attribute. * Its presence makes this option `true` unless the value is specifically set to `false` * @param {HTMLElement} node - The element to check for the attribute `data-smooth-transition` * @returns {Boolean} return false if contentDivTarget is null */ function _hasSmoothTransition(node) { if (node.hasAttribute(Attribute.DATA_SMOOTH_TRANSITION) && node.dataset.smoothTransition !== 'false') { return true; } return false; } /** * Get the direction of the sticky. * @param {string} str - The string to parse. * @param {string} [defaultValue=top] - The default value to fallback to. * @returns {string} The direction of the sticky. */ function _getDirection(str, defaultValue) { if (defaultValue === void 0) { defaultValue = Default.DIRECTION; } switch (str) { case 'top': case 'bottom': return str; default: return defaultValue; } } /** * Handle intersection observer * @this FixedSticky */ function _onStickyChange() { this.el.classList.toggle(ClassName.STUCK, this.isStuck); _updateContentDivSpacing.bind(this)(); _updateScrollPadding.bind(this)(); } /** * Update margin spacing on the element before/after the sticky bar so that overlapping * does not occur when the page bar is fixed. Remove property if it is not stuck * @this FixedSticky */ function _updateContentDivSpacing() { if (this.contentDivTarget === null) { return; } var adjustNextElementSpacing = this.stickyElementHeight + this.contentDivTargetSpacing; if (this.rootMarginOffset !== 0) { adjustNextElementSpacing -= this.rootMarginOffset; } if (this.isStuck) { this.contentDivTarget.style.setProperty(this.styleProp, adjustNextElementSpacing + 'px', 'important'); } else { this.contentDivTarget.style.setProperty(this.styleProp, ''); } } /** * Updates scroll padding so that elements scrolled into view don't stay behind * @this FixedSticky */ function _updateScrollPadding(removeScrollPadding) { var htmlElement = document.querySelector('html'); this.stickyElementHeight = this.el.getBoundingClientRect().height; if (removeScrollPadding) { htmlElement.style.scrollPaddingTop = '0'; htmlElement.style.scrollPaddingBottom = '0'; } if (this.direction === Direction.TOP) { if (this.isStuck) { htmlElement.style.scrollPaddingTop = this.stickyElementHeight + this.extraScrollPaddingPx + 'px'; } else { htmlElement.style.scrollPaddingTop = this.stickyElementHeight + this.rootMarginOffset + this.extraScrollPaddingPx + 'px'; } } else if (this.direction === Direction.BOTTOM) { if (this.isStuck) { htmlElement.style.scrollPaddingBottom = this.stickyElementHeight + this.extraScrollPaddingPx + 'px'; } else { htmlElement.style.scrollPaddingBottom = this.stickyElementHeight + this.rootMarginOffset + this.extraScrollPaddingPx + 'px'; } } } /** * Triggers a boundary check when focus changes to handle edge cases where Intersection Observer does not fire * Uses focusin because focus does not bubble * @this FixedSticky */ function _onFocusin() { if (this.enableObserver) { this.isStuck = this.doesSentinelExceedBoundary(); this.el.classList.toggle(ClassName.STUCK, this.isStuck); _updateScrollPadding.bind(this)(); } } /** Calculate whether the height of the sticky has exceeded 33% of the viewport height based on height of the sticky's hidden elements and the height of the sticky's visible elements. @returns {boolean} Whether the height of the sticky has exceeded 33% of the viewport height. @this FixedSticky */ function _stickyExceedsAcceptedHeight() { // Subtracting two additional pixels based on a border that is toggled based on visibility. return (this.hiddenElementsHeight + this.visibleElementsHeight - 2) / window.innerHeight > 0.33; } /** Set the status of the sticky observer, dependent on configuration and/or height condition @this FixedSticky */ function _setObserver() { switch (this.observerBehavior) { case ObserverBehavior.OFF: this.setObserverStatus(false); break; case ObserverBehavior.ALWAYS: this.setObserverStatus(true); break; default: if (_stickyExceedsAcceptedHeight.call(this)) { this.setObserverStatus(false); } else { this.setObserverStatus(true); } } } /** * Validate observer behavior or fall back to default * @param {string} [option] - configuration for observerBehavior * @returns {ObserverBehavior} * @this FixedSticky */ function _getObserverBehavior(option) { // TODO: remove in v2 - deprecated as of v1.14.0 // handle previous `enableObserver: false` and override if (this.enableObserverInitial === false) { return ObserverBehavior.OFF; } var isValid = function isValid(behavior) { return Object.values(ObserverBehavior).includes(behavior); }; if (option && isValid(option)) { return option; } if (isValid(this.el.dataset.observerBehavior)) { return this.el.dataset.observerBehavior; } return ObserverBehavior.SIZE_AWARE; } /** Calculate the combined height of all ".sticky-show-stuck" elements. @returns {number} Combined height of all ".sticky-show-stuck" elements. @this FixedSticky */ function _getShowStuckHeight() { var _this = this; var hiddenHeight = 0; // Calculate the height of hidden elements when not stuck var showStuck = this.el.querySelectorAll(Selector$1.SHOW_STUCK); if (showStuck && showStuck instanceof NodeList) { // Get the height of all hidden elements showStuck.forEach(function (el, index, list) { hiddenHeight += window.mwf.Util.getElementOuterHeight(el, { cssSelectors: ['margin', 'padding'] }); // If this is the last item in the node list, remove the CSS hack that displays hidden elements if (index === list.length - 1) { _this.el.classList.remove(ClassName.GET_HEIGHT); } }); } return hiddenHeight; } /** Calculate the height of hidden and visible elements. @returns {Object} Object containing height of hidden and visible elements. @this FixedSticky */ function _calculateHeights() { this.el.classList.add(ClassName.GET_HEIGHT); var hiddenHeight = _getShowStuckHeight.call(this); var visibleHeight = this.el.offsetHeight; this.el.classList.remove(ClassName.GET_HEIGHT); return { hidden: hiddenHeight, visible: visibleHeight }; } /** * Set value of instances members and DOM node properties depending on the direction instance member * @this FixedSticky */ function _setDirectionalProps() { if (this.direction === Direction.BOTTOM) { this.el.style.top = null; // prevent interference this.el.style.bottom = '0'; this.contentDivTarget = this.el.previousElementSibling; this.contentDivTargetSpacing = this.contentDivTarget ? parseInt(getComputedStyle(this.contentDivTarget).paddingBottom, 10) + parseInt(getComputedStyle(this.contentDivTarget).marginBottom, 10) : 0; this.styleProp = 'margin-bottom'; this.el.classList.add(ClassName.STICKY_BOTTOM); this.el.classList.remove(ClassName.STICKY_TOP); } else { // Assume direction is Direction.TOP this.el.style.bottom = null; this.el.style.top = '0'; this.contentDivTarget = this.el.nextElementSibling; this.contentDivTargetSpacing = this.contentDivTarget ? parseInt(getComputedStyle(this.contentDivTarget).paddingTop, 10) + parseInt(getComputedStyle(this.contentDivTarget).marginTop, 10) : 0; this.styleProp = 'margin-top'; this.el.classList.add(ClassName.STICKY_TOP); this.el.classList.remove(ClassName.STICKY_BOTTOM); } } /** * Create a new observer instance member, disconnecting the old one if present. Instance member sentinel must already exist * @this FixedSticky */ function _createObserver() { var _this2 = this; if (this.observer) { this.observer.disconnect(); } // If smooth transition is enabled, the`rootMarginOffset` value should reflect the combined height // of all elements hidden prior to the sticky becoming stuck. Adding this value to the rootMargin option // of the intersection observer will allow for the sticky to activate sooner, resulting in a more // seamless transition var observerOptions = { rootMargin: "-" + this.rootMarginOffset + "px 0px 0px 0px" }; var onStickyChange = _onStickyChange.bind(this); this.observer = new IntersectionObserver(function (entries) { // fire onStickyChange if not in viewport if (_this2.enableObserver) { var prevState = _this2.isStuck; _this2.isStuck = _this2.doesSentinelExceedBoundary() && !entries[0].isIntersecting; // Check if sticky has changed state from unstuck to stuck and vice versa // in order to trigger custom events if (typeof prevState !== 'undefined' && prevState !== _this2.isStuck) { if (_this2.isStuck) { // Create and dispatch custom event _this2[EventName$1.ON_STUCK] = new CustomEvent(EventName$1.ON_STUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$1.ON_STUCK]); } else { // Create and dispatch custom event _this2[EventName$1.ON_UNSTUCK] = new CustomEvent(EventName$1.ON_UNSTUCK, { bubbles: true }); _this2.el.dispatchEvent(_this2[EventName$1.ON_UNSTUCK]); } } onStickyChange(); } }, observerOptions); if (this.sentinel) { this.observer.observe(this.sentinel); } } /** * Helper function to clear key properties of an instance * @this FixedSticky */ function _teardownInstance() { window.mwf.Util.removeEvents(this.events); // remove the attribute from the element this.el.classList.remove(ClassName.STICKY); _updateScrollPadding.call(this, [true]); // remove sticky-sentinel element this.sentinel.remove(); // disconnect observer this.observer.disconnect(); } /** * Class representing a Sticky Element. */ var FixedSticky = /*#__PURE__*/function () { /** * Create the Sticky Element * @param {Object} opts - The Sticky Element options. * @param {HTMLElement} opts.el - The Sticky Element DOM node. * @param {string} opts.direction - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will attempt to read `data-direction` attribute, then defaults TOP * @param {boolean} opts.enableSmoothTransition - Whether to enable a smoother transition to hiding/showing elements as the sticky become stuck. If not defined, will attempt to read `data-smooth-transition` attribute, defaults to false * @param {boolean} opts.enableObserver - deprecated: enable the observer on initialization (defaults to true) * @param {ObserverBehavior} opts.observerBehavior - the behavior of the intersection observer to toggle stuck/unstuck states * @param {number} opts.extraScrollPaddingPx - Extra scroll padding to reduce crowding into sticky bars, defaults to 12px, same as minimal gutters */ function FixedSticky(opts) { this.el = opts.el; this.direction = _getDirection(opts.direction || this.el.dataset.direction); this.enableSmoothTransition = typeof opts.enableSmoothTransition === 'boolean' ? opts.enableSmoothTransition : _hasSmoothTransition(this.el); this.extraScrollPaddingPx = typeof opts.extraScrollPaddingPx === 'number' ? opts.extraScrollPaddingPx : 12; this.enableObserver = opts.enableObserver !== false; // Saves the initial value of enable observer status from construction. Is used to flag whether the sticky should be automatically disabled when the height of the sticky exceeds 33% of the viewport // TODO: remove in v2 - deprecated as of v1.14.0 this.enableObserverInitial = this.enableObserver; this.observerBehavior = _getObserverBehavior.call(this, opts.observerBehavior); // Add "sticky" class only while initialized to attach style and functionality provided by CSS // Set prior to all height calculations so that styles are applied first this.el.classList.add(ClassName.STICKY); // HTML element with the property data-mount="sticky" // Create a property to hold the value for the sticky element height to be reused in both the _updateContentDivSpacing and _updateScrollPadding functions. this.stickyElementHeight = 0; // Set properties based on the anchor direction this.contentDivTarget = null; this.contentDivTargetSpacing = 0; this.styleProp = ''; _setDirectionalProps.call(this); // Add event handlers this.events = [{ el: document.body, type: EventName$1.FOCUS_IN, handler: _onFocusin.bind(this) }, { el: window, type: EventName$1.RESIZE, handler: throttle(200, _updateScrollPadding.bind(this)) }, { el: window, type: EventName$1.RESIZE, handler: debounce(300, _setObserver.bind(this)), options: { passive: true } }]; window.mwf.Util.addEvents(this.events); var _calculateHeights$cal = _calculateHeights.call(this), hiddenElementsHeight = _calculateHeights$cal.hidden, visibleElementsHeight = _calculateHeights$cal.visible; // Adjusts where the sentinel to the intersection observer triggers. Expected to be 0 if smooth transition is disabled. this.rootMarginOffset = this.enableSmoothTransition ? hiddenElementsHeight : 0; this.hiddenElementsHeight = hiddenElementsHeight; this.visibleElementsHeight = visibleElementsHeight; this.sentinel = document.createElement('div'); this.sentinel.classList.add(ClassName.SENTINEL); this.el.insertAdjacentElement('beforebegin', this.sentinel); this.isStuck = false; this.observer = null; _createObserver.call(this); _setObserver.call(this); stickies.push(this); } /** * Check if the sentinel Exceeds the boundary * @returns {boolean} State of sentinel boundary */ var _proto = FixedSticky.prototype; _proto.doesSentinelExceedBoundary = function doesSentinelExceedBoundary() { var sentinelRect = this.sentinel.getBoundingClientRect(); var sentinelTop = sentinelRect.top - this.rootMarginOffset; var sentinelBottom = sentinelRect.bottom; if (this.direction === Direction.TOP && sentinelTop < 0) { return true; } if (this.direction === Direction.BOTTOM && sentinelBottom > window.innerHeight) { return true; } return false; } /** * Set the status (enabled/disabled) of the intersection observer * @param {boolean} status The status to set */; _proto.setObserverStatus = function setObserverStatus(status) { if (this.doesSentinelExceedBoundary()) { _updateScrollPadding.call(this); if (status) { this.el.classList.add(ClassName.STUCK); } else { this.el.classList.remove(ClassName.STUCK); } } this.enableObserver = status; } /** * Updates key aspects the instance * @param {Object} opts - The Sticky options. * @param {string} [opts.direction] - Whether the Sticky element sticks to the top when scrolled below a certain point (TOP) or sticks to the bottom when scrolled above a certain point (BOTTOM). If not defined, will maintain current setting * @param {boolean} [opts.enableSmoothTransition] - Whether to enable a smoother transition to hiding/showing elements as the sticky become stuck. If not defined, will maintain current setting * @param {number} [opts.extraScrollPaddingPx] - Extra scroll padding to reduce crowding into sticky bars. If not define, will maintain current setting * @param {ObserverBehavior} [opts.observerBehavior] - the behavior of the intersection observer to toggle stuck/unstuck states */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } var updateDirection = typeof opts.direction === 'string' ? _getDirection(opts.direction) : this.direction; var updateEnableSmoothTransition = typeof opts.enableSmoothTransition === 'boolean' ? opts.enableSmoothTransition : this.enableSmoothTransition; var updateExtraScrollPaddingPx = typeof opts.extraScrollPaddingPx === 'number' ? opts.extraScrollPaddingPx : this.extraScrollPaddingPx; var _calculateHeights$cal2 = _calculateHeights.call(this), updateHiddenElementsHeight = _calculateHeights$cal2.hidden, updateVisibleElementsHeight = _calculateHeights$cal2.visible; // update visibleElementsHeight for future calculations this.visibleElementsHeight = updateVisibleElementsHeight; // Set properties based on the anchor direction if changed if (this.direction !== updateDirection) { this.direction = updateDirection; _setDirectionalProps.call(this); // need to update scroll padding if direction changes this.extraScrollPaddingPx = updateExtraScrollPaddingPx; _updateScrollPadding.call(this, [true]); } // update scroll padding if extraScrollPaddingPx updated but direction not updated if (this.extraScrollPaddingPx !== updateExtraScrollPaddingPx) { this.extraScrollPaddingPx = updateExtraScrollPaddingPx; _updateScrollPadding.call(this, [true]); } // update observer if smooth transition has changed, or hiddenElementsHeight has changed if (this.enableSmoothTransition !== updateEnableSmoothTransition || this.hiddenElementsHeight !== updateHiddenElementsHeight) { this.enableSmoothTransition = updateEnableSmoothTransition; this.hiddenElementsHeight = updateHiddenElementsHeight; this.rootMarginOffset = this.enableSmoothTransition ? updateHiddenElementsHeight : 0; _createObserver.call(this); } if (opts.observerBehavior) { this.observerBehavior = _getObserverBehavior.call(this, opts.observerBehavior); } _setObserver.call(this); // Create and dispatch custom event this[EventName$1.ON_UPDATE] = new CustomEvent(EventName$1.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName$1.ON_UPDATE]); return this; } /** * Remove the sticky. */; _proto.remove = function remove() { _teardownInstance.call(this); // remove this sticky reference from array of instances var index = stickies.indexOf(this); stickies.splice(index, 1); // Create and dispatch custom event this[EventName$1.ON_REMOVE] = new CustomEvent(EventName$1.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName$1.ON_REMOVE]); } /** * Get an array of sticky instances. * @returns {Object[]} Array of sticky instances. */; FixedSticky.getInstances = function getInstances() { return stickies; }; return FixedSticky; }(); var backToTopInstances = []; var Selector = { DATA_MOUNT: '[data-mount="fixed-back-to-top"]' }; var EventName = { SCROLL: 'scroll', ON_REMOVE: 'onRemove', ON_RESIZE: 'resize', ON_UPDATE: 'onUpdate' }; var Attributes = { TABINDEX: 'tabindex' }; var DISPLAY_BUTTON_THRESHOLD = 0.7; // percentage of the page where button will display var initialPageLoad = true; /** * Switch the back to top element between static and sticky */ function _scrollListener() { var _this = this; // use offset margin and subtract the top position of the sentinel var offsetWithSentinel = this.stickyElement.sentinel.offsetTop - this.offsetMarginTop; var scrollY = window.scrollY || window.pageYOffset; if (scrollY > offsetWithSentinel) { this.stickyElement.setObserverStatus(true); this.el.style.opacity = 1; } else { var timeout = initialPageLoad ? 0 : 175; // prevent button flashing on page load this.el.style.opacity = 0; setTimeout(function () { _this.el.classList.remove(ClassName.STUCK); _this.stickyElement.enableObserver = false; }, timeout); initialPageLoad = false; } } /** * Update sticky offset margin top value when browser height changes * and remove/create new sticky element */ function _onWindowResize() { // extra conditional check to prevent code from constantly running on resize if (this.offsetMarginTop !== window.mwf.Util.getDocumentHeight() * DISPLAY_BUTTON_THRESHOLD) { this.offsetMarginTop = window.mwf.Util.getDocumentHeight() * DISPLAY_BUTTON_THRESHOLD; this.stickyElement.remove(); this.stickyElement = new FixedSticky({ el: this.el, direction: Direction.BOTTOM }); } } /** * Class representing Back to Top. */ var FixedBackToTop = /*#__PURE__*/function () { /** * Create the Back to Top. * @param {Object} opts - The Back to Top options. * @param {Node} opts.el - The Back to Top DOM node. * @param {number} [opts.offsetMarginTop] - Offset in pixels from top of page where Back to Top should begin to be sticky. * @param {Function} [opts.onScroll] - Function to override the scroll event handler. * @param {Function} [opts.onWindowResize] - Function to override the window resize event handler. */ function FixedBackToTop(opts) { this.el = opts.el; this.offsetMarginTop = opts.offsetMarginTop || window.mwf.Util.getDocumentHeight() * DISPLAY_BUTTON_THRESHOLD; this.onScroll = opts.onScroll || _scrollListener.bind(this); this.onWindowResize = opts.onWindowResize || _onWindowResize.bind(this); this.setTabindex(); // Create custom events backToTopInstances.push(this); this.stickyElement = new FixedSticky({ el: this.el, direction: Direction.BOTTOM }); // Do the initial firing of the listener to set the state this.onScroll(); // attach event listeners this.events = { scrollEvent: { el: document, type: EventName.SCROLL, handler: throttle(200, this.onScroll), options: { passive: true } }, resizeEvent: { el: window, type: EventName.ON_RESIZE, handler: throttle(200, this.onWindowResize) } }; window.mwf.Util.addEvents(Object.values(this.events)); } /** * Check if the element needs a tabindex and set it */ var _proto = FixedBackToTop.prototype; _proto.setTabindex = function setTabindex() { var link = this.el.querySelector('a'); var href = link.getAttribute('href'); var targetElement = document.querySelector(href); var isElementFound = document.querySelector(href) !== null; if (isElementFound && // Only do something if the element is not tabbable !window.mwf.Util.isElementTabbable(targetElement)) { var tabindex = targetElement.getAttribute(Attributes.TABINDEX); // If we don't have a tabindex if (tabindex === null) { // Set the tabindex of the element to -1 targetElement.setAttribute(Attributes.TABINDEX, '-1'); } } } /** * Update the Back to Top. * @param {Object} [opts] - The Back to Top options. * @param {number} [opts.offsetMarginTop] - Offset in pixels from top of page where Back to Top should begin to be sticky. * @param {Function} [opts.onScroll] - Function to override the scroll event handler. * @param {Function} [opts.onWindowResize] - Function to override the window resize event handler. */; _proto.update = function update(opts) { if (opts === void 0) { opts = {}; } if (opts.offsetMarginTop) { this.offsetMarginTop = opts.offsetMarginTop; } if (opts.onScroll) { window.mwf.Util.removeEvents([this.events.scrollEvent]); this.onScroll = opts.onScroll; window.mwf.Util.addEvents([this.events.scrollEvent]); } if (opts.onWindowResize) { window.mwf.Util.removeEvents([this.events.resizeEvent]); this.onWindowResize = opts.onWindowResize; window.mwf.Util.addEvents([this.events.resizeEvent]); } // Do the initial firing of the listener to set the state this.onScroll(); // Create and dispatch custom event this[EventName.ON_UPDATE] = new CustomEvent(EventName.ON_UPDATE, { bubbles: true }); this.el.dispatchEvent(this[EventName.ON_UPDATE]); } /** * Remove the event listener from the back to top element */; _proto.remove = function remove() { window.mwf.Util.removeEvents(Object.values(this.events)); this.stickyElement.remove(); // remove this back to top reference from array of instances var index = backToTopInstances.indexOf(this); backToTopInstances.splice(index, 1); // Create and dispatch custom event this[EventName.ON_REMOVE] = new CustomEvent(EventName.ON_REMOVE, { bubbles: true }); this.el.dispatchEvent(this[EventName.ON_REMOVE]); } /** * Get back to top instances. * @returns {Object[]} Array of back to top instances */; FixedBackToTop.getInstances = function getInstances() { return backToTopInstances; }; return FixedBackToTop; }(); document.addEventListener('DOMContentLoaded', function () { initializeComponents(); document.dispatchEvent(new CustomEvent(JS_INITIALIZED)); }); var PLUGIN_INITIALIZED = 'mwfFixedStickyInitialized'; document.addEventListener('mwfInitialized', function () { window.mwf.Util.initializeComponent(Selector.DATA_MOUNT, function (el) { return new FixedBackToTop({ el: el }); }); window.mwf.Util.initializeComponent(Selector$1.DATA_MOUNT, function (el) { return new FixedSticky({ el: el }); }); document.dispatchEvent(new CustomEvent(PLUGIN_INITIALIZED)); }); exports.AIChatDrawer = AIChatDrawer; exports.AISearchForm = AISearchForm; exports.AlertExtension = AlertExtension; exports.Breadcrumbs = Breadcrumbs; exports.CardInteractiveSelector = CardInteractive; exports.CardStatSelector = CardStat; exports.ClipboardShare = ClipboardShare; exports.CollapseControlsExtension = CollapseControlsExtension; exports.CollapseExtension = CollapseExtension; exports.ContactSales = ContactSales; exports.DropdownExtension = DropdownExtension; exports.DropdownFilter = DropdownFilter; exports.DynamicContent = DynamicContent; exports.DynamicallyAddedFilters = DynamicallyAddedFilters; exports.Effects = Effects; exports.EventFinder = EventFinder; exports.FeaturedCardsInteractive = FeaturedCardsInteractive; exports.Filter = Filters; exports.FixedBackToTop = FixedBackToTop; exports.FixedSticky = FixedSticky; exports.Icon = Icon; exports.ModalExtension = Modal; exports.MultiCollapse = MultiCollapse; exports.MultiCollapseControls = MultiCollapseControls; exports.OcrAccordion = OcrAccordion; exports.OcrFixedSticky = OcrFixedSticky; exports.OcrScrollspy = OcrScrollspy; exports.OcrTab = OcrTab; exports.Pagination = Pagination; exports.ProactiveChat = ProactiveChat; exports.RollingText = RollingText; exports.ScrollSnapCarousel = SnapCarousel; exports.SelectorSlider = SelectorSlider; exports.SingleSelect = SingleSelect; exports.SolutionCenter = SolutionCenter; exports.TabSlider = TabSlider; exports.Table = Table; exports.TimeSlider = TimeSlider; exports.VideoExtension = VideoExtension; Object.defineProperty(exports, '__esModule', { value: true }); })); if (window.oneCloudReimagine) { document.dispatchEvent(new CustomEvent('oneCloudReimagineIntialized')); if (console && console.log && oneCloudReimagine.version) { console.log('OneCloud Reimagine v' + oneCloudReimagine.version); } }