PageSourceSearch

https://uniwersytetradom.pl/wp-content/plugins/elementor-pro/assets/js/frontend.js?ver=4.3.0

js uniwersytetradom.pl collected 2026-09-25 02:49:24 UTC 161,648 bytes, 4,427 lines download raw bytes

1/*! elementor-pro - v4.3.0 - 22-09-2026 */
2(function() {
3	//#region \0rolldown/runtime.js
4	var __defProp$1 = Object.defineProperty;
5	var __name = (target, value) => __defProp$1(target, "name", {
6		value,
7		configurable: true
8	});
9	var __esmMin = (fn, res, err) => () => {
10		if (err) throw err[0];
11		try {
12			return fn && (res = fn(fn = 0)), res;
13		} catch (e) {
14			throw err = [e], e;
15		}
16	};
17	var __exportAll = (all, no_symbols) => {
18		let target = {};
19		for (var name in all) __defProp$1(target, name, {
20			get: all[name],
21			enumerable: true
22		});
23		if (!no_symbols) __defProp$1(target, Symbol.toStringTag, { value: "Module" });
24		return target;
25	};
26	//#endregion
27	//#region assets/dev/js/public-path.js
28	__webpack_public_path__ = ElementorProFrontendConfig.urls.assets + "js/";
29	//#endregion
30	//#region \0@[email protected]/helpers/esm/typeof.js
31	function _typeof(o) {
32		"@babel/helpers - typeof";
33		return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
34			return typeof o;
35		} : function(o) {
36			return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
37		}, _typeof(o);
38	}
39	//#endregion
40	//#region \0@[email protected]/helpers/esm/toPrimitive.js
41	function toPrimitive(t, r) {
42		if ("object" != _typeof(t) || !t) return t;
43		var e = t[Symbol.toPrimitive];
44		if (void 0 !== e) {
45			var i = e.call(t, r || "default");
46			if ("object" != _typeof(i)) return i;
47			throw new TypeError("@@toPrimitive must return a primitive value.");
48		}
49		return ("string" === r ? String : Number)(t);
50	}
51	//#endregion
52	//#region \0@[email protected]/helpers/esm/toPropertyKey.js
53	function toPropertyKey(t) {
54		var i = toPrimitive(t, "string");
55		return "symbol" == _typeof(i) ? i : i + "";
56	}
57	//#endregion
58	//#region \0@[email protected]/helpers/esm/defineProperty.js
59	function _defineProperty(e, r, t) {
60		return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
61			value: t,
62			enumerable: !0,
63			configurable: !0,
64			writable: !0
65		}) : e[r] = t, e;
66	}
67	//#endregion
68	//#region modules/motion-fx/assets/js/frontend/motion-fx/interactions/base.js
69	var base_default = class extends elementorModules.ViewModule {
70		static {
71			__name(this, "default");
72		}
73		constructor(..._args) {
74			super(..._args);
75			_defineProperty(this, "onInsideViewport", () => {
76				this.run();
77				this.animationFrameRequest = requestAnimationFrame(this.onInsideViewport);
78			});
79		}
80		__construct(options) {
81			this.motionFX = options.motionFX;
82			if (!this.intersectionObservers) this.setElementInViewportObserver();
83		}
84		setElementInViewportObserver() {
85			this.intersectionObserver = elementorModules.utils.Scroll.scrollObserver({ callback: (event) => {
86				if (event.isInViewport) this.onInsideViewport();
87				else this.removeAnimationFrameRequest();
88			} });
89			const observedElement = "page" === this.motionFX.getSettings("range") ? elementorFrontend.elements.$body[0] : this.motionFX.elements.$parent[0];
90			this.intersectionObserver.observe(observedElement);
91		}
92		runCallback(...args) {
93			this.getSettings("callback")(...args);
94		}
95		removeIntersectionObserver() {
96			if (this.intersectionObserver) this.intersectionObserver.unobserve(this.motionFX.elements.$parent[0]);
97		}
98		removeAnimationFrameRequest() {
99			if (this.animationFrameRequest) cancelAnimationFrame(this.animationFrameRequest);
100		}
101		destroy() {
102			this.removeAnimationFrameRequest();
103			this.removeIntersectionObserver();
104		}
105		onInit() {
106			super.onInit();
107		}
108	};
109	//#endregion
110	//#region modules/motion-fx/assets/js/frontend/motion-fx/interactions/scroll.js
111	var scroll_default = class extends base_default {
112		static {
113			__name(this, "default");
114		}
115		run() {
116			if (pageYOffset === this.windowScrollTop) return false;
117			this.onScrollMovement();
118			this.windowScrollTop = pageYOffset;
119		}
120		onScrollMovement() {
121			this.updateMotionFxDimensions();
122			this.updateAnimation();
123			this.resetTransitionVariable();
124		}
125		resetTransitionVariable() {
126			this.motionFX.$element.css("--e-transform-transition-duration", "100ms");
127		}
128		updateMotionFxDimensions() {
129			if (this.motionFX.getSettings().refreshDimensions) this.motionFX.defineDimensions();
130		}
131		updateAnimation() {
132			let passedRangePercents;
133			if ("page" === this.motionFX.getSettings("range")) passedRangePercents = elementorModules.utils.Scroll.getPageScrollPercentage();
134			else if (this.motionFX.getSettings("isFixedPosition")) passedRangePercents = elementorModules.utils.Scroll.getPageScrollPercentage({}, window.innerHeight);
135			else passedRangePercents = elementorModules.utils.Scroll.getElementViewportPercentage(this.motionFX.elements.$parent);
136			this.runCallback(passedRangePercents);
137		}
138	};
139	//#endregion
140	//#region modules/motion-fx/assets/js/frontend/motion-fx/interactions/mouse-move.js
141	var MouseMoveInteraction = class MouseMoveInteraction extends base_default {
142		bindEvents() {
143			if (!MouseMoveInteraction.mouseTracked) {
144				elementorFrontend.elements.$window.on("mousemove", MouseMoveInteraction.updateMousePosition);
145				MouseMoveInteraction.mouseTracked = true;
146			}
147		}
148		run() {
149			const mousePosition = MouseMoveInteraction.mousePosition;
150			const oldMousePosition = this.oldMousePosition;
151			if (oldMousePosition.x === mousePosition.x && oldMousePosition.y === mousePosition.y) return;
152			this.oldMousePosition = {
153				x: mousePosition.x,
154				y: mousePosition.y
155			};
156			const passedPercentsX = 100 / innerWidth * mousePosition.x;
157			const passedPercentsY = 100 / innerHeight * mousePosition.y;
158			this.runCallback(passedPercentsX, passedPercentsY);
159		}
160		onInit() {
161			this.oldMousePosition = {};
162			super.onInit();
163		}
164	};
165	MouseMoveInteraction.mousePosition = {};
166	MouseMoveInteraction.updateMousePosition = (event) => {
167		MouseMoveInteraction.mousePosition = {
168			x: event.clientX,
169			y: event.clientY
170		};
171	};
172	//#endregion
173	//#region modules/motion-fx/assets/js/frontend/motion-fx/actions.js
174	var actions_default = class extends elementorModules.Module {
175		static {
176			__name(this, "default");
177		}
178		getMovePointFromPassedPercents(movableRange, passedPercents) {
179			return +(passedPercents / movableRange * 100).toFixed(2);
180		}
181		getEffectValueFromMovePoint(range, movePoint) {
182			return range * movePoint / 100;
183		}
184		getStep(passedPercents, options) {
185			if ("element" === this.getSettings("type")) return this.getElementStep(passedPercents, options);
186			return this.getBackgroundStep(passedPercents, options);
187		}
188		getElementStep(passedPercents, options) {
189			return -(passedPercents - 50) * options.speed;
190		}
191		getBackgroundStep(passedPercents, options) {
192			const movableRange = this.getSettings("dimensions.movable" + options.axis.toUpperCase());
193			return -this.getEffectValueFromMovePoint(movableRange, passedPercents);
194		}
195		getDirectionMovePoint(passedPercents, direction, range) {
196			let movePoint;
197			if (passedPercents < range.start) if ("out-in" === direction) movePoint = 0;
198			else if ("in-out" === direction) movePoint = 100;
199			else {
200				movePoint = this.getMovePointFromPassedPercents(range.start, passedPercents);
201				if ("in-out-in" === direction) movePoint = 100 - movePoint;
202			}
203			else if (passedPercents < range.end) if ("in-out-in" === direction) movePoint = 0;
204			else if ("out-in-out" === direction) movePoint = 100;
205			else {
206				movePoint = this.getMovePointFromPassedPercents(range.end - range.start, passedPercents - range.start);
207				if ("in-out" === direction) movePoint = 100 - movePoint;
208			}
209			else if ("in-out" === direction) movePoint = 0;
210			else if ("out-in" === direction) movePoint = 100;
211			else {
212				movePoint = this.getMovePointFromPassedPercents(100 - range.end, 100 - passedPercents);
213				if ("in-out-in" === direction) movePoint = 100 - movePoint;
214			}
215			return movePoint;
216		}
217		translateX(actionData, passedPercents) {
218			actionData.axis = "x";
219			actionData.unit = "px";
220			this.transform("translateX", passedPercents, actionData);
221		}
222		translateY(actionData, passedPercents) {
223			actionData.axis = "y";
224			actionData.unit = "px";
225			this.transform("translateY", passedPercents, actionData);
226		}
227		translateXY(actionData, passedPercentsX, passedPercentsY) {
228			this.translateX(actionData, passedPercentsX);
229			this.translateY(actionData, passedPercentsY);
230		}
231		tilt(actionData, passedPercentsX, passedPercentsY) {
232			const options = {
233				speed: actionData.speed / 10,
234				direction: actionData.direction
235			};
236			this.rotateX(options, passedPercentsY);
237			this.rotateY(options, 100 - passedPercentsX);
238		}
239		rotateX(actionData, passedPercents) {
240			actionData.axis = "x";
241			actionData.unit = "deg";
242			this.transform("rotateX", passedPercents, actionData);
243		}
244		rotateY(actionData, passedPercents) {
245			actionData.axis = "y";
246			actionData.unit = "deg";
247			this.transform("rotateY", passedPercents, actionData);
248		}
249		rotateZ(actionData, passedPercents) {
250			actionData.unit = "deg";
251			this.transform("rotateZ", passedPercents, actionData);
252		}
253		scale(actionData, passedPercents) {
254			const movePoint = this.getDirectionMovePoint(passedPercents, actionData.direction, actionData.range);
255			this.updateRulePart("transform", "scale", 1 + actionData.speed * movePoint / 1e3);
256		}
257		transform(action, passedPercents, actionData) {
258			if (actionData.direction) passedPercents = 100 - passedPercents;
259			this.updateRulePart("transform", action, this.getStep(passedPercents, actionData) + actionData.unit);
260		}
261		setCSSTransformVariables(elementSettings) {
262			this.CSSTransformVariables = [];
263			jQuery.each(elementSettings, (settingKey, settingValue) => {
264				const transformKeyMatches = settingKey.match(/_transform_(.+?)_effect/m);
265				if (transformKeyMatches && settingValue) {
266					if ("perspective" === transformKeyMatches[1]) {
267						this.CSSTransformVariables.unshift(transformKeyMatches[1]);
268						return;
269					}
270					if (this.CSSTransformVariables.includes(transformKeyMatches[1])) return;
271					this.CSSTransformVariables.push(transformKeyMatches[1]);
272				}
273			});
274		}
275		opacity(actionData, passedPercents) {
276			const movePoint = this.getDirectionMovePoint(passedPercents, actionData.direction, actionData.range);
277			const level = actionData.level / 10;
278			const opacity = 1 - level + this.getEffectValueFromMovePoint(level, movePoint);
279			this.$element.css({
280				opacity,
281				"will-change": "opacity"
282			});
283		}
284		blur(actionData, passedPercents) {
285			const movePoint = this.getDirectionMovePoint(passedPercents, actionData.direction, actionData.range);
286			const blur = actionData.level - this.getEffectValueFromMovePoint(actionData.level, movePoint);
287			this.updateRulePart("filter", "blur", blur + "px");
288		}
289		updateRulePart(ruleName, key, value) {
290			if (!this.rulesVariables[ruleName]) this.rulesVariables[ruleName] = {};
291			if (!this.rulesVariables[ruleName][key]) {
292				this.rulesVariables[ruleName][key] = true;
293				this.updateRule(ruleName);
294			}
295			const cssVarKey = `--${key}`;
296			this.$element[0].style.setProperty(cssVarKey, value);
297		}
298		updateRule(ruleName) {
299			let value = "";
300			value += this.concatTransformCSSProperties(ruleName);
301			value += this.concatTransformMotionEffectCSSProperties(ruleName);
302			this.$element.css(ruleName, value);
303		}
304		concatTransformCSSProperties(ruleName) {
305			let value = "";
306			if ("transform" === ruleName) jQuery.each(this.CSSTransformVariables, (index, variableKey) => {
307				const variableName = variableKey;
308				if (variableKey.startsWith("flip")) variableKey = variableKey.replace("flip", "scale");
309				const defaultUnit = variableKey.startsWith("rotate") || variableKey.startsWith("skew") ? "deg" : "px";
310				const defaultValue = variableKey.startsWith("scale") ? 1 : 0 + defaultUnit;
311				value += `${variableKey}(var(--e-transform-${variableName}, ${defaultValue}))`;
312			});
313			return value;
314		}
315		concatTransformMotionEffectCSSProperties(ruleName) {
316			let value = "";
317			jQuery.each(this.rulesVariables[ruleName], (variableKey) => {
318				value += `${variableKey}(var(--${variableKey}))`;
319			});
320			return value;
321		}
322		runAction(actionName, actionData, passedPercents, ...args) {
323			if (actionData.affectedRange) {
324				if (actionData.affectedRange.start > passedPercents) passedPercents = actionData.affectedRange.start;
325				if (actionData.affectedRange.end < passedPercents) passedPercents = actionData.affectedRange.end;
326			}
327			this[actionName](actionData, passedPercents, ...args);
328		}
329		refresh() {
330			this.rulesVariables = {};
331			this.CSSTransformVariables = [];
332			this.$element.css({
333				transform: "",
334				filter: "",
335				opacity: "",
336				"will-change": ""
337			});
338		}
339		onInit() {
340			this.$element = this.getSettings("$targetElement");
341			this.refresh();
342		}
343	};
344	//#endregion
345	//#region modules/motion-fx/assets/js/frontend/motion-fx/motion-fx.js
346	var motion_fx_default = class extends elementorModules.ViewModule {
347		static {
348			__name(this, "default");
349		}
350		getDefaultSettings() {
351			return {
352				type: "element",
353				$element: null,
354				$dimensionsElement: null,
355				addBackgroundLayerTo: null,
356				interactions: {},
357				refreshDimensions: false,
358				range: "viewport",
359				classes: {
360					element: "motion-fx-element",
361					parent: "motion-fx-parent",
362					backgroundType: "motion-fx-element-type-background",
363					container: "motion-fx-container",
364					layer: "motion-fx-layer",
365					perspective: "motion-fx-perspective"
366				}
367			};
368		}
369		bindEvents() {
370			this.defineDimensions = this.defineDimensions.bind(this);
371			elementorFrontend.elements.$window.on("resize elementor-pro/motion-fx/recalc", this.defineDimensions);
372		}
373		unbindEvents() {
374			elementorFrontend.elements.$window.off("resize elementor-pro/motion-fx/recalc", this.defineDimensions);
375		}
376		addBackgroundLayer() {
377			const settings = this.getSettings();
378			this.elements.$motionFXContainer = jQuery("<div>", { class: settings.classes.container });
379			this.elements.$motionFXLayer = jQuery("<div>", { class: settings.classes.layer });
380			this.updateBackgroundLayerSize();
381			this.elements.$motionFXContainer.prepend(this.elements.$motionFXLayer);
382			(settings.addBackgroundLayerTo ? this.$element.find(settings.addBackgroundLayerTo) : this.$element).prepend(this.elements.$motionFXContainer);
383		}
384		removeBackgroundLayer() {
385			this.elements.$motionFXContainer.remove();
386		}
387		updateBackgroundLayerSize() {
388			const settings = this.getSettings();
389			const speed = {
390				x: 0,
391				y: 0
392			};
393			const mouseInteraction = settings.interactions.mouseMove;
394			const scrollInteraction = settings.interactions.scroll;
395			if (mouseInteraction && mouseInteraction.translateXY) {
396				speed.x = mouseInteraction.translateXY.speed * 10;
397				speed.y = mouseInteraction.translateXY.speed * 10;
398			}
399			if (scrollInteraction) {
400				if (scrollInteraction.translateX) speed.x = scrollInteraction.translateX.speed * 10;
401				if (scrollInteraction.translateY) speed.y = scrollInteraction.translateY.speed * 10;
402			}
403			this.elements.$motionFXLayer.css({
404				width: 100 + speed.x + "%",
405				height: 100 + speed.y + "%"
406			});
407		}
408		defineDimensions() {
409			const $dimensionsElement = this.getSettings("$dimensionsElement") || this.$element;
410			const elementOffset = $dimensionsElement.offset();
411			const dimensions = {
412				elementHeight: $dimensionsElement.outerHeight(),
413				elementWidth: $dimensionsElement.outerWidth(),
414				elementTop: elementOffset.top,
415				elementLeft: elementOffset.left
416			};
417			dimensions.elementRange = dimensions.elementHeight + innerHeight;
418			this.setSettings("dimensions", dimensions);
419			if ("background" === this.getSettings("type")) this.defineBackgroundLayerDimensions();
420		}
421		defineBackgroundLayerDimensions() {
422			const dimensions = this.getSettings("dimensions");
423			dimensions.layerHeight = this.elements.$motionFXLayer.height();
424			dimensions.layerWidth = this.elements.$motionFXLayer.width();
425			dimensions.movableX = dimensions.layerWidth - dimensions.elementWidth;
426			dimensions.movableY = dimensions.layerHeight - dimensions.elementHeight;
427			this.setSettings("dimensions", dimensions);
428		}
429		initInteractionsTypes() {
430			this.interactionsTypes = {
431				scroll: scroll_default,
432				mouseMove: MouseMoveInteraction
433			};
434		}
435		prepareSpecialActions() {
436			const settings = this.getSettings();
437			const hasTiltEffect = !!(settings.interactions.mouseMove && settings.interactions.mouseMove.tilt);
438			this.elements.$parent.toggleClass(settings.classes.perspective, hasTiltEffect);
439		}
440		cleanSpecialActions() {
441			const settings = this.getSettings();
442			this.elements.$parent.removeClass(settings.classes.perspective);
443		}
444		runInteractions() {
445			const settings = this.getSettings();
446			this.actions.setCSSTransformVariables(settings.elementSettings);
447			this.prepareSpecialActions();
448			jQuery.each(settings.interactions, (interactionName, actions) => {
449				this.interactions[interactionName] = new this.interactionsTypes[interactionName]({
450					motionFX: this,
451					callback: (...args) => {
452						jQuery.each(actions, (actionName, actionData) => this.actions.runAction(actionName, actionData, ...args));
453					}
454				});
455				this.interactions[interactionName].run();
456			});
457		}
458		destroyInteractions() {
459			this.cleanSpecialActions();
460			jQuery.each(this.interactions, (interactionName, interaction) => interaction.destroy());
461			this.interactions = {};
462		}
463		refresh() {
464			this.actions.setSettings(this.getSettings());
465			if ("background" === this.getSettings("type")) {
466				this.updateBackgroundLayerSize();
467				this.defineBackgroundLayerDimensions();
468			}
469			this.actions.refresh();
470			this.destroyInteractions();
471			this.runInteractions();
472		}
473		destroy() {
474			this.destroyInteractions();
475			this.actions.refresh();
476			const settings = this.getSettings();
477			this.$element.removeClass(settings.classes.element);
478			this.elements.$parent.removeClass(settings.classes.parent);
479			if ("background" === settings.type) {
480				this.$element.removeClass(settings.classes.backgroundType);
481				this.removeBackgroundLayer();
482			}
483		}
484		onInit() {
485			super.onInit();
486			const settings = this.getSettings();
487			this.$element = settings.$element;
488			this.elements.$parent = this.$element.parent();
489			this.$element.addClass(settings.classes.element);
490			this.elements.$parent = this.$element.parent();
491			this.elements.$parent.addClass(settings.classes.parent);
492			if ("background" === settings.type) {
493				this.$element.addClass(settings.classes.backgroundType);
494				this.addBackgroundLayer();
495			}
496			this.defineDimensions();
497			settings.$targetElement = "element" === settings.type ? this.$element : this.elements.$motionFXLayer;
498			this.interactions = {};
499			this.actions = new actions_default(settings);
500			this.initInteractionsTypes();
501			this.runInteractions();
502		}
503	};
504	//#endregion
505	//#region modules/motion-fx/assets/js/frontend/handler.js
506	var handler_default = class extends elementorModules.frontend.handlers.Base {
507		static {
508			__name(this, "default");
509		}
510		__construct(...args) {
511			super.__construct(...args);
512			this.toggle = elementorFrontend.debounce(this.toggle, 200);
513		}
514		getDefaultSettings() {
515			return { selectors: { container: ".elementor-widget-container" } };
516		}
517		getDefaultElements() {
518			const selectors = this.getSettings("selectors");
519			let container = this.$element.find(selectors.container);
520			if (0 === container.length) container = this.$element;
521			return { $container: container };
522		}
523		bindEvents() {
524			elementorFrontend.elements.$window.on("resize", this.toggle);
525		}
526		unbindEvents() {
527			elementorFrontend.elements.$window.off("resize", this.toggle);
528		}
529		addCSSTransformEvents() {
530			if (this.getElementSettings("motion_fx_motion_fx_scrolling") && !this.isTransitionEventAdded) {
531				this.isTransitionEventAdded = true;
532				this.elements.$container.on("mouseenter", () => {
533					this.elements.$container.css("--e-transform-transition-duration", "");
534				});
535			}
536		}
537		initEffects() {
538			this.effects = {
539				translateY: {
540					interaction: "scroll",
541					actions: ["translateY"]
542				},
543				translateX: {
544					interaction: "scroll",
545					actions: ["translateX"]
546				},
547				rotateZ: {
548					interaction: "scroll",
549					actions: ["rotateZ"]
550				},
551				scale: {
552					interaction: "scroll",
553					actions: ["scale"]
554				},
555				opacity: {
556					interaction: "scroll",
557					actions: ["opacity"]
558				},
559				blur: {
560					interaction: "scroll",
561					actions: ["blur"]
562				},
563				mouseTrack: {
564					interaction: "mouseMove",
565					actions: ["translateXY"]
566				},
567				tilt: {
568					interaction: "mouseMove",
569					actions: ["tilt"]
570				}
571			};
572		}
573		prepareOptions(name) {
574			const elementSettings = this.getElementSettings();
575			const type = "motion_fx" === name ? "element" : "background";
576			const interactions = {};
577			jQuery.each(elementSettings, (key, value) => {
578				const keyRegex = new RegExp("^" + name + "_(.+?)_effect");
579				const keyMatches = key.match(keyRegex);
580				if (!keyMatches || !value) return;
581				const options = {};
582				const effectName = keyMatches[1];
583				jQuery.each(elementSettings, (subKey, subValue) => {
584					const subKeyRegex = new RegExp(name + "_" + effectName + "_(.+)");
585					const subKeyMatches = subKey.match(subKeyRegex);
586					if (!subKeyMatches) return;
587					if ("effect" === subKeyMatches[1]) return;
588					if ("object" === typeof subValue) subValue = Object.keys(subValue.sizes).length ? subValue.sizes : subValue.size;
589					options[subKeyMatches[1]] = subValue;
590				});
591				const effect = this.effects[effectName];
592				const interactionName = effect.interaction;
593				if (!interactions[interactionName]) interactions[interactionName] = {};
594				effect.actions.forEach((action) => interactions[interactionName][action] = options);
595			});
596			let $element = this.$element;
597			let $dimensionsElement;
598			let $childElement;
599			const elementType = this.getElementType();
600			if ("element" === type && !["section", "container"].includes(elementType)) {
601				$dimensionsElement = $element;
602				let childElementSelector;
603				if ("column" === elementType) childElementSelector = ".elementor-widget-wrap";
604				else childElementSelector = ".elementor-widget-container";
605				$childElement = $element.find("> " + childElementSelector);
606				$element = 0 === $childElement.length ? this.$element : $childElement;
607			}
608			const options = {
609				type,
610				interactions,
611				elementSettings,
612				$element,
613				$dimensionsElement,
614				refreshDimensions: this.isEdit,
615				range: elementSettings[name + "_range"],
616				classes: {
617					element: "elementor-motion-effects-element",
618					parent: "elementor-motion-effects-parent",
619					backgroundType: "elementor-motion-effects-element-type-background",
620					container: "elementor-motion-effects-container",
621					layer: "elementor-motion-effects-layer",
622					perspective: "elementor-motion-effects-perspective"
623				}
624			};
625			if (!options.range && "fixed" === this.getCurrentDeviceSetting("_position")) options.range = "page";
626			if ("fixed" === this.getCurrentDeviceSetting("_position")) options.isFixedPosition = true;
627			if ("background" === type && "column" === this.getElementType()) options.addBackgroun
627dLayerTo = " > .elementor-element-populated";
628			return options;
629		}
630		activate(name) {
631			const options = this.prepareOptions(name);
632			if (jQuery.isEmptyObject(options.interactions)) return;
633			this[name] = new motion_fx_default(options);
634		}
635		deactivate(name) {
636			if (this[name]) {
637				this[name].destroy();
638				delete this[name];
639			}
640		}
641		toggle() {
642			const currentDeviceMode = elementorFrontend.getCurrentDeviceMode();
643			const elementSettings = this.getElementSettings();
644			["motion_fx", "background_motion_fx"].forEach((name) => {
645				const devices = elementSettings[name + "_devices"];
646				if ((!devices || -1 !== devices.indexOf(currentDeviceMode)) && (elementSettings[name + "_motion_fx_scrolling"] || elementSettings[name + "_motion_fx_mouse"])) if (this[name]) this.refreshInstance(name);
647				else this.activate(name);
648				else this.deactivate(name);
649			});
650		}
651		refreshInstance(instanceName) {
652			const instance = this[instanceName];
653			if (!instance) return;
654			const preparedOptions = this.prepareOptions(instanceName);
655			instance.setSettings(preparedOptions);
656			instance.refresh();
657		}
658		onInit() {
659			super.onInit();
660			const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
661			if (prefersReducedMotion && prefersReducedMotion.matches) return;
662			this.initEffects();
663			this.addCSSTransformEvents();
664			this.toggle();
665		}
666		onElementChange(propertyName) {
667			if (/motion_fx_((scrolling)|(mouse)|(devices))$/.test(propertyName)) {
668				if ("motion_fx_motion_fx_scrolling" === propertyName) this.addCSSTransformEvents();
669				this.toggle();
670				return;
671			}
672			const propertyMatches = propertyName.match(".*?(motion_fx|_transform)");
673			if (propertyMatches) {
674				const instanceName = propertyMatches[0].match("(_transform)") ? "motion_fx" : propertyMatches[0];
675				this.refreshInstance(instanceName);
676				if (!this[instanceName]) this.activate(instanceName);
677			}
678			if (/^_position/.test(propertyName)) ["motion_fx", "background_motion_fx"].forEach((instanceName) => {
679				this.refreshInstance(instanceName);
680			});
681		}
682		onDestroy() {
683			super.onDestroy();
684			["motion_fx", "background_motion_fx"].forEach((name) => {
685				this.deactivate(name);
686			});
687		}
688	};
689	//#endregion
690	//#region modules/motion-fx/assets/js/frontend/frontend.js
691	var frontend_default$5 = class extends elementorModules.Module {
692		static {
693			__name(this, "default");
694		}
695		constructor() {
696			super();
697			elementorFrontend.elementsHandler.attachHandler("global", handler_default, null);
698		}
699	};
700	//#endregion
701	//#region ../elementor/assets/dev/js/frontend/utils/utils.js
702	var isScrollSnapActive = () => {
703		var _a;
704		var _b;
705		return "yes" === (elementorFrontend.isEditMode() ? (_a = elementor.settings.page.model.attributes) == null ? void 0 : _a.scroll_snap : (_b = elementorFrontend.config.settings.page) == null ? void 0 : _b.scroll_snap) ? true : false;
706	};
707	//#endregion
708	//#region modules/sticky/assets/js/frontend/handlers/sticky.js
709	var sticky_default = elementorModules.frontend.handlers.Base.extend({
710		currentConfig: {},
711		debouncedReactivate: null,
712		bindEvents() {
713			elementorFrontend.addListenerOnce(this.getUniqueHandlerID() + "sticky", "resize", this.reactivateOnResize);
714		},
715		unbindEvents() {
716			elementorFrontend.removeListeners(this.getUniqueHandlerID() + "sticky", "resize", this.reactivateOnResize);
717		},
718		isStickyInstanceActive() {
719			return void 0 !== this.$element.data("sticky");
720		},
721		/**
722		* Get the current active setting value for a responsive control.
723		*
724		* @param {string} setting
725		* @return {any} - Setting value.
726		*/
727		getResponsiveSetting(setting) {
728			const elementSettings = this.getElementSettings();
729			return elementorFrontend.getCurrentDeviceSetting(elementSettings, setting);
730		},
731		/**
732		* Return an array of settings names for responsive control (e.g. `settings`, `setting_tablet`, `setting_mobile` ).
733		*
734		* @param {string} setting
735		* @return {string[]} - List of settings.
736		*/
737		getResponsiveSettingList(setting) {
738			return ["", ...Object.keys(elementorFrontend.config.responsive.activeBreakpoints)].map((suffix) => {
739				return suffix ? `${setting}_${suffix}` : setting;
740			});
741		},
742		getConfig() {
743			const elementSettings = this.getElementSettings();
744			const stickyOptions = {
745				to: elementSettings.sticky,
746				offset: this.getResponsiveSetting("sticky_offset"),
747				effectsOffset: this.getResponsiveSetting("sticky_effects_offset"),
748				classes: {
749					sticky: "elementor-sticky",
750					stickyActive: "elementor-sticky--active elementor-section--handles-inside",
751					stickyEffects: "elementor-sticky--effects",
752					spacer: "elementor-sticky__spacer"
753				},
754				isRTL: elementorFrontend.config.is_rtl,
755				isScrollSnapActive: isScrollSnapActive(),
756				handleScrollbarWidth: elementorFrontend.isEditMode()
757			};
758			const $wpAdminBar = elementorFrontend.elements.$wpAdminBar;
759			const isParentContainer = this.isContainerElement(this.$element[0]) && !this.isContainerElement(this.$element[0].parentElement);
760			if ($wpAdminBar.length && "top" === elementSettings.sticky && "fixed" === $wpAdminBar.css("position")) stickyOptions.offset += $
760wpAdminBar.height();
761			if (elementSettings.sticky_parent && !isParentContainer) stickyOptions.parent = ".e-con, .e-con-inner, .elementor-widget-wrap";
762			return stickyOptions;
763		},
764		activate() {
765			this.currentConfig = this.getConfig();
766			this.$element.sticky(this.currentConfig);
767		},
768		deactivate() {
769			if (!this.isStickyInstanceActive()) return;
770			this.$element.sticky("destroy");
771		},
772		run(refresh) {
773			if (!this.getElementSettings("sticky")) {
774				this.deactivate();
775				return;
776			}
777			var currentDeviceMode = elementorFrontend.getCurrentDeviceMode();
778			if (-1 !== this.getElementSettings("sticky_on").indexOf(currentDeviceMode)) {
779				if (true === refresh) this.reactivate();
780				else if (!this.isStickyInstanceActive()) this.activate();
781			} else this.deactivate();
782		},
783		/**
784		* Reactivate the sticky instance on resize only if the new sticky config is different from the current active one,
785		* in order to avoid re-initializing the sticky when not needed, and avoid layout shifts.
786		* The config can be different between devices, so this need to be checked on each screen resize to make sure that
787		* the current screen size uses the appropriate Sticky config.
788		*
789		* @return {void}
790		*/
791		reactivateOnResize() {
792			clearTimeout(this.debouncedReactivate);
793			this.debouncedReactivate = setTimeout(() => {
794				const config = this.getConfig();
795				if (JSON.stringify(config) !== JSON.stringify(this.currentConfig)) this.run(true);
796			}, 300);
797		},
798		reactivate() {
799			this.deactivate();
800			this.activate();
801		},
802		onElementChange(settingKey) {
803			if (-1 !== ["sticky", "sticky_on"].indexOf(settingKey)) this.run(true);
804			if (-1 !== [
805				...this.getResponsiveSettingList("sticky_offset"),
806				...this.getResponsiveSettingList("sticky_effects_offset"),
807				"sticky_parent"
808			].indexOf(settingKey)) this.reactivate();
809		},
810		/**
811		* Listen to device mode changes and re-initialize the sticky.
812		*
813		* @return {void}
814		*/
815		onDeviceModeChange() {
816			setTimeout(() => this.run(true));
817		},
818		onInit() {
819			elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments);
820			if (elementorFrontend.isEditMode()) elementor.listenTo(elementor.channels.deviceMode, "change", () => this.onDeviceModeChange());
821			this.run();
822		},
823		onDestroy() {
824			elementorModules.frontend.handlers.Base.prototype.onDestroy.apply(this, arguments);
825			this.deactivate();
826		},
827		/**
828		*
829		* @param {HTMLElement|null|undefined} element
830		* @return {boolean} Is the passed element a container.
831		*/
832		isContainerElement(element) {
833			return ["e-con", "e-con-inner"].some((containerClass) => {
834				return element === null || element === void 0 ? void 0 : element.classList.contains(containerClass);
835			});
836		}
837	});
838	//#endregion
839	//#region modules/sticky/assets/js/frontend/frontend.js
840	var frontend_default$4 = class extends elementorModules.Module {
841		static {
842			__name(this, "default");
843		}
844		constructor() {
845			super();
846			elementorFrontend.elementsHandler.attachHandler("section", sticky_default, null);
847			elementorFrontend.elementsHandler.attachHandler("container", sticky_default, null);
848			elementorFrontend.elementsHandler.attachHandler("widget", sticky_default, null);
849		}
850	};
851	var __vitePreload = function preload(baseModule, deps, importerUrl) {
852		let promise = Promise.resolve();
853		function handlePreloadError(err) {
854			const e = new Event("vite:preloadError", { cancelable: true });
855			e.payload = err;
856			window.dispatchEvent(e);
857			if (!e.defaultPrevented) throw err;
858		}
859		return promise.then((res) => {
860			for (const item of res || []) {
861				if (item.status !== "rejected") continue;
862				handlePreloadError(item.reason);
863			}
864			return baseModule().catch(handlePreloadError);
865		});
866	};
867	//#endregion
868	//#region modules/code-highlight/assets/js/frontend/handler.js
869	var handler_exports$1 = /* @__PURE__ */ __exportAll({ default: () => codeHighlightHandler });
870	var codeHighlightHandler;
871	var init_handler$1 = __esmMin((() => {
872		codeHighlightHandler = class extends elementorModules.frontend.handlers.Base {
873			onInit(...args) {
874				super.onInit(...args);
875				Prism.highlightAllUnder(this.$element[0], false);
876			}
877			onElementChange() {
878				Prism.highlightAllUnder(this.$element[0], false);
879			}
880		};
881	}));
882	//#endregion
883	//#region modules/code-highlight/assets/js/frontend/frontend.js
884	var frontend_default$3 = class extends elementorModules.Module {
885		static {
886			__name(this, "default");
887		}
888		constructor() {
889			super();
890			elementorFrontend.elementsHandler.attachHandler("code-highlight", () => __vitePreload(() => Promise.resolve().then(() => (init_handler$1(), handler_exports$1)), void 0));
891		}
892	};
893	//#endregion
894	//#region \0@[email protected]/helpers/esm/asyncToGenerator.js
895	function asyncGeneratorStep(n, t, e, r, o, a, c) {
896		try {
897			var i = n[a](c);
898			var u = i.value;
899		} catch (n) {
900			e(n);
901			return;
902		}
903		i.done ? t(u) : Promise.resolve(u).then(r, o);
904	}
905	function _asyncToGenerator(n) {
906		return function() {
907			var t = this;
908			var e = arguments;
909			return new Promise(function(r, o) {
910				var a = n.apply(t, e);
911				function _next(n) {
912					asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
913				}
914				function _throw(n) {
915					asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
916				}
917				_next(void 0);
918			});
919		};
920	}
921	var init_asyncToGenerator = __esmMin((() => {}));
922	//#endregion
923	//#region modules/video-playlist/assets/js/frontend/base-tabs.js
924	var baseTabs;
925	var init_base_tabs = __esmMin((() => {
926		baseTabs = class extends elementorModules.frontend.handlers.Base {
927			getDefaultSettings() {
928				return {
929					selectors: {
930						tablist: "[role=\"tablist\"]",
931						tabTitle: ".e-tab-title",
932						tabContent: ".e-tab-content"
933					},
934					classes: { active: "e-active" },
935					showTabFn: "show",
936					hideTabFn: "hide",
937					toggleSelf: true,
938					hidePrevious: true,
939					autoExpand: true,
940					keyDirection: {
941						ArrowLeft: elementorFrontendConfig.is_rtl ? 1 : -1,
942						ArrowUp: -1,
943						ArrowRight: elementorFrontendConfig.is_rtl ? -1 : 1,
944						ArrowDown: 1
945					}
946				};
947			}
948			getDefaultElements() {
949				const selectors = this.getSettings("selectors");
950				return {
951					$tabTitles: this.findElement(selectors.tabTitle),
952					$tabContents: this.findElement(selectors.tabContent)
953				};
954			}
955			activateDefaultTab(videoId) {
956				const settings = this.getSettings();
957				if (!settings.autoExpand || "editor" === settings.autoExpand && !this.isEdit) return;
958				const defaultActiveTab = this.getEditSettings("activeItemIndex") || videoId || 1;
959				const originalToggleMethods = {
960					showTabFn: settings.showTabFn,
961					hideTabFn: settings.hideTabFn
962				};
963				this.setSettings({
964					showTabFn: "show",
965					hideTabFn: "hide"
966				});
967				this.changeActiveTab(defaultActiveTab);
968				this.setSettings(originalToggleMethods);
969			}
970			handleKeyboardNavigation(event) {
971				const tab = event.currentTarget;
972				const $tabList = jQuery(tab.closest(this.getSettings("selectors").tablist));
973				const $tabs = $tabList.find(this.getSettings("selectors").tabTitle);
974				const isVertical = "vertical" === $tabList.attr("aria-orientation");
975				switch (event.key) {
976					case "ArrowLeft":
977					case "ArrowRight":
978						if (isVertical) return;
979						break;
980					case "ArrowUp":
981					case "ArrowDown":
982						if (!isVertical) return;
983						event.preventDefault();
984						break;
985					case "Home":
986						event.preventDefault();
987						$tabs.first().trigger("focus");
988						return;
989					case "End":
990						event.preventDefault();
991						$tabs.last().trigger("focus");
992						return;
993					default: return;
994				}
995				const tabIndex = tab.getAttribute("data-tab") - 1;
996				const direction = this.getSettings("keyDirection")[event.key];
997				const nextTab = $tabs[tabIndex + direction];
998				if (nextTab) nextTab.focus();
999				else if (-1 === tabIndex + direction) $tabs.last().trigger("focus");
1000				else $tabs.first().trigger("focus");
1001			}
1002			deactivateActiveTab(tabIndex) {
1003				const settings = this.getSettings();
1004				const activeClass = settings.classes.active;
1005				const activeFilter = tabIndex ? "[data-tab=\"" + tabIndex + "\"]" : "." + activeClass;
1006				const $activeTitle = this.elements.$tabTitles.filter(activeFilter);
1007				const $activeContent = this.elements.$tabContents.filter(activeFilter);
1008				$activeTitle.add($activeContent).removeClass(activeClass);
1009				$activeTitle.attr({
1010					tabindex: "-1",
1011					"aria-selected": "false"
1012				});
1013				$activeContent[settings.hideTabFn]();
1014				$activeContent.attr("hidden", "hidden");
1015			}
1016			activateTab(tabIndex) {
1017				const settings = this.getSettings();
1018				const activeClass = settings.classes.active;
1019				const $requestedTitle = this.elements.$tabTitles.filter("[data-tab=\"" + tabIndex + "\"]");
1020				const $requestedContent = this.elements.$tabContents.filter("[data-tab=\"" + tabIndex + "\"]");
1021				const animationDuration = "show" === settings.showTabFn ? 0 : 400;
1022				$requestedTitle.add($requestedContent).addClass(activeClass);
1023				$requestedTitle.attr({
1024					tabindex: "0",
1025					"aria-selected": "true"
1026				});
1027				$requestedContent[settings.showTabFn](animationDuration, () => elementorFrontend.elements.$window.trigger("resize"));
1028				$requestedContent.removeAttr("hidden");
1029			}
1030			isActiveTab(tabIndex) {
1031				return this.elements.$tabTitles.filter("[data-tab=\"" + tabIndex + "\"]").hasClass(this.getSettings("classes.active"));
1032			}
1033			bindEvents() {
1034				this.elements.$tabTitles.on({
1035					keydown: (event) => {
1036						if (jQuery(event.target).is("a") && `Enter` === event.key) event.preventDefault();
1037						if ([
1038							"End",
1039							"Home",
1040							"ArrowUp",
1041							"ArrowDown"
1042						].includes(event.key)) this.handleKeyboardNavigation(event);
1043					},
1044					keyup: (event) => {
1045						switch (event.key) {
1046							case "ArrowLeft":
1047							case "ArrowRight":
1048								this.handleKeyboardNavigation(event);
1049								break;
1050							case "Enter":
1051							case "Space":
1052								event.preventDefault();
1053								this.changeActiveTab(event.currentTarget.getAttribute("data-tab"));
1054								break;
1055						}
1056					},
1057					click: (event) => {
1058						event.preventDefault();
1059						this.changeActiveTab(event.currentTarget.getAttribute("data-tab"));
1060					}
1061				});
1062			}
1063			onInit(...args) {
1064				super.onInit(...args);
1065			}
1066			changeActiveTab(tabIndex) {
1067				const isActiveTab = this.isActiveTab(tabIndex);
1068				const settings = this.getSettings();
1069				if ((settings.toggleSelf || !isActiveTab) && settings.hidePrevious) this.deactivateActiveTab();
1070				if (!settings.hidePrevious && isActiveTab) this.deactivateActiveTab(tabIndex);
1071				if (!isActiveTab) this.activateTab(tabIndex);
1072			}
1073		};
1074	}));
1075	//#endregion
1076	//#region modules/video-playlist/assets/js/frontend/player-base.js
1077	var PlayerBase;
1078	var init_player_base = __esmMin((() => {
1079		PlayerBase = class {
1080			constructor(playlistItem, videoIndex) {
1081				this.playlistItem = playlistItem;
1082				this.positionInVideoList = videoIndex;
1083			}
1084			formatDuration(duration) {
1085				const dateObj = /* @__PURE__ */ new Date(duration * 1e3);
1086				const hours = dateObj.getUTCHours();
1087				const minutes = dateObj.getUTCMinutes();
1088				const seconds = dateObj.getSeconds();
1089				if (hours !== 0) return `${hours.toString()}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
1090				return `${minutes.toString()}:${seconds.toString().padStart(2, "0")}`;
1091			}
1092		};
1093	}));
1094	//#endregion
1095	//#region modules/video-playlist/assets/js/frontend/player-youtube.js
1096	var playerYoutube;
1097	var init_player_youtube = __esmMin((() => {
1098		init_player_base();
1099		init_asyncToGenerator();
1100		playerYoutube = class extends PlayerBase {
1101			constructor(playlistItem, videoIndex) {
1102				super(playlistItem, videoIndex);
1103				this.apiProvider = elementorFrontend.utils.youtube;
1104				this.playerObject = null;
1105				this.watchCount = 0;
1106				this.isVideoPlaying = false;
1107				this.isVideoPausedLocal = false;
1108				this.isVideoEnded = false;
1109				this.seekSequenceArray = [];
1110				this.pauseCurrentTime = null;
1111				this.isReady = false;
1112			}
1113			create() {
1114				this.currentVideoID = this.apiProvider.getVideoIDFromURL(this.playlistItem.videoUrl);
1115				return new Promise((resolve) => {
1116					this.apiProvider.onApiReady((apiObject) => {
1117						const playerOptions = {
1118							width: "773",
1119							videoId: this.currentVideoID,
1120							playerVars: {
1121								rel: 0,
1122								showinfo: 0,
1123								ecver: 2
1124							},
1125							events: { onReady: () => {
1126								this.isReady = true;
1127								resolve();
1128							} }
1129						};
1130						this.playerObject = new apiObject.Player(this.playlistItem.tabContent.querySelector("div"), playerOptions);
1131						this.playerObject.addEventListener("onStateChange", (event) => {
1132							if (3 === event.data) if (2 === this.seekSequenceArray[this.seekSequenceArray.length - 1]) this.seekSequenceArray.push(3);
1133							else {
1134								this.seekSequenceArray = [];
1135								clearTimeout(this.seekTimeOut);
1136							}
1137						});
1138					});
1139				});
1140			}
1141			handleEnded(callback) {
1142				this.playerObject.addEventListener("onStateChange", (event) => {
1143					if (0 === event.data) {
1144						this.watchCount++;
1145						this.isVideoEnded = true;
1146						event.target.seekTo(0);
1147						event.target.stopVideo();
1148						this.isVideoPlaying = false;
1149						callback();
1150					}
1151				});
1152			}
1153			handlePaused(callback) {
1154				this.playerObject.addEventListener("onStateChange", (event) => {
1155					if (2 === event.data) {
1156						this.seekSequenceArray = [];
1157						this.seekSequenceArray.push(2);
1158						this.pauseCurrentTime = this.playerObject.playerInfo.currentTime;
1159						this.seekTimeOut = setTimeout(() => {
1160							if (2 === this.seekSequenceArray.length && 2 === this.seekSequenceArray[0] && 3 === this.seekSequenceArray[1]) {
1161								this.seekSequenceArray = [];
1162								clearTimeout(this.seekTimeOut);
1163							} else {
1164								callback(this.positionInVideoList);
1165								this.isVideoPausedLocal = true;
1166							}
1167						}, 1e3);
1168					}
1169				});
1170			}
1171			handlePlayed(callback) {
1172				this.playerObject.addEventListener("onStateChange", (event) => {
1173					if (1 === event.data && !this.isVideoEnded) {
1174						if (!(2 === this.seekSequenceArray.length && 2 === this.seekSequenceArray[0] && 3 === this.seekSequenceArray[1])) callback();
1175					} else this.isVideoEnded = false;
1176				});
1177			}
1178			handleError(callback) {
1179				this.playerObject.addEventListener("onError", () => {
1180					callback();
1181				});
1182			}
1183			handleFullScreenChange(callback) {
1184				this.playerObject.h.addEventListener("fullscreenchange", () => {
1185					callback(document.fullscreenElement);
1186				});
1187			}
1188			getCurrentTime() {
1189				const currentTime = this.pauseCurrentTime ? this.pauseCurrentTime : this.playerObject.playerInfo.currentTime;
1190				this.pauseCurrentTime = null;
1191				return currentTime;
1192			}
1193			play() {
1194				if (!this.isReady) return;
1195				this.isVideoPlaying = true;
1196				this.playerObject.playVideo();
1197			}
1198			pause() {
1199				if (!this.isReady) return;
1200				this.isVideoPlaying = false;
1201				this.playerObject.pauseVideo();
1202			}
1203			mute() {
1204				this.playerObject.mute();
1205			}
1206			setVideoProviderData() {
1207				var _this = this;
1208				return _asyncToGenerator(function* () {
1209					if (!_this.isReady) return;
1210					if (_this.currentVideoID && 11 === _this.currentVideoID.length) {
1211						_this.playlistItem.thumbnail = { url: "https://img.youtube.com/vi/" + _this.playerObject.getVideoData().video_id + "/maxresdefault.jpg" };
1212						_this.playlistItem.video_title = _this.playerObject.getVideoData().title;
1213						_this.playlistItem.duration = _this.formatDuration(_this.playerObject.getDuration());
1214					} else {
1215						_this.playlistItem.thumbnail = { url: "" };
1216						_this.playlistItem.video_title = "";
1217						_this.playlistItem.duration = "";
1218					}
1219				})();
1220			}
1221		};
1222	}));
1223	//#endregion
1224	//#region modules/video-playlist/assets/js/frontend/player-vimeo.js
1225	var playerVimeo;
1226	var init_player_vimeo = __esmMin((() => {
1227		init_player_base();
1228		init_asyncToGenerator();
1229		playerVimeo = class extends PlayerBase {
1230			constructor(playlistItem, videoIndex) {
1231				super(playlistItem, videoIndex);
1232				this.apiProvider = elementorFrontend.utils.vimeo;
1233				this.playerObject = null;
1234				this.watchCount = 0;
1235				this.isVideoInFullScreenChange = false;
1236				this.isReady = false;
1237			}
1238			create() {
1239				this.currentVideoID = this.apiProvider.getVideoIDFromURL(this.playlistItem.videoUrl);
1240				return new Promise((resolve) => {
1241					this.apiProvider.onApiReady((apiObject) => {
1242						const playerOptions = {
1243							id: this.currentVideoID,
1244							autoplay: false
1245						};
1246						this.playerObject = new apiObject.Player(this.playlistItem.tabContent.querySelector("div"), playerOptions);
1247						this.playerObject.ready().then(() => {
1248							this.isReady = true;
1249							resolve();
1250						});
1251					});
1252				});
1253			}
1254			handleEnded(callback) {
1255				this.playerObject.on("ended", () => {
1256					this.watchCount++;
1257					callback(this.playlistItem);
1258				});
1259			}
1260			handlePaused(callback) {
1261				this.playerObject.on("pause", (event) => {
1262					if (0 === event.percent || event.percent >= 1 || this.isVideoInFullScreenChange) return;
1263					callback(this.positionInVideoList);
1264				});
1265			}
1266			handlePlayed(callback) {
1267				this.playerObject.on("play", () => {
1268					if (this.isVideoInFullScreenChange) {
1269						this.isVideoInFullScreenChange = false;
1270						return;
1271					}
1272					callback(this.playlistItem);
1273				});
1274			}
1275			handleFullScreenChange(callback) {
1276				this.playerObject.element.addEventListener("fullscreenchange", () => {
1277					callback(document.fullscreenElement);
1278					this.isVideoInFullScreenChange = true;
1279				});
1280			}
1281			getCurrentTime() {
1282				return this.playerObject.getCurrentTime().then((seconds) => seconds);
1283			}
1284			play() {
1285				if (!this.isReady) return;
1286				this.playerObject.play();
1287			}
1288			pause() {
1289				if (!this.isReady) return;
1290				this.playerObject.pause();
1291			}
1292			mute() {
1293				this.playerObject.setMuted(true);
1294			}
1295			setVideoProviderData() {
1296				var _this = this;
1297				return _asyncToGenerator(function* () {
1298					if (!_this.currentVideoID && 9 === !_this.currentVideoID.length) return;
1299					const videoId = yield _this.playerObject.getVideoId();
1300					const videoData = yield (yield fetch("https://vimeo.com/api/v2/video/" + videoId + ".json")).json();
1301					_this.playlistItem.duration = _this.formatDuration(videoData[0].duration);
1302					_this.playlistItem.video_title = videoData[0].title;
1303					_this.playlistItem.thumbnail = { url: videoData[0].thumbnail_medium };
1304					return _this.playlistItem;
1305				})();
1306			}
1307		};
1308	}));
1309	//#endregion
1310	//#region modules/video-playlist/assets/js/frontend/player-hosted.js
1311	var playerHosted;
1312	var init_player_hosted = __esmMin((() => {
1313		init_player_base();
1314		playerHosted = class extends PlayerBase {
1315			constructor(playlistItem, videoIndex) {
1316				super(playlistItem, videoIndex);
1317				this.playerObject = null;
1318				this.watchCount = 0;
1319				this.isVideoPlaying = false;
1320				this.isVideoPausedLocal = false;
1321				this.isVideoSeeking = false;
1322				this.isVideoEnded = false;
1323				this.isReady = false;
1324			}
1325			create() {
1326				return new Promise((resolve) => {
1327					const video = document.createElement("video");
1328					video.setAttribute("controls", "");
1329					const text = document.createTextNode("Sorry, your browser doesn't support embedded videos.");
1330					const source = document.createElement("source");
1331					source.setAttribute("src", this.playlistItem.videoUrl);
1332					source.setAttribute("type", "video/" + this.playlistItem.videoUrl.split(".").pop());
1333					video.appendChild(source);
1334					video.appendChild(text);
1335					this.playerObject = video;
1336					this.playlistItem.tabContent.querySelector("div").replaceWith(this.playerObject);
1337					this.playerObject.addEventListener("canplay", () => {
1338						this.isReady = true;
1339						resolve();
1340					});
1341					this.playerObject.addEventListener("seeked", () => {
1342						this.isVideoSeeking = false;
1343					});
1344					this.playerObject.addEventListener("seeking", () => {
1345						clearTimeout(this.seekTimeOut);
1346						this.isVideoSeeking = true;
1347					});
1348				});
1349			}
1350			handleEnded(callback) {
1351				this.playerObject.addEventListener("ended", () => {
1352					this.watchCount++;
1353					this.isVideoEnded = true;
1354					this.isVideoPlaying = false;
1355					callback(this.playlistItem);
1356				});
1357			}
1358			handlePaused(callback) {
1359				this.playerObject.addEventListener("pause", () => {
1360					this.seekTimeOut = setTimeout(() => {
1361						if (!this.isVideoSeeking && !this.isVideoEnded) {
1362							callback(this.positionInVideoList);
1363							this.isVideoPausedLocal = true;
1364						} else this.isVideoEnded = false;
1365					}, 30);
1366				});
1367			}
1368			handlePlayed(callback) {
1369				this.playerObject.addEventListener("play", () => {
1370					if (!this.isVideoSeeking) callback(this.playlistItem);
1371				});
1372			}
1373			handleFullScreenChange(callback) {
1374				jQuery(this.playerObject).on("webkitfullscreenchange mozfullscreenchange fullscreenchange", () => {
1375					callback(document.fullscreenElement);
1376				});
1377			}
1378			getCurrentTime() {
1379				return this.playerObject.currentTime;
1380			}
1381			play() {
1382				if (!this.isReady) return;
1383				this.isVideoPlaying = true;
1384				this.playerObject.play();
1385			}
1386			pause() {
1387				if (!this.isReady) return;
1388				this.isVideoPlaying = false;
1389				this.playerObject.pause();
1390			}
1391			mute() {
1392				this.playerObject.muted = true;
1393			}
1394		};
1395	}));
1396	//#endregion
1397	//#region modules/video-playlist/assets/js/frontend/scroll-utils.js
1398	function handleVideosPanelScroll(elements, event) {
1399		if (!event) {
1400			if (elements.$tabsItems[0].offsetHeight < elements.$tabsItems[0].scrollHeight) elements.$tabsWrapper.addClass("bottom-shadow");
1401			return;
1402		}
1403		if (event.target.scrollTop > 0) elements.$tabsWrapper.addClass("top-shadow");
1404		else elements.$tabsWrapper.removeClass("top-shadow");
1405		if (event.target.offsetHeight + event.target.scrollTop >= event.target.scrollHeight) elements.$tabsWrapper.removeClass("bottom-shadow");
1406		else elements.$tabsWrapper.addClass("bottom-shadow");
1407	}
1408	var init_scroll_utils = __esmMin((() => {}));
1409	//#endregion
1410	//#region modules/video-playlist/assets/js/frontend/playlist-event.js
1411	var PlaylistEvent;
1412	var init_playlist_event = __esmMin((() => {
1413		PlaylistEvent = class {
1414			constructor({ event, tab, playlist, video }) {
1415				this.event = {
1416					type: event.type || "",
1417					time: event.time || 0,
1418					element: event.element,
1419					trigger: event.trigger || "",
1420					watchCount: event.watchCount || 0
1421				};
1422				this.tab = {
1423					name: tab.name,
1424					index: tab.index
1425				};
1426				this.playlist = {
1427					name: playlist.name,
1428					currentItem: playlist.currentItem,
1429					amount: playlist.amount
1430				};
1431				this.video = {
1432					provider: video.provider,
1433					url: video.url,
1434					title: video.title,
1435					duration: video.duration
1436				};
1437			}
1438		};
1439	}));
1440	//#endregion
1441	//#region modules/video-playlist/assets/js/frontend/event-trigger.js
1442	function getEventTabsObject(widgetObject) {
1443		const currentInnerTabsTitleElements = widgetObject.elements.$innerTabs.filter(".e-active").find(".e-inner-tabs-wrapper .e-inner-tab-title");
1444		if (currentInnerTabsTitleElements.length) {
1445			const activeInnerTabTitleElement = currentInnerTabsTitleElements.filter(".e-inner-tab-active");
1446			return {
1447				name: activeInnerTabTitleElement.text().trim(),
1448				index: activeInnerTabTitleElement.index() + 1
1449			};
1450		}
1451		return {
1452			name: "none",
1453			index: "none"
1454		};
1455	}
1456	function getEventPlaylistObject(widgetObject, positionInVideoList) {
1457		const currentVideoIndex = positionInVideoList || widgetObject.currentPlaylistItemIndex;
1458		return {
1459			name: widgetObject.getElementSettings("playlist_title"),
1460			currentItem: currentVideoIndex,
1461			amount: widgetObject.playlistItemsArray.filter((video) => video.videoType !== "section").length
1462		};
1463	}
1464	function getEventVideoObject(widgetObject, positionInVideoList) {
1465		const currentVideoIndex = positionInVideoList || widgetObject.currentPlaylistItemIndex;
1466		const currentVideo = widgetObject.playlistItemsArray[currentVideoIndex - 1];
1467		return {
1468			provider: currentVideo.videoType,
1469			url: currentVideo.videoUrl,
1470			title: currentVideo.videoTitle,
1471			duration: currentVideo.videoDuration
1472		};
1473	}
1474	function getEventEventObject(_x, _x2, _x3, _x4) {
1475		return _getEventEventObject.apply(this, arguments);
1476	}
1477	function _getEventEventObject() {
1478		_getEventEventObject = _asyncToGenerator(function* (widgetObject, eventType, eventTrigger, positionInVideoList) {
1479			const currentVideoIndex = positionInVideoList || widgetObject.currentPlaylistItemIndex;
1480			const currentVideo = widgetObject.playlistItemsArray[currentVideoIndex - 1];
1481			return {
1482				type: eventType,
1483				time: yield currentVideo.playerInstance.getCurrentTime(),
1484				element: widgetObject.$element,
1485				trigger: eventTrigger,
1486				watchCount: currentVideo.playerInstance.watchCount
1487			};
1488		});
1489		return _getEventEventObject.apply(this, arguments);
1490	}
1491	function triggerEvent(_x5, _x6, _x7, _x8) {
1492		return _triggerEvent.apply(this, arguments);
1493	}
1494	function _triggerEvent() {
1495		_triggerEvent = _asyncToGenerator(function* (widgetObject, eventType, eventTrigger, positionInVideoList) {
1496			const currentEvent = new PlaylistEvent({
1497				event: yield getEventEventObject(widgetObject, eventType, eventTrigger, positionInVideoList),
1498				tab: getEventTabsObject(widgetObject),
1499				playlist: getEventPlaylistObject(widgetObject, positionInVideoList),
1500				video: getEventVideoObject(widgetObject, positionInVideoList)
1501			});
1502			jQuery("body").trigger("elementor-video-playList", currentEvent);
1503		});
1504		return _triggerEvent.apply(this, arguments);
1505	}
1506	var init_event_trigger = __esmMin((() => {
1507		init_playlist_event();
1508		init_asyncToGenerator();
1509	}));
1510	//#endregion
1511	//#region modules/video-playlist/assets/js/frontend/inner-tabs.js
1512	function toggleInnerTabs(event, clickedTab, widgetObject) {
1513		const activeTabWrapper = event.currentTarget;
1514		const tabTitles = activeTabWrapper.querySelectorAll(".e-inner-tab-title");
1515		if (clickedTab.hasClass("e-inner-tab-active") || tabTitles.length < 2) return;
1516		const tabsContents = activeTabWrapper.querySelectorAll(".e-inner-tab-content");
1517		tabTitles.forEach((tabTitle) => {
1518			tabTitle.classList.toggle("e-inner-tab-active");
1519		});
1520		tabsContents.forEach((tabContent) => {
1521			tabContent.toggleAttribute("hidden");
1522			tabContent.classList.toggle("e-inner-tab-active");
1523		});
1524		handleInnerTabsButtonsDisplay(Array.from(tabsContents), widgetObject.isCollapsible, widgetObject.innerTabsHeightLimit);
1525		triggerEvent(widgetObject, "tabOpened", "click");
1526	}
1527	function handleInnerTabs(event, widgetObject) {
1528		const clickedTarget = event.target;
1529		const clickedTagType = clickedTarget.tagName;
1530		if (clickedTarget.classList.contains("e-inner-tab-title-text")) {
1531			event.preventDefault();
1532			toggleInnerTabs(event, jQuery(clickedTarget).parent(".e-inner-tab-title"), widgetObject);
1533		}
1534		if (clickedTarget.classList.contains("e-tab-mobile-title")) toggleInnerTabs(event, jQuery(clickedTarget), widgetObject);
1535		if ("button" === clickedTagType.toLowerCase()) onTabContentButtonsClick(event, widgetObject);
1536	}
1537	function handleInnerTabsButtonsDisplay(tabsContents, isCollapsible, innerTabsHeightLimit) {
1538		if (!isCollapsible) return;
1539		const activeInnerTab = tabsContents.filter((tabsContent) => tabsContent.classList.contains("e-inner-tab-active"));
1540		const innerTabScrollableHeight = activeInnerTab[0].querySelector(".e-inner-tab-text > div").offsetHeight;
1541		const innerTabsLimitHeight = parseInt(innerTabsHeightLimit.size);
1542		if (innerTabsLimitHeight && innerTabScrollableHeight > innerTabsLimitHeight) activeInnerTab[0].classList.add("show-inner-tab-buttons");
1543	}
1544	function onTabContentButtonsClick(event, widgetObject) {
1545		const $activeTabContent = jQuery(event.currentTarget).find(".e-inner-tab-content").filter(".e-inner-tab-active");
1546		$activeTabContent.find("button").toggleClass("show-button");
1547		$activeTabContent.toggleClass("show-full-height");
1548		triggerEvent(widgetObject, $activeTabContent.hasClass("show-full-height") ? "tabExpanded" : "tabCollapsed", "click");
1549	}
1550	var init_inner_tabs = __esmMin((() => {
1551		init_event_trigger();
1552	}));
1553	//#endregion
1554	//#region modules/video-playlist/assets/js/frontend/url-params.js
1555	function handleURLParams(playlistId, playlistItemsArray) {
1556		const params = new URLSearchParams(location.search);
1557		const playlistName = params.get("playlist");
1558		const defaultTabIndex = 1;
1559		if (!playlistName) return false;
1560		if (playlistName === playlistId) {
1561			const videoId = params.get("video");
1562			const videoItem = playlistItemsArray.find((playlistItem) => videoId === playlistItem.dataItemId);
1563			const tabIndex = videoItem ? videoItem.dataTab : defaultTabIndex;
1564			if (!tabIndex) setVideoParams(playlistId, playlistItemsArray, defaultTabIndex);
1565			return tabIndex || false;
1566		}
1567	}
1568	function setVideoParams(playlistId, playlistItemsArray, videoId) {
1569		const params = new URLSearchParams(location.search);
1570		params.set("playlist", playlistId);
1571		params.set("video", playlistItemsArray[videoId - 1].dataItemId);
1572		history.replaceState({}, "", location.pathname + "?" + params);
1573	}
1574	var init_url_params = __esmMin((() => {}));
1575	//#endregion
1576	//#region modules/video-playlist/assets/js/frontend/handler.js
1577	var handler_exports = /* @__PURE__ */ __exportAll({ default: () => VideoPlaylistHandler });
1578	var __defProp, __defProps, __getOwnPropDescs, __getOwnPropSymbols, __hasOwnProp, __propIsEnum, __defNormalProp, __spreadValues, __spreadProps, VideoPlaylistHandler;
1579	var init_handler = __esmMin((() => {
1580		init_base_tabs();
1581		init_player_youtube();
1582		init_player_vimeo();
1583		init_player_hosted();
1584		init_scroll_utils();
1585		init_inner_tabs();
1586		init_url_params();
1587		init_event_trigger();
1588		__defProp = Object.defineProperty;
1589		__defProps = Object.defineProperties;
1590		__getOwnPropDescs = Object.getOwnPropertyDescriptors;
1591		__getOwnPropSymbols = Object.getOwnPropertySymbols;
1592		__hasOwnProp = Object.prototype.hasOwnProperty;
1593		__propIsEnum = Object.prototype.propertyIsEnumerable;
1594		__defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {
1595			enumerable: true,
1596			configurable: true,
1597			writable: true,
1598			value
1599		}) : obj[key] = value;
1600		__spreadValues = (a, b) => {
1601			for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]);
1602			if (__getOwnPropSymbols) {
1603				for (var prop of __getOwnPropSymbols(b)) if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]);
1604			}
1605			return a;
1606		};
1607		__spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1608		VideoPlaylistHandler = class extends baseTabs {
1609			getDefaultSettings() {
1610				const defaultSettings = super.getDefaultSettings();
1611				return __spreadProps(__spreadValues({}, defaultSettings), { selectors: __spreadValues(__spreadValues({}, defaultSettings.selectors), {
1612					tabsWrapper: ".e-tabs-items-wrapper",
1613					tabsItems: ".e-tabs-items",
1614					toggleVideosDisplayButton: ".e-tabs-toggle-videos-display-button",
1615					videos: ".e-tabs-content-wrapper .e-tab-content",
1616					innerTabs: ".e-tabs-inner-tabs .e-tab-content",
1617					imageOverlay: ".elementor-custom-embed-image-overlay"
1618				}) });
1619			}
1620			getDefaultElements() {
1621				const elements = super.getDefaultElements();
1622				const selectors = this.getSettings("selectors");
1623				return __spreadProps(__spreadValues({}, elements), {
1624					$tabsWrapper: this.findElement(selectors.tabsWrapper),
1625					$tabsItems: this.findElement(selectors.tabsItems),
1626					$toggleVideosDisplayButton: this.findElement(selectors.toggleVideosDisplayButton),
1627					$videos: this.findElement(selectors.videos),
1628					$innerTabs: this.findElement(selectors.innerTabs),
1629					$imageOverlay: this.findElement(selectors.imageOverlay)
1630				});
1631			}
1632			initEditorListeners() {
1633				super.initEditorListeners();
1634				this.editorListeners.push({
1635					event: "elementorPlaylistWidget:fetchVideoData",
1636					to: elementor.channels.editor,
1637					callback: (e) => {
1638						this.getCurrentPlayerSelected().setVideoProviderData().then(() => {
1639							e.currentItem = this.getCurrentItemSelected();
1640							elementor.channels.editor.trigger("elementorPlaylistWidget:setVideoData", e);
1641						});
1642					}
1643				});
1644			}
1645			bindEvents() {
1646				super.bindEvents();
1647				this.elements.$imageOverlay.on({ click: (e) => {
1648					e.currentTarget.remove();
1649					this.getCurrentPlayerSelected().play();
1650				} });
1651				this.elements.$innerTabs.on({ click: (event) => {
1652					handleInnerTabs(event, this);
1653				} });
1654				this.elements.$tabsItems.on({ scroll: (event) => {
1655					handleVideosPanelScroll(this.elements, event);
1656				} });
1657				this.elements.$toggleVideosDisplayButton.on({ click: (event) => {
1658					jQuery(event.target).toggleClass("rotate-up");
1659					jQuery(event.target).toggleClass("rotate-down");
1660					this.elements.$tabsWrapper.slideToggle("slow");
1661				} });
1662			}
1663			onInit(...args) {
1664				super.onInit(...args);
1665				this.playlistId = this.getID();
1666				this.storageKey = "watched_videos_" + this.getID();
1667				const storageObject = elementorFrontend.storage.get(this.storageKey);
1668				if (storageObject) this.watchedVideosArray = JSON.parse(storageObject);
1669				else this.watchedVideosArray = [];
1670				this.watchedIndication = this.getElementSettings("show_watched_indication");
1671				handleVideosPanelScroll(this.elements);
1672				this.isAutoplayOnLoad = "yes" === this.getElementSettings("autoplay_on_load");
1673				this.isAutoplayNextUp = "yes" === this.getElementSettings("autoplay_next");
1674				this.isFirstVideoActivated = true;
1675				this.createPlaylistItems();
1676				this.isCollapsible = this.getElementSettings("inner_tab_is_content_collapsible");
1677				this.innerTabsHeightLimit = this.getElementSettings("inner_tab_collapsible_height");
1678				this.currentPlayingPlaylistItemIndex = 1;
1679				this.activateInitialVideo();
1680				this.activateInnerTabInEditMode();
1681			}
1682			onEditSettingsChange(propertyName) {
1683				if ("panel" === propertyName) this.preventTabActivation = true;
1684				if ("activeItemIndex" !== propertyName) return;
1685				if (this.preventTabActivation) {
1686					this.preventTabActivation = false;
1687					return;
1688				}
1689				this.activateDefaultTab();
1690			}
1691			activateInitialVideo() {
1692				var _a;
1693				this.isPageOnLoad = true;
1694				const isLazyLoad = !!this.getElementSettings("lazy_load");
1695				const initialTabIndex = handleURLParams(this.playlistId, this.playlistItemsArray);
1696				let isUrlParamsExist = false;
1697				if (initialTabIndex) {
1698					this.currentPlaylistItemIndex = initialTabIndex;
1699					this.currentPlayingPlaylistItemIndex = initialTabIndex;
1700					isUrlParamsExist = true;
1701				} else {
1702					this.currentPlaylistItemIndex = 1;
1703					this.currentPlayingPlaylistItemIndex = 1;
1704				}
1705				if (this.isAutoplayOnLoad && !isUrlParamsExist) setVideoParams(this.playlistId, this.playlistItemsArray, this.currentPlaylistItemIndex);
1706				if (isUrlParamsExist) (_a = this.$element[0]) == null || _a.scrollIntoView({ behavior: "smooth" });
1707				this.handleFirstVideoActivation(isLazyLoad);
1708			}
1709			handleFirstVideoActivation(isLazyLoad) {
1710				if (!isLazyLoad) {
1711					this.activateDefaultTab(this.currentPlaylistItemIndex);
1712					return;
1713				}
1714				const playlistElement = document.querySelector(".elementor-element-" + this.playlistId + " .e-tabs-main-area");
1715				const observer = elementorModules.utils.Scroll.scrollObserver({ callback: (event) => {
1716					if (event.isInViewport) {
1717						this.activateDefaultTab(this.currentPlaylistItemIndex);
1718						observer.unobserve(playlistElement);
1719					}
1720				} });
1721				observer.observe(playlistElement);
1722			}
1723			getCurrentItemSelected() {
1724				return this.playlistItemsArray[this.currentPlaylistItemIndex - 1];
1725			}
1726			getCurrentPlayerSelected() {
1727				return this.getCurrentItemSelected().playerInstance;
1728			}
1729			getCurrentPlayerPlaying() {
1730				return this.playlistItemsArray[this.currentPlayingPlaylistItemIndex - 1].playerInstance;
1731			}
1732			isVideoShouldBePlayed() {
1733				if (this.currentPlayingPlaylistItemIndex !== this.currentPlaylistItemIndex) {
1734					if (this.getCurrentPlayerPlaying()) this.getCurrentPlayerPlaying().pause();
1735					this.currentPlayingPlaylistItemIndex = this.currentPlaylistItemIndex;
1736				} else if (this.getCurrentPlayerPlaying().isVideoPlaying) {
1737					this.getCurrentPlayerPlaying().pause();
1738					return false;
1739				}
1740				return true;
1741			}
1742			activateInnerTabInEditMode() {
1743				if (this.isEdit && this.getEditSettings("innerActiveIndex")) {
1744					const innerTabActivated = this.getEditSettings("innerActiveIndex");
1745					jQuery(this.elements.$innerTabs.eq(this.currentPlaylistItemIndex - 1).find(".e-inner-tab-title a"))[innerTabActivated].click();
1746				}
1747			}
1748			handleVideo(playListItem) {
1749				if (playListItem.playerInstance) {
1750					if (this.isVideoShouldBePlayed()) {
1751						if (1 === this.currentPlaylistItemIndex && this.elements.$imageOverlay) this.elements.$imageOverlay.remove();
1752						this.playVideoAfterCreation(playListItem);
1753					}
1754				} else {
1755					playListItem.playerInstance = new {
1756						youtube: playerYoutube,
1757						vimeo: playerVimeo,
1758						hosted: playerHosted
1759					}[playListItem.videoType](playListItem, this.currentPlaylistItemIndex);
1760					playListItem.playerInstance.create().then(() => {
1761						if (this.isVideoShouldBePlayed()) this.playVideoOnCreation(playListItem);
1762						playListItem.playerInstance.handleFullScreenChange((isEnterFullScreenMode) => {
1763							triggerEvent(this, isEnterFullScreenMode ? "videoFullScreen" : "videoExitFullScreen", "click");
1764						});
1765						playListItem.playerInstance.handlePlayed(() => {
1766							const currentPlaylistItem = this.getCurrentItemSelected();
1767							let videoTrigger = "click";
1768							if (currentPlaylistItem.isAutoplayOnLoad) {
1769								videoTrigger = "onLoad";
1770								playListItem.isAutoplayOnLoad = false;
1771							} else if (currentPlaylistItem.isAutoPlayNextUp) videoTrigger = "nextVideo";
1772							triggerEvent(this, currentPlaylistItem.playerInstance.isVideoPausedLocal ? "videoResume" : "videoStart", videoTrigger);
1773						});
1774						playListItem.playerInstance.handleEnded(() => {
1775							triggerEvent(this, "videoEnded", "click");
1776							if (this.watchedIndication) this.elements.$tabTitles.filter(".e-active").addClass("watched-video");
1777							const endedVideoId = this.getCurrentItemSelected().dataItemId;
1778							if (!this.watchedVideosArray.includes(endedVideoId) && this.watchedIndication) {
1779								this.watchedVideosArray.push(this.getCurrentItemSelected().dataItemId);
1780								elementorFrontend.storage.set(this.storageKey, JSON.stringify(this.watchedVideosArray));
1781							}
1782							if (this.isAutoplayNextUp) {
1783								if (this.playlistItemsArray.length >= ++this.currentPlaylistItemIndex) {
1784									while ("section" === this.getCurrentItemSelected().videoType) {
1785										this.currentPlaylistItemIndex++;
1786										if (this.playlistItemsArray.length < this.currentPlaylistItemIndex) {
1787											this.currentPlaylistItemIndex = this.playlistItemsArray.length;
1788											return;
1789										}
1790									}
1791									this.changeActiveTab(this.currentPlaylistItemIndex, true);
1792								}
1793							}
1794						});
1795						playListItem.playerInstance.handlePaused((positionInVideoList) => {
1796							triggerEvent(this, "videoPaused", "click", positionInVideoList);
1797						});
1798					});
1799				}
1800			}
1801			playVideoAfterCreation(playListItem) {
1802				playListItem.playerInstance.play();
1803			}
1804			playVideoOnCreation(playListItem) {
1805				if (this.isAutoplayOnLoad) {
1806					playListItem.isAutoplayOnLoad = true;
1807					playListItem.playerInstance.mute();
1808					playListItem.playerInstance.play();
1809					this.isAutoplayOnLoad = false;
1810				} else if (!this.isFirstVideoActivated) {
1811					playListItem.isAutoPlayNextUp = true;
1812					playListItem.playerInstance.play();
1813				}
1814				this.isFirstVideoActivated = false;
1815			}
1816			createPlaylistItems() {
1817				this.playlistItemsArray = [];
1818				this.elements.$videos.each((index, tabContent) => {
1819					const playListItem = {};
1820					const $tabContent = jQuery(tabContent);
1821					playListItem.videoUrl = $tabContent.attr("data-video-url");
1822					playListItem.videoType = $tabContent.attr("data-video-type");
1823					playListItem.videoTitle = $tabContent.attr("data-video-title");
1824					playListItem.videoDuration = $tabContent.attr("data-video-duration");
1825					playListItem.tabContent = tabContent;
1826					playListItem.dataTab = index + 1;
1827					playListItem.dataItemId = this.getElementSettings().tabs[index]._id;
1828					this.playlistItemsArray.push(playListItem);
1829				});
1830				if (this.watchedVideosArray.length > 0 && this.watchedIndication) this.watchedVideosArray.forEach((watchedVideoId) => {
1831					const watchedPlaylistItem = this.playlistItemsArray.find((playlistItem) => playlistItem.dataItemId === watchedVideoId);
1832					this.elements.$tabTitles.filter("[data-tab=\"" + watchedPlaylistItem.dataTab + "\"]").addClass("watched-video");
1833				});
1834			}
1835			changeActiveTab(tabIndex, isVideoSelectedAutomatically) {
1836				super.changeActiveTab(tabIndex);
1837				if (this.playlistItemsArray[tabIndex - 1] && this.playlistItemsArray[tabIndex - 1].videoType !== "section") {
1838					this.currentPlaylistItemIndex = parseInt(tabIndex);
1839					if (isVideoSelectedAutomatically) this.currentPlayingPlaylistItemIndex = this.currentPlaylistItemIndex;
1840					this.handleVideo(this.getCurrentItemSelected(), isVideoSelectedAutomatically);
1841					if (!this.isPageOnLoad) setVideoParams(this.playlistId, this.playlistItemsArray, this.currentPlaylistItemIndex);
1842					this.isPageOnLoad = false;
1843					if (jQuery(this.elements.$innerTabs.eq(tabIndex - 1)).find(".e-inner-tab-content").length > 0) handleInnerTabsButtonsDisplay(this.elements.$innerTabs.filter(".e-active").find(".e-inner-tab-content").toArray(), this.isCollapsible, this.innerTabsHeightLimit);
1844				}
1845			}
1846		};
1847	}));
1848	//#endregion
1849	//#region modules/video-playlist/assets/js/frontend/frontend.js
1850	init_asyncToGenerator();
1851	var frontend_default$2 = class extends elementorModules.Module {
1852		static {
1853			__name(this, "default");
1854		}
1855		constructor() {
1856			super();
1857			elementorFrontend.hooks.addAction("frontend/element_ready/video-playlist.default", ($element) => {
1858				__vitePreload(_asyncToGenerator(function* () {
1859					const { default: dynamicHandler } = yield Promise.resolve().then(() => (init_handler(), handler_exports));
1860					return { default: dynamicHandler };
1861				}), void 0).then(({ default: dynamicHandler }) => {
1862					elementorFrontend.elementsHandler.addHandler(dynamicHandler, {
1863						$element,
1864						toggleSelf: false
1865					});
1866				});
1867			});
1868		}
1869	};
1870	//#endregion
1871	//#region modules/payments/assets/js/frontend/handlers/paypal-button.js
1872	var paypal_button_exports = /* @__PURE__ */ __exportAll({ default: () => PayPalHandler });
1873	var PayPalHandler;
1874	var init_paypal_button = __esmMin((() => {
1875		PayPalHandler = class extends elementorModules.frontend.handlers.Base {
1876			getDefaultSettings() {
1877				return { selectors: {
1878					button: ".elementor-button.elementor-paypal-legacy",
1879					errors: ".elementor-message-danger"
1880				} };
1881			}
1882			getDefaultElements() {
1883				const settings = this.getSettings();
1884				return {
1885					wrapper: this.$element[0],
1886					button: this.$element[0].querySelector(settings.selectors.button),
1887					errors: this.$element[0].querySelectorAll(settings.selectors.errors)
1888				};
1889			}
1890			handleClick(event) {
1891				if (0 < this.elements.errors.length) {
1892					event.preventDefault();
1893					this.elements.errors.forEach((error) => {
1894						error.classList.remove("elementor-hidden");
1895					});
1896				}
1897			}
1898			bindEvents() {
1899				this.elements.button.addEventListener("click", this.handleClick.bind(this));
1900			}
1901		};
1902	}));
1903	//#endregion
1904	//#region node_modules/dompurify/dist/purify.es.mjs
1905	/*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE */
1906	function _arrayLikeToArray(r, a) {
1907		(null == a || a > r.length) && (a = r.length);
1908		for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
1909		return n;
1910	}
1911	function _arrayWithHoles(r) {
1912		if (Array.isArray(r)) return r;
1913	}
1914	function _iterableToArrayLimit(r, l) {
1915		var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
1916		if (null != t) {
1917			var e;
1918			var n;
1919			var i;
1920			var u;
1921			var a = [];
1922			var f = true;
1923			var o = false;
vendor: 9,644 bytes, lines 1924-2165
1924			try {
1925				if (i = (t = t.call(r)).next, 0 === l);
1926				else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
1927			} catch (r) {
1928				o = true, n = r;
1929			} finally {
1930				try {
1931					if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
1932				} finally {
1933					if (o) throw n;
1934				}
1935			}
1936			return a;
1937		}
1938	}
1939	function _nonIterableRest() {
1940		throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1941	}
1942	function _slicedToArray(r, e) {
1943		return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
1944	}
1945	function _unsupportedIterableToArray(r, a) {
1946		if (r) {
1947			if ("string" == typeof r) return _arrayLikeToArray(r, a);
1948			var t = {}.toString.call(r).slice(8, -1);
1949			return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
1950		}
1951	}
1952	/**
1953	* Creates a new function that calls the given function with a specified thisArg and arguments.
1954	*
1955	* @param func - The function to be wrapped and called.
1956	* @returns A new function that calls the given function with a specified thisArg and arguments.
1957	*/
1958	function unapply(func) {
1959		return function(thisArg) {
1960			if (thisArg instanceof RegExp) thisArg.lastIndex = 0;
1961			for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) args[_key3 - 1] = arguments[_key3];
1962			return apply(func, thisArg, args);
1963		};
1964	}
1965	/**
1966	* Creates a new function that constructs an instance of the given constructor function with the provided arguments.
1967	*
1968	* @param func - The constructor function to be wrapped and called.
1969	* @returns A new function that constructs an instance of the given constructor function with the provided arguments.
1970	*/
1971	function unconstruct(Func) {
1972		return function() {
1973			for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) args[_key4] = arguments[_key4];
1974			return construct(Func, args);
1975		};
1976	}
1977	/**
1978	* Add properties to a lookup table
1979	*
1980	* @param set - The set to which elements will be added.
1981	* @param array - The array containing elements to be added to the set.
1982	* @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
1983	* @returns The modified set with added elements.
1984	*/
1985	function addToSet(set, array) {
1986		let transformCaseFunc = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : stringToLowerCase;
1987		if (setPrototypeOf) setPrototypeOf(set, null);
1988		if (!arrayIsArray(array)) return set;
1989		let l = array.length;
1990		while (l--) {
1991			let element = array[l];
1992			if (typeof element === "string") {
1993				const lcElement = transformCaseFunc(element);
1994				if (lcElement !== element) {
1995					if (!isFrozen(array)) array[l] = lcElement;
1996					element = lcElement;
1997				}
1998			}
1999			set[element] = true;
2000		}
2001		return set;
2002	}
2003	/**
2004	* Clean up an array to harden against CSPP
2005	*
2006	* @param array - The array to be cleaned.
2007	* @returns The cleaned version of the array
2008	*/
2009	function cleanArray(array) {
2010		for (let index = 0; index < array.length; index++) if (!objectHasOwnProperty(array, index)) array[index] = null;
2011		return array;
2012	}
2013	/**
2014	* Shallow clone an object
2015	*
2016	* @param object - The object to be cloned.
2017	* @returns A new object that copies the original.
2018	*/
2019	function clone(object) {
2020		const newObject = create(null);
2021		for (const _ref2 of entries(object)) {
2022			var _ref3 = _slicedToArray(_ref2, 2);
2023			const property = _ref3[0];
2024			const value = _ref3[1];
2025			if (objectHasOwnProperty(object, property)) if (arrayIsArray(value)) newObject[property] = cleanArray(value);
2026			else if (value && typeof value === "object" && value.constructor === Object) newObject[property] = clone(value);
2027			else newObject[property] = value;
2028		}
2029		return newObject;
2030	}
2031	/**
2032	* Convert non-node values into strings without depending on direct property access.
2033	*
2034	* @param value - The value to stringify.
2035	* @returns A string representation of the provided value.
2036	*/
2037	function stringifyValue(value) {
2038		switch (typeof value) {
2039			case "string": return value;
2040			case "number": return numberToString(value);
2041			case "boolean": return booleanToString(value);
2042			case "bigint": return bigintToString ? bigintToString(value) : "0";
2043			case "symbol": return symbolToString ? symbolToString(value) : "Symbol()";
2044			case "undefined": return objectToString(value);
2045			case "function":
2046			case "object": {
2047				if (value === null) return objectToString(value);
2048				const valueAsRecord = value;
2049				const valueToString = lookupGetter(valueAsRecord, "toString");
2050				if (typeof valueToString === "function") {
2051					const stringified = valueToString(valueAsRecord);
2052					return typeof stringified === "string" ? stringified : objectToString(stringified);
2053				}
2054				return objectToString(value);
2055			}
2056			default: return objectToString(value);
2057		}
2058	}
2059	/**
2060	* This method automatically checks if the prop is function or getter and behaves accordingly.
2061	*
2062	* @param object - The object to look up the getter function in its prototype chain.
2063	* @param prop - The property name for which to find the getter function.
2064	* @returns The getter function found in the prototype chain or a fallback function.
2065	*/
2066	function lookupGetter(object, prop) {
2067		while (object !== null) {
2068			const desc = getOwnPropertyDescriptor(object, prop);
2069			if (desc) {
2070				if (desc.get) return unapply(desc.get);
2071				if (typeof desc.value === "function") return unapply(desc.value);
2072			}
2073			object = getPrototypeOf(object);
2074		}
2075		function fallbackValue() {
2076			return null;
2077		}
2078		return fallbackValue;
2079	}
2080	function isRegex(value) {
2081		try {
2082			regExpTest(value, "");
2083			return true;
2084		} catch (_unused) {
2085			return false;
2086		}
2087	}
2088	function createDOMPurify() {
2089		let window = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
2090		const DOMPurify = (root) => createDOMPurify(root);
2091		DOMPurify.version = "3.4.11";
2092		DOMPurify.removed = [];
2093		if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
2094			DOMPurify.isSupported = false;
2095			return DOMPurify;
2096		}
2097		let document = window.document;
2098		const originalDocument = document;
2099		const currentScript = originalDocument.currentScript;
2100		window.DocumentFragment;
2101		const HTMLTemplateElement = window.HTMLTemplateElement;
2102		const Node = window.Node;
2103		const Element = window.Element;
2104		const NodeFilter = window.NodeFilter;
2105		window.NamedNodeMap === void 0 && (window.NamedNodeMap || window.MozNamedAttrMap);
2106		window.HTMLFormElement;
2107		const DOMParser = window.DOMParser;
2108		const trustedTypes = window.trustedTypes;
2109		const ElementPrototype = Element.prototype;
2110		const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
2111		const remove = lookupGetter(ElementPrototype, "remove");
2112		const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
2113		const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
2114		const getParentNode = lookupGetter(ElementPrototype, "parentNode");
2115		const getShadowRoot = lookupGetter(ElementPrototype, "shadowRoot");
2116		const getAttributes = lookupGetter(ElementPrototype, "attributes");
2117		const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeType") : null;
2118		const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, "nodeName") : null;
2119		if (typeof HTMLTemplateElement === "function") {
2120			const template = document.createElement("template");
2121			if (template.content && template.content.ownerDocument) document = template.content.ownerDocument;
2122		}
2123		let trustedTypesPolicy;
2124		let emptyHTML = "";
2125		let defaultTrustedTypesPolicy;
2126		let defaultTrustedTypesPolicyResolved = false;
2127		let IN_TRUSTED_TYPES_POLICY = 0;
2128		const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy() {
2129			if (IN_TRUSTED_TYPES_POLICY > 0) throw typeErrorCreate("A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the \"DOMPurify and Trusted Types\" section of the README.");
2130		};
2131		const _createTrustedHTML = function _createTrustedHTML(html) {
2132			_assertNotInTrustedTypesPolicy();
2133			IN_TRUSTED_TYPES_POLICY++;
2134			try {
2135				return trustedTypesPolicy.createHTML(html);
2136			} finally {
2137				IN_TRUSTED_TYPES_POLICY--;
2138			}
2139		};
2140		const _createTrustedScriptURL = function _createTrustedScriptURL(scriptUrl) {
2141			_assertNotInTrustedTypesPolicy();
2142			IN_TRUSTED_TYPES_POLICY++;
2143			try {
2144				return trustedTypesPolicy.createScriptURL(scriptUrl);
2145			} finally {
2146				IN_TRUSTED_TYPES_POLICY--;
2147			}
2148		};
2149		const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy() {
2150			if (!defaultTrustedTypesPolicyResolved) {
2151				defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
2152				defaultTrustedTypesPolicyResolved = true;
2153			}
2154			return defaultTrustedTypesPolicy;
2155		};
2156		const _document = document;
2157		const implementation = _document.implementation;
2158		const createNodeIterator = _document.createNodeIterator;
2159		const createDocumentFragment = _document.createDocumentFragment;
2160		const getElementsByTagName = _document.getElementsByTagName;
2161		const importNode = originalDocument.importNode;
2162		let hooks = _createHooksMap();
2163		/**
2164		* Expose whether this browser supports running the full DOMPurify.
2165		*/
2166		DOMPurify.isSupported = typeof entries === "function" && typeof getParentNode === "function" && implementation && implementation.createHTMLDocument !== void 0;
2167		const MUSTACHE_EXPR$1 = MUSTACHE_EXPR;
2168		const ERB_EXPR$1 = ERB_EXPR;
2169		const TMPLIT_EXPR$1 = TMPLIT_EXPR;
2170		const DATA_ATTR$1 = DATA_ATTR;
2171		const ARIA_ATTR$1 = ARIA_ATTR;
2172		const IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA;
2173		const ATTR_WHITESPACE$1 = ATTR_WHITESPACE;
2174		const
vendor: 6,772 bytes, lines 2174-2387
2174 CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
2175		let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
2176		/**
2177		* We consider the elements and attributes below to be safe. Ideally
2178		* don't add any new ones but feel free to remove unwanted ones.
2179		*/
2180		let ALLOWED_TAGS = null;
2181		const DEFAULT_ALLOWED_TAGS = addToSet({}, [
2182			...html$1,
2183			...svg$1,
2184			...svgFilters,
2185			...mathMl$1,
2186			...text
2187		]);
2188		let ALLOWED_ATTR = null;
2189		const DEFAULT_ALLOWED_ATTR = addToSet({}, [
2190			...html,
2191			...svg,
2192			...mathMl,
2193			...xml
2194		]);
2195		let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
2196			tagNameCheck: {
2197				writable: true,
2198				configurable: false,
2199				enumerable: true,
2200				value: null
2201			},
2202			attributeNameCheck: {
2203				writable: true,
2204				configurable: false,
2205				enumerable: true,
2206				value: null
2207			},
2208			allowCustomizedBuiltInElements: {
2209				writable: true,
2210				configurable: false,
2211				enumerable: true,
2212				value: false
2213			}
2214		}));
2215		let FORBID_TAGS = null;
2216		let FORBID_ATTR = null;
2217		const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
2218			tagCheck: {
2219				writable: true,
2220				configurable: false,
2221				enumerable: true,
2222				value: null
2223			},
2224			attributeCheck: {
2225				writable: true,
2226				configurable: false,
2227				enumerable: true,
2228				value: null
2229			}
2230		}));
2231		let ALLOW_ARIA_ATTR = true;
2232		let ALLOW_DATA_ATTR = true;
2233		let ALLOW_UNKNOWN_PROTOCOLS = false;
2234		let ALLOW_SELF_CLOSE_IN_ATTR = true;
2235		let SAFE_FOR_TEMPLATES = false;
2236		let SAFE_FOR_XML = true;
2237		let WHOLE_DOCUMENT = false;
2238		let SET_CONFIG = false;
2239		let SET_CONFIG_ALLOWED_TAGS = null;
2240		let SET_CONFIG_ALLOWED_ATTR = null;
2241		let FORCE_BODY = false;
2242		let RETURN_DOM = false;
2243		let RETURN_DOM_FRAGMENT = false;
2244		let RETURN_TRUSTED_TYPE = false;
2245		let SANITIZE_DOM = true;
2246		let SANITIZE_NAMED_PROPS = false;
2247		const SANITIZE_NAMED_PROPS_PREFIX = "user-content-";
2248		let KEEP_CONTENT = true;
2249		let IN_PLACE = false;
2250		let USE_PROFILES = {};
2251		let FORBID_CONTENTS = null;
2252		const DEFAULT_FORBID_CONTENTS = addToSet({}, [
2253			"annotation-xml",
2254			"audio",
2255			"colgroup",
2256			"desc",
2257			"foreignobject",
2258			"head",
2259			"iframe",
2260			"math",
2261			"mi",
2262			"mn",
2263			"mo",
2264			"ms",
2265			"mtext",
2266			"noembed",
2267			"noframes",
2268			"noscript",
2269			"plaintext",
2270			"script",
2271			"selectedcontent",
2272			"style",
2273			"svg",
2274			"template",
2275			"thead",
2276			"title",
2277			"video",
2278			"xmp"
2279		]);
2280		let DATA_URI_TAGS = null;
2281		const DEFAULT_DATA_URI_TAGS = addToSet({}, [
2282			"audio",
2283			"video",
2284			"img",
2285			"source",
2286			"image",
2287			"track"
2288		]);
2289		let URI_SAFE_ATTRIBUTES = null;
2290		const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, [
2291			"alt",
2292			"class",
2293			"for",
2294			"id",
2295			"label",
2296			"name",
2297			"pattern",
2298			"placeholder",
2299			"role",
2300			"summary",
2301			"title",
2302			"value",
2303			"style",
2304			"xmlns"
2305		]);
2306		const MATHML_NAMESPACE = "http://www.w3.org/1998/Math/MathML";
2307		const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
2308		const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
2309		let NAMESPACE = HTML_NAMESPACE;
2310		let IS_EMPTY_INPUT = false;
2311		let ALLOWED_NAMESPACES = null;
2312		const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [
2313			MATHML_NAMESPACE,
2314			SVG_NAMESPACE,
2315			HTML_NAMESPACE
2316		], stringToString);
2317		const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze([
2318			"mi",
2319			"mo",
2320			"mn",
2321			"ms",
2322			"mtext"
2323		]);
2324		let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
2325		const DEFAULT_HTML_INTEGRATION_POINTS = freeze(["annotation-xml"]);
2326		let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
2327		const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, [
2328			"title",
2329			"style",
2330			"font",
2331			"a",
2332			"script"
2333		]);
2334		let PARSER_MEDIA_TYPE = null;
2335		const SUPPORTED_PARSER_MEDIA_TYPES = ["application/xhtml+xml", "text/html"];
2336		const DEFAULT_PARSER_MEDIA_TYPE = "text/html";
2337		let transformCaseFunc = null;
2338		let CONFIG = null;
2339		const formElement = document.createElement("form");
2340		const isRegexOrFunction = function isRegexOrFunction(testValue) {
2341			return testValue instanceof RegExp || testValue instanceof Function;
2342		};
2343		/**
2344		* _parseConfig
2345		*
2346		* @param cfg optional config literal
2347		*/
2348		const _parseConfig = function _parseConfig() {
2349			let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
2350			if (CONFIG && CONFIG === cfg) return;
2351			if (!cfg || typeof cfg !== "object") cfg = {};
2352			cfg = clone(cfg);
2353			PARSER_MEDIA_TYPE = SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
2354			transformCaseFunc = PARSER_MEDIA_TYPE === "application/xhtml+xml" ? stringToString : stringToLowerCase;
2355			ALLOWED_TAGS = _resolveSetOption(cfg, "ALLOWED_TAGS", DEFAULT_ALLOWED_TAGS, { transform: transformCaseFunc });
2356			ALLOWED_ATTR = _resolveSetOption(cfg, "ALLOWED_ATTR", DEFAULT_ALLOWED_ATTR, { transform: transformCaseFunc });
2357			ALLOWED_NAMESPACES = _resolveSetOption(cfg, "ALLOWED_NAMESPACES", DEFAULT_ALLOWED_NAMESPACES, { transform: stringToString });
2358			URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, "ADD_URI_SAFE_ATTR", DEFAULT_URI_SAFE_ATTRIBUTES, {
2359				transform: transformCaseFunc,
2360				base: DEFAULT_URI_SAFE_ATTRIBUTES
2361			});
2362			DATA_URI_TAGS = _resolveSetOption(cfg, "ADD_DATA_URI_TAGS", DEFAULT_DATA_URI_TAGS, {
2363				transform: transformCaseFunc,
2364				base: DEFAULT_DATA_URI_TAGS
2365			});
2366			FORBID_CONTENTS = _resolveSetOption(cfg, "FORBID_CONTENTS", DEFAULT_FORBID_CONTENTS, { transform: transformCaseFunc });
2367			FORBID_TAGS = _resolveSetOption(cfg, "FORBID_TAGS", clone({}), { transform: transformCaseFunc });
2368			FORBID_ATTR = _resolveSetOption(cfg, "FORBID_ATTR", clone({}), { transform: transformCaseFunc });
2369			USE_PROFILES = objectHasOwnProperty(cfg, "USE_PROFILES") ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === "object" ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
2370			ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false;
2371			ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false;
2372			ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false;
2373			ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false;
2374			SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false;
2375			SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false;
2376			WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false;
2377			RETURN_DOM = cfg.RETURN_DOM || false;
2378			RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false;
2379			RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false;
2380			FORCE_BODY = cfg.FORCE_BODY || false;
2381			SANITIZE_DOM = cfg.SANITIZE_DOM !== false;
2382			SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false;
2383			KEEP_CONTENT = cfg.KEEP_CONTENT !== false;
2384			IN_PLACE = cfg.IN_PLACE || false;
2385			IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI;
2386			NAMESPACE = typeof cfg.NAMESPACE === "string" ? cfg.NAMESPACE : HTML_NAMESPACE;
2387			MATHML_TEXT_INTEGRATION_POINTS = 
vendor: 7,021 bytes, lines 2387-2517
2387objectHasOwnProperty(cfg, "MATHML_TEXT_INTEGRATION_POINTS") && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === "object" ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
2388			HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, "HTML_INTEGRATION_POINTS") && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === "object" ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
2389			const customElementHandling = objectHasOwnProperty(cfg, "CUSTOM_ELEMENT_HANDLING") && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === "object" ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
2390			CUSTOM_ELEMENT_HANDLING = create(null);
2391			if (objectHasOwnProperty(customElementHandling, "tagNameCheck") && isRegexOrFunction(customElementHandling.tagNameCheck)) CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck;
2392			if (objectHasOwnProperty(customElementHandling, "attributeNameCheck") && isRegexOrFunction(customElementHandling.attributeNameCheck)) CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck;
2393			if (objectHasOwnProperty(customElementHandling, "allowCustomizedBuiltInElements") && typeof customElementHandling.allowCustomizedBuiltInElements === "boolean") CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements;
2394			seal(CUSTOM_ELEMENT_HANDLING);
2395			if (SAFE_FOR_TEMPLATES) ALLOW_DATA_ATTR = false;
2396			if (RETURN_DOM_FRAGMENT) RETURN_DOM = true;
2397			if (USE_PROFILES) {
2398				ALLOWED_TAGS = addToSet({}, text);
2399				ALLOWED_ATTR = create(null);
2400				if (USE_PROFILES.html === true) {
2401					addToSet(ALLOWED_TAGS, html$1);
2402					addToSet(ALLOWED_ATTR, html);
2403				}
2404				if (USE_PROFILES.svg === true) {
2405					addToSet(ALLOWED_TAGS, svg$1);
2406					addToSet(ALLOWED_ATTR, svg);
2407					addToSet(ALLOWED_ATTR, xml);
2408				}
2409				if (USE_PROFILES.svgFilters === true) {
2410					addToSet(ALLOWED_TAGS, svgFilters);
2411					addToSet(ALLOWED_ATTR, svg);
2412					addToSet(ALLOWED_ATTR, xml);
2413				}
2414				if (USE_PROFILES.mathMl === true) {
2415					addToSet(ALLOWED_TAGS, mathMl$1);
2416					addToSet(ALLOWED_ATTR, mathMl);
2417					addToSet(ALLOWED_ATTR, xml);
2418				}
2419			}
2420			EXTRA_ELEMENT_HANDLING.tagCheck = null;
2421			EXTRA_ELEMENT_HANDLING.attributeCheck = null;
2422			if (objectHasOwnProperty(cfg, "ADD_TAGS")) {
2423				if (typeof cfg.ADD_TAGS === "function") EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
2424				else if (arrayIsArray(cfg.ADD_TAGS)) {
2425					if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) ALLOWED_TAGS = clone(ALLOWED_TAGS);
2426					addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
2427				}
2428			}
2429			if (objectHasOwnProperty(cfg, "ADD_ATTR")) {
2430				if (typeof cfg.ADD_ATTR === "function") EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
2431				else if (arrayIsArray(cfg.ADD_ATTR)) {
2432					if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) ALLOWED_ATTR = clone(ALLOWED_ATTR);
2433					addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
2434				}
2435			}
2436			if (objectHasOwnProperty(cfg, "ADD_URI_SAFE_ATTR") && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
2437			if (objectHasOwnProperty(cfg, "FORBID_CONTENTS") && arrayIsArray(cfg.FORBID_CONTENTS)) {
2438				if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
2439				addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
2440			}
2441			if (objectHasOwnProperty(cfg, "ADD_FORBID_CONTENTS") && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
2442				if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) FORBID_CONTENTS = clone(FORBID_CONTENTS);
2443				addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
2444			}
2445			if (KEEP_CONTENT) ALLOWED_TAGS["#text"] = true;
2446			if (WHOLE_DOCUMENT) addToSet(ALLOWED_TAGS, [
2447				"html",
2448				"head",
2449				"body"
2450			]);
2451			if (ALLOWED_TAGS.table) {
2452				addToSet(ALLOWED_TAGS, ["tbody"]);
2453				delete FORBID_TAGS.tbody;
2454			}
2455			if (cfg.TRUSTED_TYPES_POLICY) {
2456				if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createHTML\" hook.");
2457				if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== "function") throw typeErrorCreate("TRUSTED_TYPES_POLICY configuration option must provide a \"createScriptURL\" hook.");
2458				const previousTrustedTypesPolicy = trustedTypesPolicy;
2459				trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
2460				try {
2461					emptyHTML = _createTrustedHTML("");
2462				} catch (error) {
2463					trustedTypesPolicy = previousTrustedTypesPolicy;
2464					throw error;
2465				}
2466			} else if (cfg.TRUSTED_TYPES_POLICY === null) {
2467				trustedTypesPolicy = void 0;
2468				emptyHTML = "";
2469			} else {
2470				if (trustedTypesPolicy === void 0) trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
2471				if (trustedTypesPolicy && typeof emptyHTML === "string") emptyHTML = _createTrustedHTML("");
2472			}
2473			if (freeze) freeze(cfg);
2474			CONFIG = cfg;
2475		};
2476		const ALL_SVG_TAGS = addToSet({}, [
2477			...svg$1,
2478			...svgFilters,
2479			...svgDisallowed
2480		]);
2481		const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
2482		/**
2483		* Namespace rules for an element in the SVG namespace.
2484		*
2485		* @param tagName the element's lowercase tag name
2486		* @param parent the (possibly simulated) parent node
2487		* @param parentTagName the parent's lowercase tag name
2488		* @returns true if a spec-compliant parser could produce this element
2489		*/
2490		const _checkSvgNamespace = function _checkSvgNamespace(tagName, parent, parentTagName) {
2491			if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "svg";
2492			if (parent.namespaceURI === MATHML_NAMESPACE) return tagName === "svg" && (parentTagName === "annotation-xml" || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
2493			return Boolean(ALL_SVG_TAGS[tagName]);
2494		};
2495		/**
2496		* Namespace rules for an element in the MathML namespace.
2497		*
2498		* @param tagName the element's lowercase tag name
2499		* @param parent the (possibly simulated) parent node
2500		* @param parentTagName the parent's lowercase tag name
2501		* @returns true if a spec-compliant parser could produce this element
2502		*/
2503		const _checkMathMlNamespace = function _checkMathMlNamespace(tagName, parent, parentTagName) {
2504			if (parent.namespaceURI === HTML_NAMESPACE) return tagName === "math";
2505			if (parent.namespaceURI === SVG_NAMESPACE) return tagName === "math" && HTML_INTEGRATION_POINTS[parentTagName];
2506			return Boolean(ALL_MATHML_TAGS[tagName]);
2507		};
2508		/**
2509		* Namespace rules for an element in the HTML namespace.
2510		*
2511		* @param tagName the element's lowercase tag name
2512		* @param parent the (possibly simulated) parent node
2513		* @param parentTagName the parent's lowercase tag name
2514		* @returns true if a spec-compliant parser could produce this element
2515		*/
2516		const _checkHtmlNamespace = function _checkHtmlNamespace(tagName, parent, parentTagName) {
2517			if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) return false;
vendor: 4,228 bytes, lines 2518-2629
2518			if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) return false;
2519			return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
2520		};
2521		/**
2522		* @param element a DOM element whose namespace is being checked
2523		* @returns Return false if the element has a
2524		*  namespace that a spec-compliant parser would never
2525		*  return. Return true otherwise.
2526		*/
2527		const _checkValidNamespace = function _checkValidNamespace(element) {
2528			let parent = getParentNode(element);
2529			if (!parent || !parent.tagName) parent = {
2530				namespaceURI: NAMESPACE,
2531				tagName: "template"
2532			};
2533			const tagName = stringToLowerCase(element.tagName);
2534			const parentTagName = stringToLowerCase(parent.tagName);
2535			if (!ALLOWED_NAMESPACES[element.namespaceURI]) return false;
2536			if (element.namespaceURI === SVG_NAMESPACE) return _checkSvgNamespace(tagName, parent, parentTagName);
2537			if (element.namespaceURI === MATHML_NAMESPACE) return _checkMathMlNamespace(tagName, parent, parentTagName);
2538			if (element.namespaceURI === HTML_NAMESPACE) return _checkHtmlNamespace(tagName, parent, parentTagName);
2539			if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && ALLOWED_NAMESPACES[element.namespaceURI]) return true;
2540			return false;
2541		};
2542		/**
2543		* _forceRemove
2544		*
2545		* @param node a DOM node
2546		*/
2547		const _forceRemove = function _forceRemove(node) {
2548			arrayPush(DOMPurify.removed, { element: node });
2549			try {
2550				getParentNode(node).removeChild(node);
2551			} catch (_) {
2552				remove(node);
2553				if (!getParentNode(node)) throw typeErrorCreate("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place");
2554			}
2555		};
2556		/**
2557		* _neutralizeRoot
2558		*
2559		* Fail-closed teardown of an in-place root after the sanitize walk aborts
2560		* (campaign-3 F2). An internal throw mid-walk — e.g. a page-registered
2561		* custom element's reaction detaches a node so `_forceRemove`'s deliberate
2562		* parentless guard throws, or any other re-entrant engine mutation — would
2563		* otherwise leave the caller's *live* tree half-sanitized, with everything
2564		* after the abort point still carrying its handlers. There is no safe way
2565		* to resume the walk (the tree mutated under us), so we strip the root bare:
2566		* remove every child and every attribute, then let the caller's catch see
2567		* the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes`
2568		* getters; the root was already clobber-pre-flighted at the IN_PLACE entry).
2569		*
2570		* @param root the in-place root to empty
2571		*/
2572		const _neutralizeRoot = function _neutralizeRoot(root) {
2573			const childNodes = getChildNodes(root);
2574			if (childNodes) {
2575				const snapshot = [];
2576				arrayForEach(childNodes, (child) => {
2577					arrayPush(snapshot, child);
2578				});
2579				arrayForEach(snapshot, (child) => {
2580					try {
2581						remove(child);
2582					} catch (_) {}
2583				});
2584			}
2585			const attributes = getAttributes(root);
2586			if (attributes) for (let i = attributes.length - 1; i >= 0; --i) {
2587				const attribute = attributes[i];
2588				const name = attribute && attribute.name;
2589				if (typeof name === "string") try {
2590					root.removeAttribute(name);
2591				} catch (_) {}
2592			}
2593		};
2594		/**
2595		* _removeAttribute
2596		*
2597		* @param name an Attribute name
2598		* @param element a DOM node
2599		*/
2600		const _removeAttribute = function _removeAttribute(name, element) {
2601			try {
2602				arrayPush(DOMPurify.removed, {
2603					attribute: element.getAttributeNode(name),
2604					from: element
2605				});
2606			} catch (_) {
2607				arrayPush(DOMPurify.removed, {
2608					attribute: null,
2609					from: element
2610				});
2611			}
2612			element.removeAttribute(name);
2613			if (name === "is") if (RETURN_DOM || RETURN_DOM_FRAGMENT) try {
2614				_forceRemove(element);
2615			} catch (_) {}
2616			else try {
2617				element.setAttribute(name, "");
2618			} catch (_) {}
2619		};
2620		/**
2621		* _stripDisallowedAttributes
2622		*
2623		* Removes every attribute the active configuration does not allow from a
2624		* single element, using the same allowlist as the main attribute pass (so
2625		* `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to
2626		* neutralise nodes that are being discarded from an in-place tree.
2627		*
2628		* @param element the element to strip
2629		*/
vendor: 8,537 bytes, lines 2630-2793
2630		const _stripDisallowedAttributes = function _stripDisallowedAttributes(element) {
2631			const attributes = getAttributes(element);
2632			if (!attributes) return;
2633			for (let i = attributes.length - 1; i >= 0; --i) {
2634				const attribute = attributes[i];
2635				const name = attribute && attribute.name;
2636				if (typeof name !== "string" || ALLOWED_ATTR[transformCaseFunc(name)]) continue;
2637				try {
2638					element.removeAttribute(name);
2639				} catch (_) {}
2640			}
2641		};
2642		/**
2643		* _neutralizeSubtree
2644		*
2645		* Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT
2646		* move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary,
2647		* namespace, comment, processing-instruction and KEEP_CONTENT:false removals
2648		* all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path
2649		* those dropped nodes are detached from the caller's LIVE tree but a
2650		* handler-bearing original among them (an `<img onerror>`/`<video>` that was
2651		* loading) keeps its queued resource event, which fires in page scope after
2652		* sanitize returns. This walks a removed subtree and strips every attribute
2653		* the active configuration does not allow — so `on*` handlers are cancelled
2654		* through the SAME allowlist that governs kept nodes, not a separate `/^on/`
2655		* blocklist. Run synchronously before sanitize returns, i.e. before any
2656		* queued event can fire. Hook-free by design: these nodes leave the output,
2657		* so firing attribute hooks for them would be surprising. Clobber-safe reads;
2658		* a doomed clobbered node may shadow `removeAttribute` (its own attributes are
2659		* irrelevant — it is discarded — while its non-clobbered descendants, e.g.
2660		* the `<img>`, are reached and scrubbed).
2661		*
2662		* @param root the root of a removed subtree to neutralise
2663		*/
2664		const _neutralizeSubtree = function _neutralizeSubtree(root) {
2665			const stack = [root];
2666			while (stack.length > 0) {
2667				const node = stack.pop();
2668				if ((getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element) _stripDisallowedAttributes(node);
2669				const childNodes = getChildNodes(node);
2670				if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push(childNodes[i]);
2671			}
2672		};
2673		/**
2674		* _initDocument
2675		*
2676		* @param dirty - a string of dirty markup
2677		* @return a DOM, filled with the dirty markup
2678		*/
2679		const _initDocument = function _initDocument(dirty) {
2680			let doc = null;
2681			let leadingWhitespace = null;
2682			if (FORCE_BODY) dirty = "<remove></remove>" + dirty;
2683			else {
2684				const matches = stringMatch(dirty, /^[\r\n\t ]+/);
2685				leadingWhitespace = matches && matches[0];
2686			}
2687			if (PARSER_MEDIA_TYPE === "application/xhtml+xml" && NAMESPACE === HTML_NAMESPACE) dirty = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>" + dirty + "</body></html>";
2688			const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
2689			if (NAMESPACE === HTML_NAMESPACE) try {
2690				doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
2691			} catch (_) {}
2692			if (!doc || !doc.documentElement) {
2693				doc = implementation.createDocument(NAMESPACE, "template", null);
2694				try {
2695					doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
2696				} catch (_) {}
2697			}
2698			const body = doc.body || doc.documentElement;
2699			if (dirty && leadingWhitespace) body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
2700			if (NAMESPACE === HTML_NAMESPACE) return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? "html" : "body")[0];
2701			return WHOLE_DOCUMENT ? doc.documentElement : body;
2702		};
2703		/**
2704		* Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
2705		*
2706		* @param root The root element or node to start traversing on.
2707		* @return The created NodeIterator
2708		*/
2709		const _createNodeIterator = function _createNodeIterator(root) {
2710			return createNodeIterator.call(root.ownerDocument || root, root, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
2711		};
2712		/**
2713		* Replace template expression syntax (mustache, ERB, template
2714		* literal) with a space; shared by all SAFE_FOR_TEMPLATES scrub
2715		* sites. Order matters: mustache, then ERB, then template literal.
2716		*
2717		* @param value the string to scrub
2718		* @returns the scrubbed string
2719		*/
2720		const _stripTemplateExpressions = function _stripTemplateExpressions(value) {
2721			value = stringReplace(value, MUSTACHE_EXPR$1, " ");
2722			value = stringReplace(value, ERB_EXPR$1, " ");
2723			value = stringReplace(value, TMPLIT_EXPR$1, " ");
2724			return value;
2725		};
2726		/**
2727		* Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the
2728		* character data of an element subtree. Used as the final safety net for
2729		* SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions
2730		* which only form after text-node normalization (e.g. fragments split across
2731		* stripped elements) cannot survive into a template-evaluating framework.
2732		*
2733		* Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`
2734		* in place rather than round-tripping through innerHTML. This preserves
2735		* descendant node references (important for IN_PLACE callers), avoids a
2736		* serialize/reparse cycle, and reads literal character data — which means
2737		* `<%...%>` in text content matches the ERB regex against its real bytes
2738		* instead of the HTML-entity-escaped form innerHTML would produce.
2739		*
2740		* Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for
2741		* attributes is performed during the per-node `_sanitizeAttributes` pass.
2742		*
2743		* @param node The root element whose character data should be scrubbed.
2744		*/
2745		const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
2746			var _node$querySelectorAl;
2747			node.normalize();
2748			const walker = createNodeIterator.call(node.ownerDocument || node, node, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
2749			let currentNode = walker.nextNode();
2750			while (currentNode) {
2751				currentNode.data = _stripTemplateExpressions(currentNode.data);
2752				currentNode = walker.nextNode();
2753			}
2754			const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, "template");
2755			if (templates) arrayForEach(templates, (tmpl) => {
2756				if (_isDocumentFragment(tmpl.content)) _scrubTemplateExpressions2(tmpl.content);
2757			});
2758		};
2759		/**
2760		* _isClobbered
2761		*
2762		* Detect DOM-clobbering on HTMLFormElement nodes. Form is the only HTML
2763		* interface with [LegacyOverrideBuiltIns]; a descendant element with a
2764		* `name` attribute matching a prototype property shadows that property
2765		* on direct reads. We use this check at the IN_PLACE entry-point and
2766		* during attribute sanitization to refuse clobbered forms.
2767		*
2768		* @param element element to check for clobbering attacks
2769		* @return true if clobbered, false if safe
2770		*/
2771		const _isClobbered = function _isClobbered(element) {
2772			const realTagName = getNodeName ? getNodeName(element) : null;
2773			if (typeof realTagName !== "string") return false;
2774			if (transformCaseFunc(realTagName) !== "form") return false;
2775			return typeof element.nodeName !== "string" || typeof element.textContent !== "string" || typeof element.removeChild !== "function" || element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || element.nodeType !== getNodeType(element) || element.childNodes !== getChildNodes(element);
2776		};
2777		/**
2778		* Checks whether the given value is a DocumentFragment from any realm.
2779		*
2780		* The realm-independent replacement reads `nodeType` through the cached
2781		* Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE
2782		* constant (11). nodeType is a numeric value resolved from the node's
2783		* internal slot, identical across realms for the same kind of node.
2784		*
2785		* @param value object to check
2786		* @return true if value is a DocumentFragment-shaped node from any realm
2787		*/
2788		const _isDocumentFragment = function _isDocumentFragment(value) {
2789			if (!getNodeType || typeof value !== "object" || value === null) return false;
2790			try {
2791				return getNodeType(value) === NODE_TYPE.documentFragment;
2792			} catch (_) {
2793				return false;
2794			}
2795		};
2796		/**
2797		* Checks whether the given object is a DOM node, including nodes that
2798		* originate from a different window/realm (e.g. an iframe's
2799		* contentDocument). The previous `value instanceof Node` check was
2800		* realm-bound: nodes from a different window failed it, causing
2801		* sanitize() to silently stringify them and reset IN_PLACE to false,
2802		* returning the original node unsanitized. See GHSA-4w3q-35jp-p934.
2803		*
2804		* @param value object to check whether it's a DOM node
2805		* @return true if value is a DOM node from any realm
2806		*/
2807		const _isNode = function _isNode(value) {
2808			if (!getNodeType || typeof value !== "object" || value === null) return false;
2809			try {
2810				return typeof getNodeType(value) === "number";
2811			} catch (_) {
2812				return false;
2813			}
2814		};
2815		function _executeHooks(hooks, currentNode, data) {
2816			if (hooks.length === 0) return;
2817			arrayForEach(hooks, (hook) => {
2818				hook.call(DOMPurify, currentNode, data, CONFIG);
2819			});
2820		}
2821		/**
2822		* Structural-threat checks that condemn a node regardless of the
2823		* allowlists: mXSS via namespace confusion, risky CSS construction,
2824		* processing instructions, markup-bearing comments. Pure predicate;
2825		* the caller removes. Check order is load-bearing.
2826		*
2827		* @param currentNode the node to inspect
2828		* @param tagName the node's transformCaseFunc'd tag name
2829		* @return true if the node must be removed
2830		*/
2831		const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
2832			if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) return true;
2833			if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === "style" && _isNode(currentNode.firstElementChild)) return true;
2834			if (currentNode.nodeType === NODE_TYPE.processingInstruction) return true;
2835			if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) return true;
2836			return false;
2837		};
2838		/**
2839		* Handle a node whose tag is forbidden or not allowlisted: keep
2840		* allowed custom elements (false return exits _sanitizeElements
2841		* early - namespace/fallback checks and the afterSanitizeElements
2842		* hook are intentionally skipped for kept custom elements), else
2843		* hoist content per KEEP_CONTENT and remove.
2844		*
2845		* @param currentNode the disallowed node
2846		* @param tagName the node's transformCaseFunc'd tag name
2847		* @return true if the node was removed, false if kept
2848		*/
2849		const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName) {
2850			if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
2851				if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) return false;
2852				if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) return false;
2853			}
2854			if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
2855				const parentNode = getParentNode(currentNode);
2856				const childNodes = getChildNodes(currentNode);
2857				if (childNodes && parentNode) {
2858					const childCount = childNodes.length;
2859					for (let i = childCount - 1; i >= 0; --i) {
2860						const hoisted = IN_PLACE ? childNodes[i] : cloneNode(childNodes[i], true);
2861						parentNode.insertBefore(hoisted, getNextSibling(currentNode));
2862					}
2863				}
2864			}
2865			_forceRemove(currentNode);
2866			return true;
2867		};
2868		/**
2869		* _sanitizeElements
2870		*
2871		* @protect nodeName
2872		* @protect textContent
2873		* @protect removeChild
2874		* @param currentNode to check for permission to exist
2875		* @return true if node was killed, false if left alive
2876		*/
2877		const _sanitizeElements = function _sanitizeElements(currentNode) {
2878			_executeHooks(hooks.beforeSanitizeElements, currentNode, null);
2879			if (_isClobbered(currentNode)) {
2880				_forceRemove(currentNode);
2881				return true;
2882			}
2883			const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
2884			_executeHooks(hooks.uponSanitizeElement, currentNode, {
2885				tagName,
2886				allowedTags: ALLOWED_TAGS
2887			});
2888			if (_isUnsafeNode(currentNode, tagName)) {
2889				_forceRemove(currentNode);
2890				return true;
2891			}
2892			if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) return _sanitizeDisallowedNode(currentNode, tagName);
2893			if ((getNodeType ? getNodeType(currentNode) : currentNode.nodeType) === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
2894				_forceRemove(currentNode);
2895				return true;
2896			}
2897			if ((tagName === "noscript" || tagName === "noembed" || tagName === "noframes") && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
2898				_forceRemove(currentNode);
2899				return true;
2900			}
2901			if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
2902				const content = _stripTemplateExpressions(currentNode.textContent);
2903				if (currentNode.textContent !== content) {
2904					arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
2905					currentNode.textContent = content;
2906				}
2907			}
2908			_executeHooks(hooks.afterSanitizeElements, currentNode, null);
2909			return false;
2910		};
2911		/**
2912		* _isValidAttribute
2913		*
2914		* @param lcTag Lowercase tag name of containing element.
2915		* @param lcName Lowercase attribute name.
2916		* @param value Attribute value.
2917		* @return Returns true if `value` is valid, otherwise false.
2918		*/
2919		const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
2920			if (FORBID_ATTR[lcName]) return false;
2921			if (SANITIZE_DOM && (lcName === "id" || lcName === "name") && (value in document || value in formElement)) return false;
2922			const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
2923			if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName));
2924			else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName));
2925			else if (!nameIsPermitted) if (_isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) || lcName === "is" && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value)));
2926			else return false;
2927			else if (URI_SAFE_ATTRIBUTES[lcName]);
2928			else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
2929			else if ((lcName === "src" || lcName === "xlink:href" || lcName === "href") && lcTag !== "script" && stringIndexOf(value, "data:") === 0 && DATA_URI_TAGS[lcTag]);
2930			else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1, "")));
2931			else if (value) return false;
2932			return true;
2933		};
2934		const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, [
2935			"annotation-xml",
2936			"color-profile",
2937			"font-face",
2938			"font-face-format",
2939			"font-face-name",
2940			"font-face-src",
2941			"font-face-uri",
2942			"missing-glyph"
2943		]);
2944		/**
2945		* _isBasicCustomElement
2946		* checks if at least one dash is included in tagName, and it's not the first char
2947		* for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
2948		*
2949		* @param tagName name of the tag of the node to sanitize
2950		* @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
2951		*/
2952		const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
2953			return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
2954		};
2955		/**
2956		* Wrap an attribute value in the matching Trusted Types object when
2957		* the active policy requires it. Namespaced attributes pass through
2958		* unchanged (no TT support yet, see
2959		* https://bugs.chromium.org/p/chromium/issues/detail?id=1305293).
2960		*
2961		* @param lcTag lowercase tag name of the containing element
2962		* @param lcName lowercase attribute name
2963		* @param namespaceURI the attribute's namespace, if any
2964		* @param value the attribute value to wrap
2965		* @return the value, wrapped when Trusted Types demand it
2966		*/
2967		const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value) {
2968			if (trustedTypesPolicy && typeof trustedTypes === "object" && typeof trustedTypes.getAttributeType === "function" && !namespaceURI) switch (trustedTypes.getAttributeType(lcTag, lcName)) {
2969				case "TrustedHTML": return _createTrustedHTML(value);
2970				case "TrustedScriptURL": return _createTrustedScriptURL(value);
2971			}
2972			return value;
2973		};
2974		/**
2975		* Write a modified attribute value back onto the element. On
2976		* success, re-probe for clobbering introduced by the new value and
2977		* remove the element when found; otherwise pop the removal entry
2978		* recorded by the earlier _removeAttribute (long-standing pairing
2979		* with the SANITIZE_NAMED_PROPS path - do not "fix" casually). On
2980		* failure, remove the attribute instead.
2981		*
2982		* @param currentNode the element carrying the attribute
2983		* @param name the attribute name as present on the element
2984		* @param namespaceURI the attribute's namespace, if any
2985		* @param value the new attribute value
2986		*/
2987		const _setAttributeValue = function _setAttributeValue(currentNode, name, namespaceURI, value) {
2988			try {
2989				if (namespaceURI) currentNode.setAttributeNS(namespaceURI, name, value);
2990				else currentNode.setAttribute(name, value);
2991				if (_isClobbered(currentNode)) _forceRemove(currentNode);
2992				else arrayPop(DOMPurify.removed);
2993			} catch (_) {
2994				_removeAttribute(name, currentNode);
2995			}
2996		};
2997		/**
2998		* _sanitizeAttributes
2999		*
3000		* @protect attributes
3001		* @protect nodeName
3002		* @protect removeAttribute
3003		* @protect setAttribute
3004		*
3005		* @param currentNode to sanitize
3006		*/
3007		const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
3008			_executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
3009			const attributes = currentNode.attributes;
3010			if (!attributes || _isClobbered(currentNode)) return;
3011			const hookEvent = {
3012				attrName: "",
3013				attrValue: "",
3014				keepAttr: true,
3015				allowedAttributes: ALLOWED_ATTR,
3016				forceKeepAttr: void 0
3017			};
3018			let l = attributes.length;
3019			const lcTag = transformCaseFunc(currentNode.nodeName);
3020			while (l--) {
3021				const attr = attributes[l];
3022				const name = attr.name;
3023				const namespaceURI = attr.namespaceURI;
3024				const attrValue = attr.value;
3025				const lcName = transformCaseFunc(name);
3026				const initValue = attrValue;
3027				let value = name === "value" ? initValue : stringTrim(initValue);
3028				hookEvent.attrName = lcName;
3029				hookEvent.attrValue = value;
3030				hookEvent.keepAttr = true;
3031				hookEvent.forceKeepAttr = void 0;
3032				_executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
3033				value = hookEvent.attrValue;
vendor: 4,122 bytes, lines 3034-3141
3034				if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
3035					_removeAttribute(name, currentNode);
3036					value = SANITIZE_NAMED_PROPS_PREFIX + value;
3037				}
3038				if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
3039					_removeAttribute(name, currentNode);
3040					continue;
3041				}
3042				if (lcName === "attributename" && stringMatch(value, "href")) {
3043					_removeAttribute(name, currentNode);
3044					continue;
3045				}
3046				if (hookEvent.forceKeepAttr) continue;
3047				if (!hookEvent.keepAttr) {
3048					_removeAttribute(name, currentNode);
3049					continue;
3050				}
3051				if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
3052					_removeAttribute(name, currentNode);
3053					continue;
3054				}
3055				if (SAFE_FOR_TEMPLATES) value = _stripTemplateExpressions(value);
3056				if (!_isValidAttribute(lcTag, lcName, value)) {
3057					_removeAttribute(name, currentNode);
3058					continue;
3059				}
3060				value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
3061				if (value !== initValue) _setAttributeValue(currentNode, name, namespaceURI, value);
3062			}
3063			_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
3064		};
3065		/**
3066		* _sanitizeShadowDOM
3067		*
3068		* @param fragment to iterate over recursively
3069		*/
3070		const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
3071			let shadowNode = null;
3072			const shadowIterator = _createNodeIterator(fragment);
3073			_executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
3074			while (shadowNode = shadowIterator.nextNode()) {
3075				_executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
3076				_sanitizeElements(shadowNode);
3077				_sanitizeAttributes(shadowNode);
3078				if (_isDocumentFragment(shadowNode.content)) _sanitizeShadowDOM2(shadowNode.content);
3079				if ((getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType) === NODE_TYPE.element) {
3080					const innerSr = getShadowRoot(shadowNode);
3081					if (_isDocumentFragment(innerSr)) {
3082						_sanitizeAttachedShadowRoots(innerSr);
3083						_sanitizeShadowDOM2(innerSr);
3084					}
3085				}
3086			}
3087			_executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
3088		};
3089		/**
3090		* _sanitizeAttachedShadowRoots
3091		*
3092		* Walks `root` and feeds every attached shadow root we encounter into
3093		* the existing _sanitizeShadowDOM pipeline. The default node iterator
3094		* does not descend into shadow trees, so nodes inside an attached
3095		* shadow root would otherwise be skipped entirely.
3096		*
3097		* Two real input paths put attached shadow roots in front of us:
3098		*   1. IN_PLACE on a DOM node that already has shadow roots attached.
3099		*   2. DOM-node input where importNode(dirty, true) deep-clones the
3100		*      shadow root because it was created with `clonable: true`.
3101		*
3102		* This pass runs once, up front, so the main iteration loop (and the
3103		* existing _sanitizeShadowDOM template-content recursion) stay
3104		* untouched — string-input paths are not affected.
3105		*
3106		* @param root the subtree root to walk for attached shadow roots
3107		*/
3108		const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots(root) {
3109			const stack = [{
3110				node: root,
3111				shadow: null
3112			}];
3113			while (stack.length > 0) {
3114				const item = stack.pop();
3115				if (item.shadow) {
3116					_sanitizeShadowDOM2(item.shadow);
3117					continue;
3118				}
3119				const node = item.node;
3120				const isElement = (getNodeType ? getNodeType(node) : node.nodeType) === NODE_TYPE.element;
3121				const childNodes = getChildNodes(node);
3122				if (childNodes) for (let i = childNodes.length - 1; i >= 0; --i) stack.push({
3123					node: childNodes[i],
3124					shadow: null
3125				});
3126				if (isElement) {
3127					const rootName = getNodeName ? getNodeName(node) : null;
3128					if (typeof rootName === "string" && transformCaseFunc(rootName) === "template") {
3129						const content = node.content;
3130						if (_isDocumentFragment(content)) stack.push({
3131							node: content,
3132							shadow: null
3133						});
3134					}
3135				}
3136				if (isElement) {
3137					const sr = getShadowRoot(node);
3138					if (_isDocumentFragment(sr)) stack.push({
3139						node: null,
3140						shadow: sr
3141					}, {
vendor: 4,286 bytes, lines 3142-3236
3142						node: sr,
3143						shadow: null
3144					});
3145				}
3146			}
3147		};
3148		DOMPurify.sanitize = function(dirty) {
3149			let cfg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
3150			let body = null;
3151			let importedNode = null;
3152			let currentNode = null;
3153			let returnNode = null;
3154			IS_EMPTY_INPUT = !dirty;
3155			if (IS_EMPTY_INPUT) dirty = "<!-->";
3156			if (typeof dirty !== "string" && !_isNode(dirty)) {
3157				dirty = stringifyValue(dirty);
3158				if (typeof dirty !== "string") throw typeErrorCreate("dirty is not a string, aborting");
3159			}
3160			if (!DOMPurify.isSupported) return dirty;
3161			if (SET_CONFIG) {
3162				ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
3163				ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
3164			} else _parseConfig(cfg);
3165			if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) ALLOWED_TAGS = clone(ALLOWED_TAGS);
3166			if (hooks.uponSanitizeAttribute.length > 0) ALLOWED_ATTR = clone(ALLOWED_ATTR);
3167			DOMPurify.removed = [];
3168			const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
3169			if (inPlace) {
3170				const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
3171				if (typeof nn === "string") {
3172					const tagName = transformCaseFunc(nn);
3173					if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
3174				}
3175				if (_isClobbered(dirty)) throw typeErrorCreate("root node is clobbered and cannot be sanitized in-place");
3176				try {
3177					_sanitizeAttachedShadowRoots(dirty);
3178				} catch (error) {
3179					_neutralizeRoot(dirty);
3180					throw error;
3181				}
3182			} else if (_isNode(dirty)) {
3183				body = _initDocument("<!---->");
3184				importedNode = body.ownerDocument.importNode(dirty, true);
3185				if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === "BODY") body = importedNode;
3186				else if (importedNode.nodeName === "HTML") body = importedNode;
3187				else body.appendChild(importedNode);
3188				_sanitizeAttachedShadowRoots(importedNode);
3189			} else {
3190				if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && dirty.indexOf("<") === -1) return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
3191				body = _initDocument(dirty);
3192				if (!body) return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : "";
3193			}
3194			if (body && FORCE_BODY) _forceRemove(body.firstChild);
3195			const nodeIterator = _createNodeIterator(inPlace ? dirty : body);
3196			try {
3197				while (currentNode = nodeIterator.nextNode()) {
3198					_sanitizeElements(currentNode);
3199					_sanitizeAttributes(currentNode);
3200					if (_isDocumentFragment(currentNode.content)) _sanitizeShadowDOM2(currentNode.content);
3201				}
3202			} catch (error) {
3203				if (inPlace) _neutralizeRoot(dirty);
3204				throw error;
3205			}
3206			if (inPlace) {
3207				arrayForEach(DOMPurify.removed, (entry) => {
3208					if (entry.element) _neutralizeSubtree(entry.element);
3209				});
3210				if (SAFE_FOR_TEMPLATES) _scrubTemplateExpressions2(dirty);
3211				return dirty;
3212			}
3213			if (RETURN_DOM) {
3214				if (SAFE_FOR_TEMPLATES) _scrubTemplateExpressions2(body);
3215				if (RETURN_DOM_FRAGMENT) {
3216					returnNode = createDocumentFragment.call(body.ownerDocument);
3217					while (body.firstChild) returnNode.appendChild(body.firstChild);
3218				} else returnNode = body;
3219				if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) returnNode = importNode.call(originalDocument, returnNode, true);
3220				return returnNode;
3221			}
3222			let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
3223			if (WHOLE_DOCUMENT && ALLOWED_TAGS["!doctype"] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) serializedHTML = "<!DOCTYPE " + body.ownerDocument.doctype.name + ">\n" + serializedHTML;
3224			if (SAFE_FOR_TEMPLATES) serializedHTML = _stripTemplateExpressions(serializedHTML);
3225			return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
3226		};
3227		DOMPurify.setConfig = function() {
3228			let cfg = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
3229			_parseConfig(cfg);
3230			SET_CONFIG = true;
3231			SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
3232			SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
3233		};
3234		DOMPurify.clearConfig = function() {
3235			CONFIG = null;
3236			SET_CONFIG = false;
3237			SET_CONFIG_ALLOWED_TAGS = null;
3238			SET_CONFIG_ALLOWED_ATTR = null;
3239			trustedTypesPolicy = defaultTrustedTypesPolicy;
3240			emptyHTML = "";
3241		};
3242		DOMPurify.isValidAttribute = function(tag, attr, value) {
3243			if (!CONFIG) _parseConfig({});
3244			const lcTag = transformCaseFunc(tag);
3245			const lcName = transformCaseFunc(attr);
3246			return _isValidAttribute(lcTag, lcName, value);
3247		};
3248		DOMPurify.addHook = function(entryPoint, hookFunction) {
3249			if (typeof hookFunction !== "function") return;
3250			if (!objectHasOwnProperty(hooks, entryPoint)) return;
3251			arrayPush(hooks[entryPoint], hookFunction);
3252		};
3253		DOMPurify.removeHook = function(entryPoint, hookFunction) {
3254			if (!objectHasOwnProperty(hooks, entryPoint)) return;
3255			if (hookFunction !== void 0) {
3256				const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
3257				return index === -1 ? void 0 : arraySplice(hooks[entryPoint], index, 1)[0];
3258			}
3259			return arrayPop(hooks[entryPoint]);
3260		};
3261		DOMPurify.removeHooks = function(entryPoint) {
3262			if (!objectHasOwnProperty(hooks, entryPoint)) return;
3263			hooks[entryPoint] = [];
3264		};
3265		DOMPurify.removeAllHooks = function() {
3266			hooks = _createHooksMap();
3267		};
3268		return DOMPurify;
3269	}
3270	var entries, setPrototypeOf, isFrozen, getPrototypeOf, getOwnPropertyDescriptor, freeze, seal, create, _ref, apply, construct, arrayForEach, arrayLastIndexOf, arrayPop, arrayPush, arraySplice, arrayIsArray, stringToLowerCase, stringToString, stringMatch, stringReplace, stringIndexOf, stringTrim, numberToString, booleanToString, bigintToString, symbolToString, objectHasOwnProperty, objectToString, regExpTest, typeErrorCreate, html$1, svg$1, svgFilters, svgDisallowed, mathMl$1, mathMlDisallowed, text, html, svg, mathMl, xml, MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR, DATA_ATTR, ARIA_ATTR, IS_ALLOWED_URI, IS_SCRIPT_OR_DATA, ATTR_WHITESPACE, DOCTYPE_NAME, CUSTOM_ELEMENT, ELEMENT_MARKUP_PROBE, COMMENT_MARKUP_PROBE, FALLBACK_TAG_CLOSE, SELF_CLOSING_TAG, NODE_TYPE, getGlobal, _createTrustedTypesPolicy, _createHooksMap, _resolveSetOption, purify;
3271	var init_purify_es = __esmMin((() => {
3272		entries = Object.entries;
3273		setPrototypeOf = Object.setPrototypeOf;
3274		isFrozen = Object.isFrozen;
3275		getPrototypeOf = Object.getPrototypeOf;
3276		getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
3277		freeze = Object.freeze;
3278		seal = Object.seal;
3279		create = Object.create;
3280		_ref = typeof Reflect !== "undefined" && Reflect;
3281		apply = _ref.apply;
3282		construct = _ref.construct;
3283		if (!freeze) freeze = function freeze(x) {
3284			return x;
3285		};
3286		if (!seal) seal = function seal(x) {
3287			return x;
3288		};
3289		if (!apply) apply = function apply(func, thisArg) {
3290			for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) args[_key - 2] = arguments[_key];
3291			return func.apply(thisArg, args);
3292		};
3293		if (!construct) construct = function construct(Func) {
3294			for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) args[_key2 - 1] = arguments[_key2];
3295			return new Func(...args);
3296		};
3297		arrayForEach = unapply(Array.prototype.forEach);
3298		arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
3299		arrayPop = unapply(Array.prototype.pop);
3300		arrayPush = unapply(Array.prototype.push);
3301		arraySplice = unapply(Array.prototype.splice);
3302		arrayIsArray = Array.isArray;
3303		stringToLowerCase = unapply(String.prototype.toLowerCase);
3304		stringToString = unapply(String.prototype.toString);
3305		stringMatch = unapply(String.prototype.match);
3306		stringReplace = unapply(String.prototype.replace);
3307		stringIndexOf = unapply(String.prototype.indexOf);
3308		stringTrim = unapply(String.prototype.trim);
3309		numberToString = unapply(Number.prototype.toString);
3310		booleanToString = unapply(Boolean.prototype.toString);
3311		bigintToString = typeof BigInt === "undefined" ? null : unapply(BigInt.prototype.toString);
3312		symbolToString = typeof Symbol === "undefined" ? null : unapply(Symbol.prototype.toString);
3313		objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
3314		objectToString = unapply(Object.prototype.toString);
3315		regExpTest = unapply(RegExp.prototype.test);
3316		typeErrorCreate = unconstruct(TypeError);
3317		html$1 = freeze([
3318			"a",
3319			"abbr",
3320			"acronym",
3321			"address",
3322			"area",
3323			"article",
3324			"aside",
3325			"audio",
3326			"b",
3327			"bdi",
3328			"bdo",
3329			"big",
3330			"blink",
3331			"blockquote",
3332			"body",
3333			"br",
3334			"button",
3335			"canvas",
3336			"caption",
3337			"center",
3338			"cite",
3339			"code",
3340			"col",
3341			"colgroup",
3342			"content",
3343			"data",
3344			"datalist",
3345			"dd",
3346			"decorator",
3347			"del",
3348			"details",
3349			"dfn",
3350			"dialog",
3351			"dir",
3352			"div",
3353			"dl",
3354			"dt",
3355			"element",
3356			"em",
3357			"fieldset",
3358			"figcaption",
3359			"figure",
3360			"font",
3361			"footer",
3362			"form",
3363			"h1",
3364			"h2",
3365			"h3",
3366			"h4",
3367			"h5",
3368			"h6",
3369			"head",
3370			"header",
3371			"hgroup",
3372			"hr",
3373			"html",
3374			"i",
3375			"img",
3376			"input",
3377			"ins",
3378			"kbd",
3379			"label",
3380			"legend",
3381			"li",
3382			"main",
3383			"map",
3384			"mark",
3385			"marquee",
3386			"menu",
3387			"menuitem",
3388			"meter",
3389			"nav",
3390			"nobr",
3391			"ol",
3392			"optgroup",
3393			"option",
3394			"output",
3395			"p",
3396			"picture",
3397			"pre",
3398			"progress",
3399			"q",
3400			"rp",
3401			"rt",
3402			"ruby",
3403			"s",
3404			"samp",
3405			"search",
3406			"section",
3407			"select",
3408			"shadow",
3409			"slot",
3410			"small",
3411			"source",
3412			"spacer",
3413			"span",
3414			"strike",
3415			"strong",
3416			"style",
3417			"sub",
3418			"summary",
3419			"sup",
3420			"table",
3421			"tbody",
3422			"td",
3423			"template",
3424			"textarea",
3425			"tfoot",
3426			"th",
3427			"thead",
3428			"time",
3429			"tr",
3430			"track",
3431			"tt",
3432			"u",
3433			"ul",
3434			"var",
3435			"video",
3436			"wbr"
3437		]);
3438		svg$1 = freeze([
3439			"svg",
3440			"a",
3441			"altglyph",
3442			"altglyphdef",
3443			"altglyphitem",
3444			"animatecolor",
3445			"animatemotion",
3446			"animatetransform",
3447			"circle",
3448			"clippath",
3449			"defs",
3450			"desc",
3451			"ellipse",
3452			"enterkeyhint",
3453			"exportparts",
3454			"filter",
3455			"font",
3456			"g",
3457			"glyph",
3458			"glyphref",
3459			"hkern",
3460			"image",
3461			"inputmode",
3462			"line",
3463			"lineargradient",
3464			"marker",
3465			"mask",
3466			"metadata",
3467			"mpath",
3468			"part",
3469			"path",
3470			"pattern",
3471			"polygon",
3472			"polyline",
3473			"radialgradient",
3474			"rect",
3475			"stop",
3476			"style",
3477			"switch",
3478			"symbol",
3479			"text",
3480			"textpath",
3481			"title",
3482			"tref",
3483			"tspan",
3484			"view",
3485			"vkern"
3486		]);
3487		svgFilters = freeze([
3488			"feBlend",
3489			"feColorMatrix",
3490			"feComponentTransfer",
3491			"feComposite",
3492			"feConvolveMatrix",
3493			"feDiffuseLighting",
3494			"feDisplacementMap",
3495			"feDistantLight",
3496			"feDropShadow",
3497			"feFlood",
3498			"feFuncA",
3499			"feFuncB",
3500			"feFuncG",
3501			"feFuncR",
3502			"feGaussianBlur",
3503			"feImage",
3504			"feMerge",
3505			"feMergeNode",
3506			"feMorphology",
3507			"feOffset",
3508			"fePointLight",
3509			"feSpecularLighting",
3510			"feSpotLight",
3511			"feTile",
3512			"feTurbulence"
3513		]);
3514		svgDisallowed = freeze([
3515			"animate",
3516			"color-profile",
3517			"cursor",
3518			"discard",
3519			"font-face",
3520			"font-face-format",
3521			"font-face-name",
3522			"font-face-src",
3523			"font-face-uri",
3524			"foreignobject",
3525			"hatch",
3526			"hatchpath",
3527			"mesh",
3528			"meshgradient",
3529			"meshpatch",
3530			"meshrow",
3531			"missing-glyph",
3532			"script",
3533			"set",
3534			"solidcolor",
3535			"unknown",
3536			"use"
3537		]);
3538		mathMl$1 = freeze([
3539			"math",
3540			"menclose",
3541			"merror",
3542			"mfenced",
3543			"mfrac",
3544			"mglyph",
3545			"mi",
3546			"mlabeledtr",
3547			"mmultiscripts",
3548			"mn",
3549			"mo",
3550			"mover",
3551			"mpadded",
3552			"mphantom",
3553			"mroot",
3554			"mrow",
3555			"ms",
3556			"mspace",
3557			"msqrt",
3558			"mstyle",
3559			"msub",
3560			"msup",
3561			"msubsup",
3562			"mtable",
3563			"mtd",
3564			"mtext",
3565			"mtr",
3566			"munder",
3567			"munderover",
3568			"mprescripts"
3569		]);
3570		mathMlDisallowed = freeze([
3571			"maction",
3572			"maligngroup",
3573			"malignmark",
3574			"mlongdiv",
3575			"mscarries",
3576			"mscarry",
3577			"msgroup",
3578			"mstack",
3579			"msline",
3580			"msrow",
3581			"semantics",
3582			"annotation",
3583			"annotation-xml",
3584			"mprescripts",
3585			"none"
3586		]);
3587		text = freeze(["#text"]);
3588		html = freeze([
3589			"accept",
3590			"action",
3591			"align",
3592			"alt",
3593			"autocapitalize",
3594			"autocomplete",
3595			"autopictureinpicture",
3596			"autoplay",
3597			"background",
3598			"bgcolor",
3599			"border",
3600			"capture",
3601			"cellpadding",
3602			"cellspacing",
3603			"checked",
3604			"cite",
3605			"class",
3606			"clear",
3607			"color",
3608			"cols",
3609			"colspan",
3610			"command",
3611			"commandfor",
3612			"controls",
3613			"controlslist",
3614			"coords",
3615			"crossorigin",
3616			"datetime",
3617			"decoding",
3618			"default",
3619			"dir",
3620			"disabled",
3621			"disablepictureinpicture",
3622			"disableremoteplayback",
3623			"download",
3624			"draggable",
3625			"enctype",
3626			"enterkeyhint",
3627			"exportparts",
3628			"face",
3629			"for",
3630			"headers",
3631			"height",
3632			"hidden",
3633			"high",
3634			"href",
3635			"hreflang",
3636			"id",
3637			"inert",
3638			"inputmode",
3639			"integrity",
3640			"ismap",
3641			"kind",
3642			"label",
3643			"lang",
3644			"list",
3645			"loading",
3646			"loop",
3647			"low",
3648			"max",
3649			"maxlength",
3650			"media",
3651			"method",
3652			"min",
3653			"minlength",
3654			"multiple",
3655			"muted",
3656			"name",
3657			"nonce",
3658			"noshade",
3659			"novalidate",
3660			"nowrap",
3661			"open",
3662			"optimum",
3663			"part",
3664			"pattern",
3665			"placeholder",
3666			"playsinline",
3667			"popover",
3668			"popovertarget",
3669			"popovertargetaction",
3670			"poster",
3671			"preload",
3672			"pubdate",
3673			"radiogroup",
3674			"readonly",
3675			"rel",
3676			"required",
3677			"rev",
3678			"reversed",
3679			"role",
3680			"rows",
3681			"rowspan",
3682			"spellcheck",
3683			"scope",
3684			"selected",
3685			"shape",
3686			"size",
3687			"sizes",
3688			"slot",
3689			"span",
3690			"srclang",
3691			"start",
3692			"src",
3693			"srcset",
3694			"step",
3695			"style",
3696			"summary",
3697			"tabindex",
3698			"title",
3699			"translate",
3700			"type",
3701			"usemap",
3702			"valign",
3703			"value",
3704			"width",
3705			"wrap",
3706			"xmlns"
3707		]);
3708		svg = freeze([
3709			"accent-height",
3710			"accumulate",
3711			"additive",
3712			"alignment-baseline",
3713			"amplitude",
3714			"ascent",
3715			"attributename",
3716			"attributetype",
3717			"azimuth",
3718			"basefrequency",
3719			"baseline-shift",
3720			"begin",
3721			"bias",
3722			"by",
3723			"class",
3724			"clip",
3725			"clippathunits",
3726			"clip-path",
3727			"clip-rule",
3728			"color",
3729			"color-interpolation",
3730			"color-interpolation-filters",
3731			"color-profile",
3732			"color-rendering",
3733			"cx",
3734			"cy",
3735			"d",
3736			"dx",
3737			"dy",
3738			"diffuseconstant",
3739			"direction",
3740			"display",
3741			"divisor",
3742			"dur",
3743			"edgemode",
3744			"elevation",
3745			"end",
3746			"exponent",
3747			"fill",
3748			"fill-opacity",
3749			"fill-rule",
3750			"filter",
3751			"filterunits",
3752			"flood-color",
3753			"flood-opacity",
3754			"font-family",
3755			"font-size",
3756			"font-size-adjust",
3757			"font-stretch",
3758			"font-style",
3759			"font-variant",
3760			"font-weight",
3761			"fx",
3762			"fy",
3763			"g1",
3764			"g2",
3765			"glyph-name",
3766			"glyphref",
3767			"gradientunits",
3768			"gradienttransform",
3769			"height",
3770			"href",
3771			"id",
3772			"image-rendering",
3773			"in",
3774			"in2",
3775			"intercept",
3776			"k",
3777			"k1",
3778			"k2",
3779			"k3",
3780			"k4",
3781			"kerning",
3782			"keypoints",
3783			"keysplines",
3784			"keytimes",
3785			"lang",
3786			"lengthadjust",
3787			"letter-spacing",
3788			"kernelmatrix",
3789			"kernelunitlength",
3790			"lighting-color",
3791			"local",
3792			"marker-end",
3793			"marker-mid",
3794			"marker-start",
3795			"markerheight",
3796			"markerunits",
3797			"markerwidth",
3798			"maskcontentunits",
3799			"maskunits",
3800			"max",
3801			"mask",
3802			"mask-type",
3803			"media",
3804			"method",
3805			"mode",
3806			"min",
3807			"name",
3808			"numoctaves",
3809			"offset",
3810			"operator",
3811			"opacity",
3812			"order",
3813			"orient",
3814			"orientation",
3815			"origin",
3816			"overflow",
3817			"paint-order",
3818			"path",
3819			"pathlength",
3820			"patterncontentunits",
3821			"patterntransform",
3822			"patternunits",
3823			"points",
3824			"preservealpha",
3825			"preserveaspectratio",
3826			"primitiveunits",
3827			"r",
3828			"rx",
3829			"ry",
3830			"radius",
3831			"refx",
3832			"refy",
3833			"repeatcount",
3834			"repeatdur",
3835			"restart",
3836			"result",
3837			"rotate",
3838			"scale",
3839			"seed",
3840			"shape-rendering",
3841			"slope",
3842			"specularconstant",
3843			"specularexponent",
3844			"spreadmethod",
3845			"startoffset",
3846			"stddeviation",
3847			"stitchtiles",
3848			"stop-color",
3849			"stop-opacity",
3850			"stroke-dasharray",
3851			"stroke-dashoffset",
3852			"stroke-linecap",
3853			"stroke-linejoin",
3854			"stroke-miterlimit",
3855			"stroke-opacity",
3856			"stroke",
3857			"stroke-width",
3858			"style",
3859			"surfacescale",
3860			"systemlanguage",
3861			"tabindex",
3862			"tablevalues",
3863			"targetx",
3864			"targety",
3865			"transform",
3866			"transform-origin",
3867			"text-anchor",
3868			"text-decoration",
3869			"text-rendering",
3870			"textlength",
3871			"type",
3872			"u1",
3873			"u2",
3874			"unicode",
3875			"values",
3876			"viewbox",
3877			"visibility",
3878			"version",
3879			"vert-adv-y",
3880			"vert-origin-x",
3881			"vert-origin-y",
3882			"width",
3883			"word-spacing",
3884			"wrap",
3885			"writing-mode",
3886			"xchannelselector",
3887			"ychannelselector",
3888			"x",
3889			"x1",
3890			"x2",
3891			"xmlns",
3892			"y",
3893			"y1",
3894			"y2",
3895			"z",
3896			"zoomandpan"
3897		]);
3898		mathMl = freeze([
3899			"accent",
3900			"accentunder",
3901			"align",
3902			"bevelled",
3903			"close",
3904			"columnalign",
3905			"columnlines",
3906			"columnspacing",
3907			"columnspan",
3908			"denomalign",
3909			"depth",
3910			"dir",
3911			"display",
3912			"displaystyle",
3913			"encoding",
3914			"fence",
3915			"frame",
3916			"height",
3917			"href",
3918			"id",
3919			"largeop",
3920			"length",
3921			"linethickness",
3922			"lquote",
3923			"lspace",
3924			"mathbackground",
3925			"mathcolor",
3926			"mathsize",
3927			"mathvariant",
3928			"maxsize",
3929			"minsize",
3930			"movablelimits",
3931			"notation",
3932			"numalign",
3933			"open",
3934			"rowalign",
3935			"rowlines",
3936			"rowspacing",
3937			"rowspan",
3938			"rspace",
3939			"rquote",
3940			"scriptlevel",
3941			"scriptminsize",
3942			"scriptsizemultiplier",
3943			"selection",
3944			"separator",
3945			"separators",
3946			"stretchy",
3947			"subscriptshift",
3948			"supscriptshift",
3949			"symmetric",
3950			"voffset",
3951			"width",
3952			"xmlns"
3953		]);
3954		xml = freeze([
3955			"xlink:href",
3956			"xml:id",
3957			"xlink:title",
3958			"xml:space",
3959			"xmlns:xlink"
3960		]);
3961		MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
3962		ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
3963		TMPLIT_EXPR = seal(/\${[\w\W]*/g);
3964		DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/);
3965		ARIA_ATTR = seal(/^aria-[\-\w]+$/);
3966		IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i);
3967		IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
3968		ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g);
3969		DOCTYPE_NAME = seal(/^html$/i);
3970		CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
3971		ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
3972		COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
3973		FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
3974		SELF_CLOSING_TAG = seal(/\/>/i);
3975		NODE_TYPE = {
3976			element: 1,
3977			attribute: 2,
3978			text: 3,
3979			cdataSection: 4,
3980			entityReference: 5,
3981			entityNode: 6,
3982			processingInstruction: 7,
3983			comment: 8,
3984			document: 9,
3985			documentType: 10,
3986			documentFragment: 11,
3987			notation: 12
3988		};
3989		getGlobal = function getGlobal() {
3990			return typeof window === "undefined" ? null : window;
3991		};
3992		_createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
3993			if (typeof trustedTypes !== "object" || typeof trustedTypes.createPolicy !== "function") return null;
3994			let suffix = null;
3995			const ATTR_NAME = "data-tt-policy-suffix";
3996			if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) suffix = purifyHostElement.getAttribute(ATTR_NAME);
3997			const policyName = "dompurify" + (suffix ? "#" + suffix : "");
3998			try {
3999				return trustedTypes.createPolicy(policyName, {
4000					createHTML(html) {
4001						return html;
4002					},
4003					createScriptURL(scriptUrl) {
4004						return scriptUrl;
4005					}
4006				});
4007			} catch (_) {
4008				console.warn("TrustedTypes policy " + policyName + " could not be created.");
4009				return null;
4010			}
4011		};
4012		_createHooksMap = function _createHooksMap() {
4013			return {
4014				afterSanitizeAttributes: [],
4015				afterSanitizeElements: [],
4016				afterSanitizeShadowDOM: [],
4017				beforeSanitizeAttributes: [],
4018				beforeSanitizeElements: [],
4019				beforeSanitizeShadowDOM: [],
4020				uponSanitizeAttribute: [],
4021				uponSanitizeElement: [],
4022				uponSanitizeShadowNode: []
4023			};
4024		};
4025		_resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
4026			return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
4027		};
4028		purify = createDOMPurify();
4029	}));
4030	//#endregion
4031	//#region modules/payments/assets/js/frontend/handlers/stripe-button.js
4032	var stripe_button_exports = /* @__PURE__ */ __exportAll({ default: () => StripeHandler });
4033	var StripeHandler;
4034	var init_stripe_button = __esmMin((() => {
4035		init_purify_es();
4036		StripeHandler = class extends elementorModules.frontend.handlers.Base {
4037			getDefaultSettings() {
4038				return { selectors: {
4039					form: ".elementor-stripe-form",
4040					errors: ".elementor-message-danger"
4041				} };
4042			}
4043			getDefaultElements() {
4044				const settings = this.getSettings();
4045				return {
4046					form: this.$element[0].querySelector(settings.selectors.form),
4047					errors: this.$element[0].querySelectorAll(settings.selectors.errors),
4048					post_id: this.$element.closest("[data-elementor-id]").attr("data-elementor-id")
4049				};
4050			}
4051			handleSubmit(event) {
4052				event.preventDefault();
4053				if (elementorFrontend.isEditMode()) return;
4054				if (this.elements.errors.innerHTML !== "") document.querySelectorAll(".elementor-stripe-error-message").forEach((e) => e.remove());
4055				const stripeForm = this.elements.form;
4056				const formData = new FormData(stripeForm);
4057				const ajaxurl = formData.get("url");
4058				const action = formData.get("action");
4059				const postId = parseInt(this.elements.post_id);
4060				const widgetId = formData.get("widget_id");
4061				const customErrorMsg = formData.get("custom_error_msg");
4062				const customErrorMsgGlobal = formData.get("custom_error_msg_global");
4063				const customErrorMsgPayment = formData.get("custom_error_msg_payment");
4064				const nonce = formData.get("stripe_form_submit_nonce");
4065				const pageUrl = document.URL;
4066				const target = "yes" === formData.get("open_in_new_window") ? "_blank" : "_self";
4067				const createErrorContainer = (errorMsg) => {
4068					const errorDiv = document.createElement("div");
4069					const errorCont = stripeForm.appendChild(errorDiv);
4070					errorCont.className = "elementor-message elementor-stripe-error-message elementor-message-danger";
4071					errorCont.innerHTML = `${purify.sanitize(errorMsg)}`;
4072				};
4073				const data = {
4074					action,
4075					postId,
4076					widgetId,
4077					pageUrl,
4078					nonce
4079				};
4080				if (0 < this.elements.errors.length) this.elements.errors.forEach((error) => {
4081					error.classList.remove("elementor-hidden");
4082				});
4083				else jQuery.post(ajaxurl, {
4084					action,
4085					data
4086				}).done((response) => {
4087					const code = response.response.code;
4088					const result2 = response.body && JSON.parse(response.body);
4089					switch (code) {
4090						case 200:
4091							window.open(result2.url, target);
4092							break;
4093						case 401:
4094						case 403:
4095							if (customErrorMsg) createErrorContainer(customErrorMsgPayment);
4096							else createErrorContainer(result2.error.message);
4097							break;
4098						default: if (customErrorMsg) createErrorContainer(customErrorMsgGlobal);
4099						else createErrorContainer(result2.error.message);
4100					}
4101				}).fail(() => {
4102					if (customErrorMsg) createErrorContainer(customErrorMsgGlobal);
4103					else createErrorContainer(result.error.message);
4104				});
4105			}
4106			bindEvents() {
4107				this.elements.form.addEventListener("submit", (e) => this.handleSubmit(e));
4108			}
4109		};
4110	}));
4111	//#endregion
4112	//#region modules/payments/assets/js/frontend/frontend.js
4113	var frontend_default$1 = class extends elementorModules.Module {
4114		static {
4115			__name(this, "default");
4116		}
4117		constructor() {
4118			super();
4119			elementorFrontend.elementsHandler.attachHandler("paypal-button", () => __vitePreload(() => Promise.resolve().then(() => (init_paypal_button(), paypal_button_exports)), void 0));
4120			elementorFrontend.elementsHandler.attachHandler("stripe-button", () => __vitePreload(() => Promise.resolve().then(() => (init_stripe_button(), stripe_button_exports)), void 0));
4121		}
4122	};
4123	//#endregion
4124	//#region modules/progress-tracker/assets/js/frontend/handlers/circular-progress.js
4125	var CircularProgress;
4126	var init_circular_progress = __esmMin((() => {
4127		CircularProgress = class {
4128			constructor(element, settings) {
4129				this.settings = settings;
4130				this.lastKnownProgress = null;
4131				this.circularProgressTracker = element.find(".elementor-scrolling-tracker-circular")[0];
4132				this.circularCurrentProgress = this.circularProgressTracker.getElementsByClassName("current-progress")[0];
4133				this.circularCurrentProgressPercentage = this.circularProgressTracker.getElementsByClassName("current-progress-percentage")[0];
4134				const circumference = this.circularCurrentProgress.r.baseVal.value * 2 * Math.PI;
4135				this.circularCurrentProgress.style.strokeDasharray = `${circumference} ${circumference}`;
4136				this.circularCurrentProgress.style.strokeDashoffset = circumference;
4137				this.elements = this.cacheElements();
4138				this.resizeObserver = new ResizeObserver(() => {
4139					if (this.lastKnownProgress) this.updateProgress(this.lastKnownProgress);
4140				});
4141				this.resizeObserver.observe(this.circularProgressTracker);
4142			}
4143			cacheElements() {
4144				return {
4145					circularProgressTracker: this.circularProgressTracker,
4146					circularCurrentProgress: this.circularCurrentProgress,
4147					circularCurrentProgressPercentage: this.circularCurrentProgressPercentage
4148				};
4149			}
4150			updateProgress(progress) {
4151				if (progress <= 0) {
4152					this.elements.circularCurrentProgress.style.display = "none";
4153					this.elements.circularCurrentProgressPercentage.style.display = "none";
4154					return;
4155				}
4156				this.elements.circularCurrentProgress.style.display = "block";
4157				this.elements.circularCurrentProgressPercentage.style.display = "block";
4158				const circumference = this.elements.circularCurrentProgress.r.baseVal.value * 2 * Math.PI;
4159				const offset = circumference - progress / 100 * circumference;
4160				this.lastKnownProgress = progress;
4161				this.elements.circularCurrentProgress.style.strokeDasharray = `${circumference} ${circumference}`;
4162				this.elements.circularCurrentProgress.style.strokeDashoffset = "ltr" === this.settings.direction ? -offset : offset;
4163				if ("yes" === this.settings.percentage) this.elements.circularCurrentProgressPercentage.innerHTML = Math.round(progress) + "%";
4164			}
4165			onDestroy() {
4166				this.resizeObserver.unobserve(this.circularProgressTracker);
4167			}
4168		};
4169	}));
4170	//#endregion
4171	//#region modules/progress-tracker/assets/js/frontend/handlers/linear-progress.js
4172	var LinearProgress;
4173	var init_linear_progress = __esmMin((() => {
4174		LinearProgress = class {
4175			constructor(element, settings) {
4176				this.settings = settings;
4177				this.linearProgressTracker = element.find(".elementor-scrolling-tracker-horizontal")[0];
4178				this.linearCurrentProgress = this.linearProgressTracker.getElementsByClassName("current-progress")[0];
4179				this.linearCurrentProgressPercentage = this.linearProgressTracker.getElementsByClassName("current-progress-percentage")[0];
4180				this.elements = this.cacheElements();
4181			}
4182			cacheElements() {
4183				return {
4184					linearProgressTracker: this.linearProgressTracker,
4185					linearCurrentProgress: this.linearCurrentProgress,
4186					linearCurrentProgressPercentage: this.linearCurrentProgressPercentage
4187				};
4188			}
4189			updateProgress(progress) {
4190				if (progress < 1) {
4191					this.elements.linearCurrentProgress.style.display = "none";
4192					return;
4193				}
4194				this.elements.linearCurrentProgress.style.display = "flex";
4195				this.elements.linearCurrentProgress.style.width = progress + "%";
4196				if ("yes" === this.settings.percentage && this.elements.linearCurrentProgress.getBoundingClientRect().width > this.elements.linearCurrentProgressPercentage.getBoundingClientRect().width * 1.5) {
4197					this.elements.linearCurrentProgressPercentage.innerHTML = Math.round(progress) + "%";
4198					this.elements.linearCurrentProgressPercentage.style.color = getComputedStyle(this.linearCurrentProgress).getPropertyValue("--percentage-color");
4199				} else this.elements.linearCurrentProgressPercentage.style.color = "transparent";
4200			}
4201		};
4202	}));
4203	//#endregion
4204	//#region modules/progress-tracker/assets/js/frontend/handlers/progress-tracker.js
4205	var progress_tracker_exports = /* @__PURE__ */ __exportAll({ default: () => ProgressTracker });
4206	var ProgressTracker;
4207	var init_progress_tracker = __esmMin((() => {
4208		init_circular_progress();
4209		init_linear_progress();
4210		ProgressTracker = class extends elementorModules.frontend.handlers.Base {
4211			onInit() {
4212				elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments);
4213				this.circular = "circular" === this.getElementSettings().type;
4214				const Handler = this.circular ? CircularProgress : LinearProgress;
4215				this.progressBar = new Handler(this.$element, this.getElementSettings());
4216				this.progressPercentage = 0;
4217				this.scrollHandler();
4218				this.handler = this.scrollHandler.bind(this);
4219				this.initListeners();
4220			}
4221			getTrackingElementSelector() {
4222				const trackingElementSetting = this.getElementSettings().relative_to;
4223				let selector;
4224				switch (trackingElementSetting) {
4225					case "selector":
4226						selector = jQuery(this.getElementSettings().selector);
4227						break;
4228					case "post_content":
4229						selector = jQuery(".elementor-widget-theme-post-content");
4230						break;
4231					default:
4232						selector = this.isScrollSnap() ? jQuery("#e-scroll-snap-container") : elementorFrontend.elements.$body;
4233						break;
4234				}
4235				return selector;
4236			}
4237			isScrollSnap() {
4238				return "yes" === (this.isEdit ? elementor.settings.page.model.attributes.scroll_snap : elementorFrontend.config.settings.page.scroll_snap) ? true : false;
4239			}
4240			addScrollSnapContainer() {
4241				if (this.isScrollSnap() && !jQuery("#e-scroll-snap-container").length) jQuery("body").wrapInner("<div id=\"e-scroll-snap-container\" />");
4242			}
4243			scrollHandler() {
4244				this.addScrollSnapContainer();
4245				const $trackingElementSelector = this.getTrackingElementSelector();
4246				const scrollStartPercentage = $trackingElementSelector.is(elementorFrontend.elements.$body) || $trackingElementSelector.is(jQuery("#e-scroll-snap-container")) ? -100 : 0;
4247				this.progressPercentage = elementorModules.utils.Scroll.getElementViewportPercentage(this.getTrackingElementSelector(), {
4248					start: scrollStartPercentage,
4249					end: -100
4250				});
4251				this.progressBar.updateProgress(this.progressPercentage);
4252			}
4253			initListeners() {
4254				window.addEventListener("scroll", this.handler);
4255				elementorFrontend.elements.$body[0].addEventListener("scroll", this.handler);
4256			}
4257			onDestroy() {
4258				if (this.progressBar.onDestroy) this.progressBar.onDestroy();
4259				window.removeEventListener("scroll", this.handler);
4260				elementorFrontend.elements.$body[0].removeEventListener("scroll", this.handler);
4261			}
4262		};
4263	}));
4264	//#endregion
4265	//#region modules/progress-tracker/assets/js/frontend/frontend.js
4266	var frontend_default = class extends elementorModules.Module {
4267		static {
4268			__name(this, "default");
4269		}
4270		constructor() {
4271			super();
4272			elementorFrontend.elementsHandler.attachHandler("progress-tracker", () => __vitePreload(() => Promise.resolve().then(() => (init_progress_tracker(), progress_tracker_exports)), void 0));
4273		}
4274	};
4275	//#endregion
4276	//#region assets/dev/js/frontend/utils/controls.js
4277	var Controls = class {
4278		/**
4279		* Get Control Value
4280		*
4281		* Retrieves a control value.
4282		* This function has been copied from `elementor/assets/dev/js/editor/utils/conditions.js`.
4283		*
4284		* @since 3.11.0
4285		*
4286		* @param {{}}     controlSettings A settings object (e.g. element settings - keys and values)
4287		* @param {string} controlKey      The control key name
4288		* @param {string} controlSubKey   A specific property of the control object.
4289		* @return {*} Control Value
4290		*/
4291		getControlValue(controlSettings, controlKey, controlSubKey) {
4292			let value;
4293			if ("object" === typeof controlSettings[controlKey] && controlSubKey) value = controlSettings[controlKey][controlSubKey];
4294			else value = controlSettings[controlKey];
4295			return value;
4296		}
4297		/**
4298		* Get the value of a responsive control.
4299		*
4300		* Retrieves the value of a responsive control for the current device or for this first parent device which has a control value.
4301		*
4302		* @since 3.11.0
4303		*
4304		* @param {{}}     controlSettings A settings object (e.g. element settings - keys and values)
4305		* @param {string} controlKey      The control key name
4306		* @param {string} controlSubKey   A specific property of the control object.
4307		* @return {*} Control Value
4308		*/
4309		getResponsiveControlValue(controlSettings, controlKey, controlSubKey = "") {
4310			const currentDeviceMode = elementorFrontend.getCurrentDeviceMode();
4311			const controlValueDesktop = this.getControlValue(controlSettings, controlKey, controlSubKey);
4312			if ("widescreen" === currentDeviceMode) {
4313				const controlValueWidescreen = this.getControlValue(controlSettings, `${controlKey}_widescreen`, controlSubKey);
4314				return !!controlValueWidescreen || 0 === controlValueWidescreen ? controlValueWidescreen : controlValueDesktop;
4315			}
4316			const activeBreakpoints = elementorFrontend.breakpoints.getActiveBreakpointsList({ withDesktop: true });
4317			let parentDeviceMode = currentDeviceMode;
4318			let deviceIndex = activeBreakpoints.indexOf(currentDeviceMode);
4319			let controlValue = "";
4320			while (deviceIndex <= activeBreakpoints.length) {
4321				if ("desktop" === parentDeviceMode) {
4322					controlValue = controlValueDesktop;
4323					break;
4324				}
4325				const responsiveControlKey = `${controlKey}_${parentDeviceMode}`;
4326				const responsiveControlValue = this.getControlValue(controlSettings, responsiveControlKey, controlSubKey);
4327				if (!!responsiveControlValue || 0 === responsiveControlValue) {
4328					controlValue = responsiveControlValue;
4329					break;
4330				}
4331				deviceIndex++;
4332				parentDeviceMode = activeBreakpoints[deviceIndex];
4333			}
4334			return controlValue;
4335		}
4336	};
4337	//#endregion
4338	//#region assets/dev/js/frontend/utils/dropdown-menu-height-controller.js
4339	var DropdownMenuHeightController = class {
4340		constructor(widgetConfig) {
4341			this.widgetConfig = widgetConfig;
4342		}
4343		calculateStickyMenuNavHeight() {
4344			this.widgetConfig.elements.$dropdownMenuContainer.css(this.widgetConfig.settings.menuHeightCssVarName, "");
4345			const menuToggleHeight = this.widgetConfig.elements.$dropdownMenuContainer.offset().top - jQuery(window).scrollTop();
4346			return elementorFrontend.elements.$window.height() - menuToggleHeight;
4347		}
4348		calculateMenuTabContentHeight($tab) {
4349			return elementorFrontend.elements.$window.height() - $tab[0].getBoundingClientRect().top;
4350		}
4351		isElementSticky() {
4352			return this.widgetConfig.elements.$element.hasClass("elementor-sticky") || this.widgetConfig.elements.$element.parents(".elementor-sticky").length;
4353		}
4354		getMenuHeight() {
4355			return this.isElementSticky() ? this.calculateStickyMenuNavHeight() + "px" : this.widgetConfig.settings.dropdownMenuContainerMaxHeight;
4356		}
4357		setMenuHeight(menuHeight) {
4358			this.widgetConfig.elements.$dropdownMenuContainer.css(this.widgetConfig.settings.menuHeightCssVarName, menuHeight);
4359		}
4360		reassignMobileMenuHeight() {
4361			const menuHeight = this.isToggleActive() ? this.getMenuHeight() : 0;
4362			return this.setMenuHeight(menuHeight);
4363		}
4364		reassignMenuHeight($activeTabContent) {
4365			if (!this.isElementSticky() || 0 === $activeTabContent.length) return;
4366			const offsetBottom = elementorFrontend.elements.$window.height() - $activeTabContent[0].getBoundingClientRect().top;
4367			if (!($activeTabContent.height() > offsetBottom)) return;
4368			$activeTabContent.css("height", this.calculateMenuTabContentHeight($activeTabContent) + "px");
4369			$activeTabContent.css("overflow-y", "scroll");
4370		}
4371		resetMenuHeight($activeTabContent) {
4372			if (!this.isElementSticky()) return;
4373			$activeTabContent.css("height", "initial");
4374			$activeTabContent.css("overflow-y", "visible");
4375		}
4376		isToggleActive() {
4377			var _this$widgetConfig$at;
4378			const $menuToggle = this.widgetConfig.elements.$menuToggle;
4379			if (!!((_this$widgetConfig$at = this.widgetConfig.attributes) === null || _this$widgetConfig$at === void 0 ? void 0 : _this$widgetConfig$at.menuToggleState)) return "true" === $menuToggle.attr(this.widgetConfig.attributes.menuToggleState);
4380			return $menuToggle.hasClass(this.widgetConfig.classes.menuToggleActiveClass);
4381		}
4382	};
4383	//#endregion
4384	//#region assets/dev/js/frontend/frontend.js
4385	var ElementorProFrontend = class extends elementorModules.ViewModule {
4386		onInit() {
4387			super.onInit();
4388			this.config = ElementorProFrontendConfig;
4389			this.modules = {};
4390			this.initOnReadyComponents();
4391		}
4392		bindEvents() {
4393			jQuery(window).on("elementor/frontend/init", this.onElementorFrontendInit.bind(this));
4394		}
4395		initModules() {
4396			let handlers = {
4397				motionFX: frontend_default$5,
4398				sticky: frontend_default$4,
4399				codeHighlight: frontend_default$3,
4400				videoPlaylist: frontend_default$2,
4401				payments: frontend_default$1,
4402				progressTracker: frontend_default
4403			};
4404			elementorProFrontend.trigger("elementor-pro/modules/init/before");
4405			handlers = elementorFrontend.hooks.applyFilters("elementor-pro/frontend/handlers", handlers);
4406			jQuery.each(handlers, (moduleName, ModuleClass) => {
4407				this.modules[moduleName] = new ModuleClass();
4408			});
4409			this.modules.linkActions = { addAction: (...args) => {
4410				elementorFrontend.utils.urlActions.addAction(...args);
4411			} };
4412		}
4413		onElementorFrontendInit() {
4414			this.initModules();
4415		}
4416		initOnReadyComponents() {
4417			this.utils = {
4418				controls: new Controls(),
4419				DropdownMenuHeightController
4420			};
4421		}
4422	};
4423	window.elementorProFrontend = new ElementorProFrontend();
4424	//#endregion
4425})();
4426
4427//# sourceMappingURL=frontend.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.