@aarsteinmedia/dotlottie-player 6.0.3 → 6.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/svg.js ADDED
@@ -0,0 +1,1502 @@
1
+ import { isServer, PlayMode, PreserveAspectRatio, namespaceSVG, RendererType, createElementID, PlayerEvents, download, getFilename } from '@aarsteinmedia/lottie-web/utils';
2
+ export { PlayMode, PlayerEvents } from '@aarsteinmedia/lottie-web/utils';
3
+ import Lottie from '@aarsteinmedia/lottie-web/svg';
4
+ import { convert, getAnimationData } from '@aarsteinmedia/lottie-web/dotlottie';
5
+
6
+ /**
7
+ * Credit to: Leonardo Favre https://github.com/leofavre/observed-properties.
8
+ */ const updateOnConnected = Symbol('UPDATE_ON_CONNECTED');
9
+ if (isServer) {
10
+ // Mock HTMLElement for server-side rendering
11
+ global.HTMLElement = // eslint-disable-next-line @typescript-eslint/no-extraneous-class
12
+ class EmptyHTMLElement {
13
+ };
14
+ }
15
+ /**
16
+ * HTMLElement enhanced to track property changes.
17
+ */ class PropertyCallbackElement extends HTMLElement {
18
+ constructor(){
19
+ super();
20
+ if (updateOnConnected in this) {
21
+ this[updateOnConnected] = [];
22
+ }
23
+ const { observedProperties = [] } = this.constructor;
24
+ const { length } = observedProperties;
25
+ for(let i = 0; i < length; i++){
26
+ const initialValue = this[observedProperties[i]], cachedValue = Symbol(observedProperties[i]);
27
+ this[cachedValue] = initialValue;
28
+ Object.defineProperty(this, observedProperties[i] ?? '', {
29
+ get () {
30
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
31
+ return this[cachedValue];
32
+ },
33
+ set (value) {
34
+ const oldValue = this[cachedValue];
35
+ this[cachedValue] = value;
36
+ this.propertyChangedCallback(observedProperties[i], oldValue, value);
37
+ }
38
+ });
39
+ if (typeof initialValue !== 'undefined' && updateOnConnected in this && Array.isArray(this[updateOnConnected])) {
40
+ this[updateOnConnected].push(observedProperties[i]);
41
+ }
42
+ }
43
+ }
44
+ connectedCallback() {
45
+ let arr = [];
46
+ if (updateOnConnected in this && Array.isArray(this[updateOnConnected])) {
47
+ arr = this[updateOnConnected];
48
+ }
49
+ const { length } = arr;
50
+ for(let i = 0; i < length; i++){
51
+ if (!('propertyChangedCallback' in this) || typeof this.propertyChangedCallback !== 'function') {
52
+ continue;
53
+ }
54
+ if (arr[i] ?? '' in this) {
55
+ this.propertyChangedCallback(arr[i] ?? '', undefined, this[arr[i]]);
56
+ }
57
+ }
58
+ }
59
+ propertyChangedCallback(_name, _oldValue, _value) {
60
+ throw new Error(`${this.constructor.name}: Method propertyChangedCallback is not implemented`);
61
+ }
62
+ }
63
+
64
+ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-toolbar-height: 35px;\n --lottie-player-toolbar-background-color: #fff;\n --lottie-player-toolbar-icon-color: #000;\n --lottie-player-toolbar-icon-hover-color: #000;\n --lottie-player-toolbar-icon-active-color: #4285f4;\n --lottie-player-seeker-track-color: rgb(0 0 0 / 20%);\n --lottie-player-seeker-thumb-color: #4285f4;\n --lottie-player-seeker-display: block;\n\n width: 100%;\n height: 100%;\n\n &:not([hidden]) {\n display: block;\n }\n\n .main {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n margin: 0;\n padding: 0;\n }\n\n .animation {\n width: 100%;\n height: 100%;\n display: flex;\n margin: 0;\n padding: 0;\n }\n\n [data-controls='true'] .animation {\n height: calc(100% - 35px);\n }\n\n .animation-container {\n position: relative;\n }\n\n .popover {\n position: absolute;\n right: 5px;\n bottom: 40px;\n background-color: var(--lottie-player-toolbar-background-color);\n border-radius: 5px;\n padding: 10px 15px;\n border: solid 2px var(--lottie-player-toolbar-icon-color);\n animation: fade-in 0.2s ease-in-out;\n\n &::before {\n content: '';\n right: 10px;\n border: 7px solid transparent;\n margin-right: -7px;\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n top: 100%;\n border-top-color: var(--lottie-player-toolbar-icon-color);\n }\n }\n\n .error {\n display: flex;\n margin: auto;\n justify-content: center;\n height: 100%;\n align-items: center;\n\n & svg {\n width: 100%;\n height: auto;\n }\n }\n\n .toolbar {\n display: flex;\n place-items: center center;\n background: var(--lottie-player-toolbar-background-color);\n margin: 0;\n height: 35px;\n padding: 5px;\n border-radius: 5px;\n gap: 5px;\n\n &.has-error {\n pointer-events: none;\n opacity: 0.5;\n }\n\n & button {\n cursor: pointer;\n fill: var(--lottie-player-toolbar-icon-color);\n color: var(--lottie-player-toolbar-icon-color);\n background: none;\n border: 0;\n padding: 0;\n outline: 0;\n height: 100%;\n margin: 0;\n align-items: center;\n gap: 5px;\n opacity: 0.9;\n\n &:not([hidden]) {\n display: flex;\n }\n\n &:hover {\n opacity: 1;\n }\n\n &[data-active='true'] {\n opacity: 1;\n fill: var(--lottie-player-toolbar-icon-active-color);\n }\n\n &:disabled {\n opacity: 0.5;\n }\n\n &:focus {\n outline: 0;\n }\n\n & svg {\n pointer-events: none;\n\n & > * {\n fill: inherit;\n }\n }\n\n &.disabled svg {\n display: none;\n }\n }\n }\n\n .progress-container {\n position: relative;\n width: 100%;\n\n &.simple {\n margin-right: 12px;\n }\n }\n\n .seeker {\n appearance: none;\n outline: none;\n width: 100%;\n height: 20px;\n border-radius: 3px;\n border: 0;\n cursor: pointer;\n background-color: transparent;\n\n display: var(--lottie-player-seeker-display);\n color: var(--lottie-player-seeker-thumb-color);\n margin: 0;\n padding: 7.5px 0;\n position: relative;\n z-index: 1;\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n appearance: none;\n outline: none;\n }\n\n &::-webkit-slider-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n border: 0;\n background-color: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -webkit-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-webkit-slider-thumb,\n &:focus::-webkit-slider-thumb {\n transform: scale(1);\n }\n\n &::-moz-range-progress {\n background-color: var(--lottie-player-seeker-thumb-color);\n height: 5px;\n border-radius: 3px;\n }\n\n &::-moz-range-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background-color: var(--lottie-player-seeker-thumb-color);\n border: 0;\n cursor: pointer;\n -moz-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-moz-range-thumb,\n &:focus::-moz-range-thumb {\n transform: scale(1);\n }\n\n &::-ms-track {\n width: 100%;\n height: 5px;\n cursor: pointer;\n background: transparent;\n border-color: transparent;\n color: transparent;\n }\n\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n border-radius: 3px;\n }\n\n &::-ms-fill-lower {\n background-color: var(--lottie-player-seeker-thumb-color);\n border-radius: 3px;\n }\n\n &::-ms-thumb {\n border: 0;\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -ms-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-ms-thumb {\n transform: scale(1);\n }\n\n &:focus {\n &::-ms-thumb {\n transform: scale(1);\n }\n\n &::-ms-fill-lower,\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n }\n }\n }\n\n & progress {\n appearance: none;\n outline: none;\n position: absolute;\n width: 100%;\n height: 5px;\n border-radius: 3px;\n border: 0;\n top: 0;\n left: 0;\n margin: 7.5px 0;\n background-color: var(--lottie-player-seeker-track-color);\n pointer-events: none;\n\n &::-webkit-progress-inner-element {\n border-radius: 3px;\n overflow: hidden;\n }\n\n &::-webkit-slider-runnable-track {\n background-color: transparent;\n }\n\n &::-webkit-progress-value {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n }\n\n & *::-moz-progress-bar {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n}\n\n@keyframes fade-in {\n 0% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n :host {\n --lottie-player-toolbar-background-color: #000;\n --lottie-player-toolbar-icon-color: #fff;\n --lottie-player-toolbar-icon-hover-color: #fff;\n --lottie-player-seeker-track-color: rgb(255 255 255 / 60%);\n }\n}\n";
65
+
66
+ const boomerangIcon = /* HTML */ `
67
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
68
+ <path
69
+ d="m11.8 13.2-.3.3c-.5.5-1.1 1.1-1.7 1.5-.5.4-1 .6-1.5.8-.5.2-1.1.3-1.6.3s-1-.1-1.5-.3c-.6-.2-1-.5-1.4-1-.5-.6-.8-1.2-.9-1.9-.2-.9-.1-1.8.3-2.6.3-.7.8-1.2 1.3-1.6.3-.2.6-.4 1-.5.2-.2.5-.2.8-.3.3 0 .7-.1 1 0 .3 0 .6.1.9.2.9.3 1.7.9 2.4 1.5.4.4.8.7 1.1 1.1l.1.1.4-.4c.6-.6 1.2-1.2 1.9-1.6.5-.3 1-.6 1.5-.7.4-.1.7-.2 1-.2h.9c1 .1 1.9.5 2.6 1.4.4.5.7 1.1.8 1.8.2.9.1 1.7-.2 2.5-.4.9-1 1.5-1.8 2-.4.2-.7.4-1.1.4-.4.1-.8.1-1.2.1-.5 0-.9-.1-1.3-.3-.8-.3-1.5-.9-2.1-1.5-.4-.4-.8-.7-1.1-1.1h-.3zm-1.1-1.1c-.1-.1-.1-.1 0 0-.3-.3-.6-.6-.8-.9-.5-.5-1-.9-1.6-1.2-.4-.3-.8-.4-1.3-.4-.4 0-.8 0-1.1.2-.5.2-.9.6-1.1 1-.2.3-.3.7-.3 1.1 0 .3 0 .6.1.9.1.5.4.9.8 1.2.5.4 1.1.5 1.7.5.5 0 1-.2 1.5-.5.6-.4 1.1-.8 1.6-1.3.1-.3.3-.5.5-.6zM13 12c.5.5 1 1 1.5 1.4.5.5 1.1.9 1.9 1 .4.1.8 0 1.2-.1.3-.1.6-.3.9-.5.4-.4.7-.9.8-1.4.1-.5 0-.9-.1-1.4-.3-.8-.8-1.2-1.7-1.4-.4-.1-.8-.1-1.2 0-.5.1-1 .4-1.4.7-.5.4-1 .8-1.4 1.2-.2.2-.4.3-.5.5z"
70
+ />
71
+ </svg>
72
+ `;
73
+
74
+ const convertIcon = /* HTML */ `
75
+ <svg
76
+ width="24"
77
+ height="24"
78
+ aria-hidden="true"
79
+ focusable="false"
80
+ >
81
+ <path
82
+ d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"
83
+ />
84
+ </svg>
85
+ `;
86
+
87
+ const downloadIcon = /* HTML */ `
88
+ <svg
89
+ width="24"
90
+ height="24"
91
+ aria-hidden="true"
92
+ focusable="false"
93
+ >
94
+ <path
95
+ d="M16.8 10.8 12 15.6l-4.8-4.8h3V3.6h3.6v7.2h3zM12 15.6H3v4.8h18v-4.8h-9zm7.8 2.4h-2.4v-1.2h2.4V18z"
96
+ />
97
+ </svg>
98
+ `;
99
+
100
+ const loopIcon = /* HTML */ `
101
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
102
+ <path
103
+ d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"
104
+ />
105
+ </svg>
106
+ `;
107
+
108
+ const nextIcon = /* HTML */ `
109
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
110
+ <path d="m6.1 5.8 9.8 6.2-9.8 6.2V5.8zM16.4 5.8h1.5v12.4h-1.5z" />
111
+ </svg>
112
+ `;
113
+
114
+ const playIcon = /* HTML */ `
115
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
116
+ <path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z" />
117
+ </svg>
118
+ `;
119
+
120
+ const prevIcon = /* HTML */ `
121
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
122
+ <path d="M17.9 18.2 8.1 12l9.8-6.2v12.4zm-10.3 0H6.1V5.8h1.5v12.4z" />
123
+ </svg>
124
+ `;
125
+
126
+ const settingsIcon = /* HTML */ `
127
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
128
+ <circle cx="12" cy="5.4" r="2.5" />
129
+ <circle cx="12" cy="12" r="2.5" />
130
+ <circle cx="12" cy="18.6" r="2.5" />
131
+ </svg>
132
+ `;
133
+
134
+ const stopIcon = /* HTML */ `
135
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
136
+ <path d="M6 6h12v12H6V6z" />
137
+ </svg>
138
+ `;
139
+
140
+ var ObjectFit = /*#__PURE__*/ function(ObjectFit) {
141
+ ObjectFit["Contain"] = "contain";
142
+ ObjectFit["Cover"] = "cover";
143
+ ObjectFit["Fill"] = "fill";
144
+ ObjectFit["None"] = "none";
145
+ ObjectFit["ScaleDown"] = "scale-down";
146
+ return ObjectFit;
147
+ }({});
148
+ var PlayerState = /*#__PURE__*/ function(PlayerState) {
149
+ PlayerState["Completed"] = "completed";
150
+ PlayerState["Destroyed"] = "destroyed";
151
+ PlayerState["Error"] = "error";
152
+ PlayerState["Frozen"] = "frozen";
153
+ PlayerState["Loading"] = "loading";
154
+ PlayerState["Paused"] = "paused";
155
+ PlayerState["Playing"] = "playing";
156
+ PlayerState["Stopped"] = "stopped";
157
+ return PlayerState;
158
+ }({});
159
+ const tagName = 'dotlottie-player';
160
+
161
+ /**
162
+ * Render Controls.
163
+ */ function renderControls() {
164
+ if (!this.shadow) {
165
+ throw new Error('No Shadow Element');
166
+ }
167
+ const slot = this.shadow.querySelector('slot[name=controls]');
168
+ if (!slot) {
169
+ return;
170
+ }
171
+ if (!this.controls) {
172
+ slot.innerHTML = '';
173
+ return;
174
+ }
175
+ slot.innerHTML = /* HTML */ `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="${this.autoplay}" aria-label="Toggle Play/Pause">${playIcon}</button> <button class="stop" data-active="${!this.autoplay}" aria-label="Stop">${stopIcon}</button> <button class="prev" aria-label="Previous animation" hidden="false">${prevIcon}</button> <button class="next" aria-label="Next animation" hidden>${nextIcon}</button><form class="progress-container${this.simple ? ' simple' : ''}"><input type="range" class="seeker" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" aria-valuenow="${this._seeker.toString()}" tabindex="0" aria-label="Slider for search"><progress max="100" value="${this._seeker}"></progress></form>${this.simple ? '' : /* HTML */ `<button class="toggleLoop" data-active="${this.loop}" tabindex="0" aria-label="Toggle loop">${loopIcon}</button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0">${boomerangIcon}</button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${this._isSettingsOpen}" aria-controls="${this._identifier}-settings">${settingsIcon}</button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert JSON animation to dotLottie format" aria-label="Convert ${this.isDotLottie ? 'dotLottie animation to JSON format' : 'JSON animation to dotLottie format'}" hidden>${convertIcon} ${this.isDotLottie ? 'Convert to JSON' : 'Convert to dotLottie'}</button> <button class="snapshot" aria-label="Download still image">${downloadIcon} Download still image</button></div>`}</div>`;
176
+ const togglePlay = this.shadow.querySelector('.togglePlay');
177
+ if (togglePlay instanceof HTMLButtonElement) {
178
+ togglePlay.onclick = this.togglePlay;
179
+ }
180
+ const stopButton = this.shadow.querySelector('.stop');
181
+ if (stopButton instanceof HTMLButtonElement) {
182
+ stopButton.onclick = this.stop;
183
+ }
184
+ const prevButton = this.shadow.querySelector('.prev');
185
+ if (prevButton instanceof HTMLButtonElement) {
186
+ if (this.animations.length > 0 && this.currentAnimation) {
187
+ prevButton.hidden = false;
188
+ }
189
+ prevButton.onclick = this.prev;
190
+ }
191
+ const nextButton = this.shadow.querySelector('.next');
192
+ if (nextButton instanceof HTMLButtonElement) {
193
+ if (this.animations.length > 0 && this.currentAnimation < this.animations.length - 1) {
194
+ nextButton.hidden = false;
195
+ }
196
+ nextButton.onclick = this.next;
197
+ }
198
+ const seeker = this.shadow.querySelector('.seeker');
199
+ if (seeker instanceof HTMLInputElement) {
200
+ seeker.onchange = this._handleSeekChange;
201
+ seeker.onmousedown = this._freeze;
202
+ }
203
+ if (!this.simple) {
204
+ const toggleLoop = this.shadow.querySelector('.toggleLoop');
205
+ if (toggleLoop instanceof HTMLButtonElement) {
206
+ toggleLoop.onclick = this.toggleLoop;
207
+ }
208
+ const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
209
+ if (toggleBoomerang instanceof HTMLButtonElement) {
210
+ toggleBoomerang.onclick = this.toggleBoomerang;
211
+ }
212
+ const convertButton = this.shadow.querySelector('.convert');
213
+ if (convertButton instanceof HTMLButtonElement) {
214
+ convertButton.onclick = ()=>{
215
+ void convert({
216
+ isDotLottie: this.isDotLottie,
217
+ manifest: this.getManifest(),
218
+ src: this.src || this.source
219
+ });
220
+ };
221
+ }
222
+ const snapshot = this.shadow.querySelector('.snapshot');
223
+ if (snapshot instanceof HTMLButtonElement) {
224
+ snapshot.onclick = ()=>this.snapshot(true);
225
+ }
226
+ const toggleSettings = this.shadow.querySelector('.toggleSettings');
227
+ if (toggleSettings instanceof HTMLButtonElement) {
228
+ toggleSettings.onclick = this._handleSettingsClick;
229
+ toggleSettings.onblur = this._handleBlur;
230
+ }
231
+ }
232
+ }
233
+
234
+ const pauseIcon = /* HTML */ `
235
+ <svg width="24" height="24" aria-hidden="true" focusable="false">
236
+ <path
237
+ d="M14.016 5.016H18v13.969h-3.984V5.016zM6 18.984V5.015h3.984v13.969H6z"
238
+ />
239
+ </svg>
240
+ `;
241
+
242
+ /**
243
+ * Render Player.
244
+ */ async function renderPlayer() {
245
+ if (!this.shadow || !this.template) {
246
+ throw new Error('No Shadow Element or Template');
247
+ }
248
+ this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" lang="${this.description ? document.documentElement.lang : 'en'}" aria-label="${this.description ?? 'Lottie animation'}" data-loaded="${this._playerState.loaded}"><figure class="animation" style="background:${this.background}">${this.playerState === PlayerState.Error ? /* HTML */ `<div class="error"><svg preserveAspectRatio="${PreserveAspectRatio.Cover}" xmlns="${namespaceSVG}" width="1920" height="1080" viewBox="0 0 1920 1080" style="white-space:preserve"><path fill="#fff" d="M0 0h1920v1080H0z"/><path fill="#3a6d8b" d="M1190.2 531 1007 212.4c-22-38.2-77.2-38-98.8.5L729.5 531.3c-21.3 37.9 6.1 84.6 49.5 84.6l361.9.3c43.7 0 71.1-47.3 49.3-85.2zM937.3 288.7c.2-7.5 3.3-23.9 23.2-23.9 16.3 0 23 16.1 23 23.5 0 55.3-10.7 197.2-12.2 214.5-.1 1-.9 1.7-1.9 1.7h-18.3c-1 0-1.8-.7-1.9-1.7-1.4-17.5-13.4-162.9-11.9-214.1zm24.2 283.8c-13.1 0-23.7-10.6-23.7-23.7s10.6-23.7 23.7-23.7 23.7 10.6 23.7 23.7-10.6 23.7-23.7 23.7zM722.1 644h112.6v34.4h-70.4V698h58.8v31.7h-58.8v22.6h72.4v36.2H722.1V644zm162 57.1h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6zm78.9 0h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5H963v15.6zm39.5 36.2c0-31.3 22.2-54.8 56.6-54.8 34.4 0 56.2 23.5 56.2 54.8s-21.8 54.6-56.2 54.6c-34.4-.1-56.6-23.3-56.6-54.6zm74 0c0-17.4-6.1-29.1-17.8-29.1-11.7 0-17.4 11.7-17.4 29.1 0 17.4 5.7 29.1 17.4 29.1s17.8-11.8 17.8-29.1zm83.1-36.2h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6z"/><path fill="none" d="M718.9 807.7h645v285.4h-645z"/><text fill="#3a6d8b" style="text-align:center;position:absolute;left:100%;font-size:47px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'.SFNSText-Regular',sans-serif" x="50%" y="848.017" text-anchor="middle">${this._errorMessage}</text></svg></div>` : ''}</figure><slot name="controls"></slot></div>`;
249
+ this.shadow.adoptedStyleSheets = [
250
+ await DotLottiePlayerBase.styles()
251
+ ];
252
+ this.shadow.appendChild(this.template.content.cloneNode(true));
253
+ }
254
+
255
+ /**
256
+ * Get extension from filename, URL or path.
257
+ */ const aspectRatio = (objectFit)=>{
258
+ switch(objectFit){
259
+ case ObjectFit.Contain:
260
+ case ObjectFit.ScaleDown:
261
+ {
262
+ return PreserveAspectRatio.Contain;
263
+ }
264
+ case ObjectFit.Cover:
265
+ {
266
+ return PreserveAspectRatio.Cover;
267
+ }
268
+ case ObjectFit.Fill:
269
+ {
270
+ return PreserveAspectRatio.Initial;
271
+ }
272
+ case ObjectFit.None:
273
+ {
274
+ return PreserveAspectRatio.None;
275
+ }
276
+ default:
277
+ {
278
+ return PreserveAspectRatio.Contain;
279
+ }
280
+ }
281
+ }, handleErrors = (err)=>{
282
+ const res = {
283
+ message: 'Unknown error',
284
+ status: isServer ? 500 : 400
285
+ };
286
+ if (err && typeof err === 'object') {
287
+ if ('message' in err && typeof err.message === 'string') {
288
+ res.message = err.message;
289
+ }
290
+ if ('status' in err) {
291
+ res.status = Number(err.status);
292
+ }
293
+ }
294
+ return res;
295
+ }, isLottie = (json)=>{
296
+ const mandatory = [
297
+ 'v',
298
+ 'ip',
299
+ 'op',
300
+ 'layers',
301
+ 'fr',
302
+ 'w',
303
+ 'h'
304
+ ];
305
+ return mandatory.every((field)=>Object.hasOwn(json, field));
306
+ }, frameOutput = (frame)=>((frame ?? 0) + 1).toString().padStart(3, '0');
307
+
308
+ const notImplemented = 'Method is not implemented';
309
+ /**
310
+ * DotLottie Player Web Component.
311
+ */ class DotLottiePlayerBase extends PropertyCallbackElement {
312
+ /**
313
+ * Attributes to observe.
314
+ */ static get observedAttributes() {
315
+ return [
316
+ 'animateOnScroll',
317
+ 'autoplay',
318
+ 'controls',
319
+ 'direction',
320
+ 'hover',
321
+ 'loop',
322
+ 'mode',
323
+ 'speed',
324
+ 'src',
325
+ 'subframe'
326
+ ];
327
+ }
328
+ static get observedProperties() {
329
+ return [
330
+ 'playerState',
331
+ '_isSettingsOpen',
332
+ '_seeker',
333
+ '_currentAnimation',
334
+ '_animations'
335
+ ];
336
+ }
337
+ /**
338
+ * Return the styles for the component.
339
+ */ static get styles() {
340
+ return async ()=>{
341
+ const styleSheet = new CSSStyleSheet();
342
+ await styleSheet.replace(css_248z);
343
+ return styleSheet;
344
+ };
345
+ }
346
+ /**
347
+ * Whether to trigger next frame with scroll.
348
+ */ set animateOnScroll(value) {
349
+ this.setAttribute('animateOnScroll', Boolean(value).toString());
350
+ }
351
+ get animateOnScroll() {
352
+ const val = this.getAttribute('animateOnScroll');
353
+ return val === 'true' || val === '' || val === '1';
354
+ }
355
+ get animations() {
356
+ return this._animations;
357
+ }
358
+ /**
359
+ * Autoplay.
360
+ */ set autoplay(value) {
361
+ this.setAttribute('autoplay', Boolean(value).toString());
362
+ }
363
+ get autoplay() {
364
+ const val = this.getAttribute('autoplay');
365
+ return val === 'true' || val === '' || val === '1';
366
+ }
367
+ /**
368
+ * Background color.
369
+ */ set background(value) {
370
+ this.setAttribute('background', value);
371
+ }
372
+ get background() {
373
+ return this.getAttribute('background') || 'transparent';
374
+ }
375
+ /**
376
+ * Show controls.
377
+ */ set controls(value) {
378
+ this.setAttribute('controls', Boolean(value).toString());
379
+ }
380
+ get controls() {
381
+ const val = this.getAttribute('controls');
382
+ return val === 'true' || val === '' || val === '1';
383
+ }
384
+ /**
385
+ * Number of times to loop.
386
+ */ set count(value) {
387
+ this.setAttribute('count', value.toString());
388
+ }
389
+ get count() {
390
+ const val = this.getAttribute('count');
391
+ if (val) {
392
+ return Number(val);
393
+ }
394
+ return 0;
395
+ }
396
+ get currentAnimation() {
397
+ return this._currentAnimation;
398
+ }
399
+ /**
400
+ * Description for screen readers.
401
+ */ set description(value) {
402
+ if (value) {
403
+ this.setAttribute('description', value);
404
+ }
405
+ }
406
+ get description() {
407
+ return this.getAttribute('description');
408
+ }
409
+ /**
410
+ * Direction of animation.
411
+ */ set direction(value) {
412
+ this.setAttribute('direction', value.toString());
413
+ }
414
+ get direction() {
415
+ const val = Number(this.getAttribute('direction'));
416
+ if (val === -1) {
417
+ return val;
418
+ }
419
+ return 1;
420
+ }
421
+ /**
422
+ * Whether to freeze animation when window loses focus.
423
+ */ set dontFreezeOnBlur(value) {
424
+ this.setAttribute('dontFreezeOnBlur', value.toString());
425
+ }
426
+ get dontFreezeOnBlur() {
427
+ const val = this.getAttribute('dontFreezeOnBlur');
428
+ return val === 'true' || val === '' || val === '1';
429
+ }
430
+ /**
431
+ * Whether to play on mouseover.
432
+ */ set hover(value) {
433
+ this.setAttribute('hover', value.toString());
434
+ }
435
+ get hover() {
436
+ const val = this.getAttribute('hover');
437
+ return val === 'true' || val === '' || val === '1';
438
+ }
439
+ /**
440
+ * Pause between loop intrations, in miliseconds.
441
+ */ set intermission(value) {
442
+ this.setAttribute('intermission', value.toString());
443
+ }
444
+ get intermission() {
445
+ const val = Number(this.getAttribute('intermission'));
446
+ if (!isNaN(val)) {
447
+ return val;
448
+ }
449
+ return 0;
450
+ }
451
+ get isDotLottie() {
452
+ return this._isDotLottie;
453
+ }
454
+ /**
455
+ * Loop animation.
456
+ */ set loop(value) {
457
+ this.setAttribute('loop', Boolean(value).toString());
458
+ }
459
+ get loop() {
460
+ const val = this.getAttribute('loop');
461
+ return val === 'true' || val === '' || val === '1';
462
+ }
463
+ /**
464
+ * Play mode.
465
+ */ set mode(value) {
466
+ this.setAttribute('mode', value);
467
+ }
468
+ get mode() {
469
+ const val = this.getAttribute('mode');
470
+ if (val === PlayMode.Bounce) {
471
+ return val;
472
+ }
473
+ return PlayMode.Normal;
474
+ }
475
+ /**
476
+ * Resizing to container.
477
+ */ set objectfit(value) {
478
+ this.setAttribute('objectfit', value);
479
+ }
480
+ get objectfit() {
481
+ const val = this.getAttribute('objectfit');
482
+ if (val && Object.values(ObjectFit).includes(val)) {
483
+ return val;
484
+ }
485
+ return ObjectFit.Contain;
486
+ }
487
+ /**
488
+ * Resizing to container (Deprecated).
489
+ */ set preserveAspectRatio(value) {
490
+ this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
491
+ }
492
+ get preserveAspectRatio() {
493
+ const val = this.getAttribute('preserveAspectRatio');
494
+ if (val && Object.values(PreserveAspectRatio).includes(val)) {
495
+ return val;
496
+ }
497
+ return null;
498
+ }
499
+ /**
500
+ * Renderer to use: svg, canvas or html.
501
+ */ set renderer(value) {
502
+ this.setAttribute('renderer', value);
503
+ }
504
+ get renderer() {
505
+ const val = this.getAttribute('renderer');
506
+ if (val === RendererType.Canvas || val === RendererType.HTML) {
507
+ return val;
508
+ }
509
+ return RendererType.SVG;
510
+ }
511
+ /**
512
+ * Hide advanced controls.
513
+ */ set simple(value) {
514
+ this.setAttribute('simple', value.toString());
515
+ }
516
+ get simple() {
517
+ const val = this.getAttribute('simple');
518
+ return val === 'true' || val === '' || val === '1';
519
+ }
520
+ /**
521
+ * Speed.
522
+ */ set speed(value) {
523
+ this.setAttribute('speed', value.toString());
524
+ }
525
+ get speed() {
526
+ const val = this.getAttribute('speed');
527
+ if (val !== null && !isNaN(Number(val))) {
528
+ return Number(val);
529
+ }
530
+ return 1;
531
+ }
532
+ /**
533
+ * Source, either path or JSON string.
534
+ */ set src(value) {
535
+ this.setAttribute('src', value || '');
536
+ }
537
+ get src() {
538
+ return this.getAttribute('src');
539
+ }
540
+ /**
541
+ * Subframe.
542
+ */ set subframe(value) {
543
+ this.setAttribute('subframe', Boolean(value).toString());
544
+ }
545
+ get subframe() {
546
+ const val = this.getAttribute('subframe');
547
+ return val === 'true' || val === '' || val === '1';
548
+ }
549
+ constructor(){
550
+ super(), this.isLight = false, /**
551
+ * Player state.
552
+ */ this.playerState = PlayerState.Loading, /**
553
+ * Animation Container.
554
+ */ this._container = null, this._errorMessage = 'Something went wrong', this._identifier = this.id || createElementID(), /**
555
+ * Whether settings toolbar is open.
556
+ */ this._isSettingsOpen = false, this._playerState = {
557
+ count: 0,
558
+ loaded: false,
559
+ prev: PlayerState.Loading,
560
+ scrollTimeout: null,
561
+ scrollY: 0,
562
+ visible: false
563
+ }, this._render = renderPlayer, this._renderControls = renderControls, /**
564
+ * Seeker.
565
+ */ this._seeker = 0, /**
566
+ * This is included in watched properties,
567
+ * so that next-button will show up
568
+ * on load, if controls are visible.
569
+ */ this._animations = [], /**
570
+ * Which animation to show, if several.
571
+ */ this._currentAnimation = 0, this._isBounce = false, this._isDotLottie = false, this._lottieInstance = null, /**
572
+ * Multi-animation settings.
573
+ */ this._multiAnimationSettings = [];
574
+ this._complete = this._complete.bind(this);
575
+ this._dataFailed = this._dataFailed.bind(this);
576
+ this._dataReady = this._dataReady.bind(this);
577
+ this._DOMLoaded = this._DOMLoaded.bind(this);
578
+ this._enterFrame = this._enterFrame.bind(this);
579
+ this._freeze = this._freeze.bind(this);
580
+ this._handleBlur = this._handleBlur.bind(this);
581
+ this._handleScroll = this._handleScroll.bind(this);
582
+ this._handleSeekChange = this._handleSeekChange.bind(this);
583
+ this._handleWindowBlur = this._handleWindowBlur.bind(this);
584
+ this._loopComplete = this._loopComplete.bind(this);
585
+ this._mouseEnter = this._mouseEnter.bind(this);
586
+ this._mouseLeave = this._mouseLeave.bind(this);
587
+ this._onVisibilityChange = this._onVisibilityChange.bind(this);
588
+ this._switchInstance = this._switchInstance.bind(this);
589
+ this._handleSettingsClick = this._handleSettingsClick.bind(this);
590
+ this.togglePlay = this.togglePlay.bind(this);
591
+ this.stop = this.stop.bind(this);
592
+ this.prev = this.prev.bind(this);
593
+ this.next = this.next.bind(this);
594
+ this._renderControls = this._renderControls.bind(this);
595
+ this.snapshot = this.snapshot.bind(this);
596
+ this.toggleLoop = this.toggleLoop.bind(this);
597
+ this.toggleBoomerang = this.toggleBoomerang.bind(this);
598
+ this.destroy = this.destroy.bind(this);
599
+ this.template = document.createElement('template');
600
+ this.shadow = this.attachShadow({
601
+ mode: 'open'
602
+ });
603
+ }
604
+ addAnimation(_params) {
605
+ throw new Error(notImplemented);
606
+ }
607
+ /**
608
+ * Runs when the value of an attribute is changed on the component.
609
+ */ async attributeChangedCallback(name, _oldValue, value) {
610
+ if (!this._lottieInstance || !this.shadow) {
611
+ return;
612
+ }
613
+ if (name === 'animateOnScroll') {
614
+ if (value === '' || Boolean(value)) {
615
+ this._lottieInstance.autoplay = false;
616
+ addEventListener('scroll', this._handleScroll, {
617
+ capture: true,
618
+ passive: true
619
+ });
620
+ return;
621
+ }
622
+ removeEventListener('scroll', this._handleScroll, true);
623
+ }
624
+ if (name === 'autoplay') {
625
+ if (this.animateOnScroll) {
626
+ return;
627
+ }
628
+ if (value === '' || Boolean(value)) {
629
+ this.play();
630
+ return;
631
+ }
632
+ this.stop();
633
+ }
634
+ if (name === 'controls') {
635
+ this._renderControls();
636
+ }
637
+ if (name === 'direction') {
638
+ if (Number(value) === -1) {
639
+ this.setDirection(-1);
640
+ return;
641
+ }
642
+ this.setDirection(1);
643
+ }
644
+ if (name === 'hover' && this._container) {
645
+ if (value === '' || Boolean(value)) {
646
+ this._container.addEventListener('mouseenter', this._mouseEnter);
647
+ this._container.addEventListener('mouseleave', this._mouseLeave);
648
+ return;
649
+ }
650
+ this._container.removeEventListener('mouseenter', this._mouseEnter);
651
+ this._container.removeEventListener('mouseleave', this._mouseLeave);
652
+ }
653
+ if (name === 'loop') {
654
+ const toggleLoop = this.shadow.querySelector('.toggleLoop');
655
+ if (toggleLoop instanceof HTMLButtonElement) {
656
+ toggleLoop.dataset.active = value;
657
+ }
658
+ this.setLoop(value === '' || Boolean(value));
659
+ }
660
+ if (name === 'mode') {
661
+ const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
662
+ if (toggleBoomerang instanceof HTMLButtonElement) {
663
+ toggleBoomerang.dataset.active = (value === PlayMode.Bounce).toString();
664
+ }
665
+ this._isBounce = value === PlayMode.Bounce;
666
+ }
667
+ if (name === 'speed') {
668
+ const val = Number(value);
669
+ if (val && !isNaN(val)) {
670
+ this.setSpeed(val);
671
+ }
672
+ }
673
+ if (name === 'src') {
674
+ await this.load(value);
675
+ }
676
+ if (name === 'subframe') {
677
+ this.setSubframe(value === '' || Boolean(value));
678
+ }
679
+ }
680
+ /**
681
+ * Initialize everything on component first render.
682
+ */ connectedCallback() {
683
+ super.connectedCallback();
684
+ try {
685
+ void (async ()=>{
686
+ await this._render();
687
+ if (!this.shadow) {
688
+ throw new Error('Missing Shadow element');
689
+ }
690
+ this._container = this.shadow.querySelector('.animation');
691
+ // Add listener for Visibility API's change event.
692
+ if (typeof document.hidden !== 'undefined') {
693
+ document.addEventListener('visibilitychange', this._onVisibilityChange);
694
+ }
695
+ // Add intersection observer for detecting component being out-of-view.
696
+ this._addIntersectionObserver();
697
+ // Setup lottie player
698
+ await this.load(this.src);
699
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Rendered));
700
+ })();
701
+ } catch (error) {
702
+ console.error(error);
703
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
704
+ }
705
+ }
706
+ convert(_params) {
707
+ throw new Error(notImplemented);
708
+ }
709
+ /**
710
+ * Destroy animation and element.
711
+ */ destroy() {
712
+ if (!this._lottieInstance?.destroy) {
713
+ return;
714
+ }
715
+ this.playerState = PlayerState.Destroyed;
716
+ this._lottieInstance.destroy();
717
+ this._lottieInstance = null;
718
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Destroyed));
719
+ this.remove();
720
+ document.removeEventListener('visibilitychange', this._onVisibilityChange);
721
+ }
722
+ /**
723
+ * Cleanup on component destroy.
724
+ */ disconnectedCallback() {
725
+ // Remove intersection observer for detecting component being out-of-view
726
+ if (this._intersectionObserver) {
727
+ this._intersectionObserver.disconnect();
728
+ this._intersectionObserver = undefined;
729
+ }
730
+ // Remove the attached Visibility API's change event listener
731
+ document.removeEventListener('visibilitychange', this._onVisibilityChange);
732
+ // Destroy the animation instance
733
+ this.destroy();
734
+ }
735
+ /**
736
+ * Returns the lottie-web instance used in the component.
737
+ */ getLottie() {
738
+ return this._lottieInstance;
739
+ }
740
+ /**
741
+ * Get Lottie Manifest.
742
+ */ getManifest() {
743
+ return this._manifest;
744
+ }
745
+ /**
746
+ * Get Multi-animation settings.
747
+ */ getMultiAnimationSettings() {
748
+ return this._multiAnimationSettings;
749
+ }
750
+ /**
751
+ * Get playback segment.
752
+ */ getSegment() {
753
+ return this._segment;
754
+ }
755
+ /**
756
+ * Initialize Lottie Web player.
757
+ */ async load(src) {
758
+ try {
759
+ if (!this.shadowRoot || !src) {
760
+ return;
761
+ }
762
+ this.source = src;
763
+ // Load the resource
764
+ const { animations, isDotLottie, manifest } = await getAnimationData(src);
765
+ if (!animations || animations.some((animation)=>!isLottie(animation))) {
766
+ throw new Error('Broken or corrupted file');
767
+ }
768
+ this._isBounce = this.mode === PlayMode.Bounce;
769
+ if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
770
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
771
+ }
772
+ const firstAnimation = manifest?.animations[0];
773
+ if (firstAnimation) {
774
+ firstAnimation.autoplay = this.autoplay;
775
+ firstAnimation.loop = this.loop;
776
+ }
777
+ this._isDotLottie = isDotLottie;
778
+ this._animations = animations;
779
+ this._manifest = manifest ?? {
780
+ animations: [
781
+ {
782
+ autoplay: !this.animateOnScroll && this.autoplay,
783
+ direction: this.direction,
784
+ id: createElementID(),
785
+ loop: this.loop,
786
+ mode: this.mode,
787
+ speed: this.speed
788
+ }
789
+ ]
790
+ };
791
+ // Clear previous animation, if any
792
+ this._lottieInstance?.destroy();
793
+ this.playerState = PlayerState.Stopped;
794
+ if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings[this._currentAnimation]?.autoplay)) {
795
+ this.playerState = PlayerState.Playing;
796
+ }
797
+ // Initialize lottie player and load animation
798
+ this._lottieInstance = this.loadAnimation({
799
+ ...this._getOptions(),
800
+ animationData: animations[this._currentAnimation]
801
+ });
802
+ this._addEventListeners();
803
+ const speed = this._multiAnimationSettings[this._currentAnimation]?.speed ?? this.speed, direction = this._multiAnimationSettings[this._currentAnimation]?.direction ?? this.direction;
804
+ // Set initial playback speed and direction
805
+ this._lottieInstance.setSpeed(speed);
806
+ this._lottieInstance.setDirection(direction);
807
+ this._lottieInstance.setSubframe(Boolean(this.subframe));
808
+ // Start playing if autoplay is enabled
809
+ if (this.autoplay || this.animateOnScroll) {
810
+ if (this.direction === -1) {
811
+ this.seek('99%');
812
+ }
813
+ if (!('IntersectionObserver' in window)) {
814
+ if (!this.animateOnScroll) {
815
+ this.play();
816
+ }
817
+ this._playerState.visible = true;
818
+ }
819
+ this._addIntersectionObserver();
820
+ }
821
+ this._renderControls();
822
+ if (this.autoplay) {
823
+ const togglePlay = this.shadow?.querySelector('.togglePlay');
824
+ if (togglePlay) {
825
+ togglePlay.innerHTML = pauseIcon;
826
+ }
827
+ }
828
+ } catch (error) {
829
+ console.error(error);
830
+ this._errorMessage = handleErrors(error).message;
831
+ this.playerState = PlayerState.Error;
832
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
833
+ }
834
+ }
835
+ loadAnimation(_config) {
836
+ throw new Error(notImplemented);
837
+ }
838
+ /**
839
+ * Skip to next animation.
840
+ */ next() {
841
+ this._currentAnimation++;
842
+ this._switchInstance();
843
+ }
844
+ /**
845
+ * Pause.
846
+ */ pause() {
847
+ if (!this._lottieInstance) {
848
+ return;
849
+ }
850
+ this._playerState.prev = this.playerState;
851
+ try {
852
+ this._lottieInstance.pause();
853
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Pause));
854
+ } finally{
855
+ this.playerState = PlayerState.Paused;
856
+ }
857
+ }
858
+ /**
859
+ * Play.
860
+ */ play() {
861
+ if (!this._lottieInstance) {
862
+ return;
863
+ }
864
+ this._playerState.prev = this.playerState;
865
+ try {
866
+ this._lottieInstance.play();
867
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Play));
868
+ } finally{
869
+ this.playerState = PlayerState.Playing;
870
+ }
871
+ }
872
+ /**
873
+ * Skip to previous animation.
874
+ */ prev() {
875
+ this._currentAnimation--;
876
+ this._switchInstance(true);
877
+ }
878
+ /**
879
+ * Name: string, oldValue: string, newValue: string.
880
+ */ propertyChangedCallback(name, _oldValue, value) {
881
+ if (!this.shadow) {
882
+ return;
883
+ }
884
+ const togglePlay = this.shadow.querySelector('.togglePlay'), stopButton = this.shadow.querySelector('.stop'), prevButton = this.shadow.querySelector('.prev'), nextButton = this.shadow.querySelector('.next'), seeker = this.shadow.querySelector('.seeker'), progress = this.shadow.querySelector('progress'), popover = this.shadow.querySelector('.popover'), convertButton = this.shadow.querySelector('.convert'), snapshot = this.shadow.querySelector('.snapshot');
885
+ if (!(togglePlay instanceof HTMLButtonElement) || !(stopButton instanceof HTMLButtonElement) || !(nextButton instanceof HTMLButtonElement) || !(prevButton instanceof HTMLButtonElement) || !(seeker instanceof HTMLInputElement) || !(progress instanceof HTMLProgressElement)) {
886
+ return;
887
+ }
888
+ if (name === 'playerState') {
889
+ togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
890
+ stopButton.dataset.active = (value === PlayerState.Stopped).toString();
891
+ if (value === PlayerState.Playing) {
892
+ togglePlay.innerHTML = pauseIcon;
893
+ } else {
894
+ togglePlay.innerHTML = playIcon;
895
+ }
896
+ }
897
+ if (name === '_seeker' && typeof value === 'number') {
898
+ seeker.value = value.toString();
899
+ seeker.ariaValueNow = value.toString();
900
+ progress.value = value;
901
+ }
902
+ if (name === '_animations' && Array.isArray(value) && this._currentAnimation + 1 < value.length) {
903
+ nextButton.hidden = false;
904
+ }
905
+ if (name === '_currentAnimation' && typeof value === 'number') {
906
+ nextButton.hidden = value + 1 >= this._animations.length;
907
+ prevButton.hidden = !value;
908
+ }
909
+ if (name === '_isSettingsOpen' && typeof value === 'boolean' && popover instanceof HTMLDivElement && convertButton instanceof HTMLButtonElement && snapshot instanceof HTMLButtonElement) {
910
+ popover.hidden = !value;
911
+ convertButton.hidden = this.isLight;
912
+ snapshot.hidden = this.renderer !== RendererType.SVG;
913
+ }
914
+ }
915
+ /**
916
+ * Reload animation.
917
+ */ async reload() {
918
+ if (!this._lottieInstance || !this.src) {
919
+ return;
920
+ }
921
+ this._lottieInstance.destroy();
922
+ await this.load(this.src);
923
+ }
924
+ /**
925
+ * Seek to a given frame.
926
+ *
927
+ * @param value - Frame to seek to.
928
+ */ seek(value) {
929
+ if (!this._lottieInstance) {
930
+ return;
931
+ }
932
+ // Extract frame number from either number or percentage value
933
+ const matches = value.toString().match(/^(\d+)(%?)$/);
934
+ if (!matches) {
935
+ return;
936
+ }
937
+ // Calculate and set the frame number
938
+ const frame = Math.round(matches[2] === '%' ? this._lottieInstance.totalFrames * Number(matches[1]) / 100 : Number(matches[1]));
939
+ // Set seeker to new frame number
940
+ this._seeker = frame;
941
+ // Send lottie player to the new frame
942
+ if (this.playerState === PlayerState.Playing || this.playerState === PlayerState.Frozen && this._playerState.prev === PlayerState.Playing) {
943
+ this._lottieInstance.goToAndPlay(frame, true);
944
+ this.playerState = PlayerState.Playing;
945
+ return;
946
+ }
947
+ this._lottieInstance.goToAndStop(frame, true);
948
+ this._lottieInstance.pause();
949
+ }
950
+ /**
951
+ * Dynamically set count for loops.
952
+ */ setCount(value) {
953
+ this.count = value;
954
+ }
955
+ /**
956
+ * Animation play direction.
957
+ *
958
+ * @param value - Animation direction.
959
+ */ setDirection(value) {
960
+ if (!this._lottieInstance) {
961
+ return;
962
+ }
963
+ this._lottieInstance.setDirection(value);
964
+ }
965
+ /**
966
+ * Set loop.
967
+ *
968
+ */ setLoop(value) {
969
+ if (!this._lottieInstance) {
970
+ return;
971
+ }
972
+ this._lottieInstance.setLoop(value);
973
+ }
974
+ /**
975
+ * Set Multi-animation settings.
976
+ */ setMultiAnimationSettings(settings) {
977
+ this._multiAnimationSettings = settings;
978
+ }
979
+ /**
980
+ * Set playback segment.
981
+ */ setSegment(segment) {
982
+ this._segment = segment;
983
+ }
984
+ /**
985
+ * Set animation playback speed.
986
+ *
987
+ * @param value - Playback speed.
988
+ */ setSpeed(value = 1) {
989
+ if (!this._lottieInstance) {
990
+ return;
991
+ }
992
+ this._lottieInstance.setSpeed(value);
993
+ }
994
+ /**
995
+ * Toggles subframe, for more smooth animations.
996
+ *
997
+ * @param value - Whether animation uses subframe.
998
+ */ setSubframe(value) {
999
+ if (!this._lottieInstance) {
1000
+ return;
1001
+ }
1002
+ this._lottieInstance.setSubframe(value);
1003
+ }
1004
+ /**
1005
+ * Snapshot and download the current frame as SVG.
1006
+ */ snapshot(shouldDownload = true, name = 'AM Lottie') {
1007
+ try {
1008
+ if (!this.shadowRoot) {
1009
+ throw new Error('Unknown error');
1010
+ }
1011
+ // Get SVG element and serialize markup
1012
+ const svgElement = this.shadowRoot.querySelector('.animation svg');
1013
+ if (!svgElement) {
1014
+ throw new Error('Could not retrieve animation from DOM');
1015
+ }
1016
+ const data = svgElement instanceof Node ? new XMLSerializer().serializeToString(svgElement) : null;
1017
+ if (!data) {
1018
+ throw new Error('Could not serialize SVG element');
1019
+ }
1020
+ if (shouldDownload) {
1021
+ download(data, {
1022
+ mimeType: 'image/svg+xml',
1023
+ name: `${getFilename(this.src || name)}-${frameOutput(this._seeker)}.svg`
1024
+ });
1025
+ }
1026
+ return data;
1027
+ } catch (error) {
1028
+ console.error(error);
1029
+ return null;
1030
+ }
1031
+ }
1032
+ /**
1033
+ * Stop.
1034
+ */ stop() {
1035
+ if (!this._lottieInstance) {
1036
+ return;
1037
+ }
1038
+ this._playerState.prev = this.playerState;
1039
+ this._playerState.count = 0;
1040
+ try {
1041
+ this._lottieInstance.stop();
1042
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Stop));
1043
+ } finally{
1044
+ this.playerState = PlayerState.Stopped;
1045
+ }
1046
+ }
1047
+ /**
1048
+ * Toggle Boomerang.
1049
+ */ toggleBoomerang() {
1050
+ const curr = this._multiAnimationSettings[this._currentAnimation] ?? {};
1051
+ if (curr.mode !== undefined) {
1052
+ if (curr.mode === PlayMode.Normal) {
1053
+ curr.mode = PlayMode.Bounce;
1054
+ this._isBounce = true;
1055
+ return;
1056
+ }
1057
+ curr.mode = PlayMode.Normal;
1058
+ this._isBounce = false;
1059
+ return;
1060
+ }
1061
+ if (this.mode === PlayMode.Normal) {
1062
+ this.mode = PlayMode.Bounce;
1063
+ this._isBounce = true;
1064
+ return;
1065
+ }
1066
+ this.mode = PlayMode.Normal;
1067
+ this._isBounce = false;
1068
+ }
1069
+ /**
1070
+ * Toggle loop.
1071
+ */ toggleLoop() {
1072
+ const hasLoop = !this.loop;
1073
+ this.loop = hasLoop;
1074
+ this.setLoop(hasLoop);
1075
+ }
1076
+ /**
1077
+ * Toggle playing state.
1078
+ */ togglePlay() {
1079
+ if (!this._lottieInstance) {
1080
+ return;
1081
+ }
1082
+ const { currentFrame, playDirection, totalFrames } = this._lottieInstance;
1083
+ if (this.playerState === PlayerState.Playing) {
1084
+ this.pause();
1085
+ return;
1086
+ }
1087
+ if (this.playerState !== PlayerState.Completed) {
1088
+ this.play();
1089
+ return;
1090
+ }
1091
+ this.playerState = PlayerState.Playing;
1092
+ if (this._isBounce) {
1093
+ this.setDirection(playDirection * -1);
1094
+ this._lottieInstance.goToAndPlay(currentFrame, true);
1095
+ return;
1096
+ }
1097
+ if (playDirection === -1) {
1098
+ this._lottieInstance.goToAndPlay(totalFrames, true);
1099
+ return;
1100
+ }
1101
+ this._lottieInstance.goToAndPlay(0, true);
1102
+ }
1103
+ /**
1104
+ * Freeze animation.
1105
+ * This internal state pauses animation and is used to differentiate between
1106
+ * user requested pauses and component instigated pauses.
1107
+ */ _freeze() {
1108
+ if (!this._lottieInstance) {
1109
+ return;
1110
+ }
1111
+ this._playerState.prev = this.playerState;
1112
+ try {
1113
+ this._lottieInstance.pause();
1114
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
1115
+ } finally{
1116
+ this.playerState = PlayerState.Frozen;
1117
+ }
1118
+ }
1119
+ /**
1120
+ * Handle blur.
1121
+ */ _handleBlur() {
1122
+ setTimeout(()=>{
1123
+ this._toggleSettings(false);
1124
+ }, 200);
1125
+ }
1126
+ /**
1127
+ * Handles click and drag actions on the progress track.
1128
+ */ _handleSeekChange({ target }) {
1129
+ if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
1130
+ return;
1131
+ }
1132
+ this.seek(Math.round(Number(target.value) / 100 * this._lottieInstance.totalFrames));
1133
+ }
1134
+ /**
1135
+ * Handle settings click event.
1136
+ */ _handleSettingsClick({ target }) {
1137
+ this._toggleSettings();
1138
+ // Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
1139
+ if (target instanceof HTMLElement) {
1140
+ target.focus();
1141
+ }
1142
+ }
1143
+ setOptions(_options) {
1144
+ throw new Error('Method not implemented');
1145
+ }
1146
+ /**
1147
+ * Add event listeners.
1148
+ */ _addEventListeners() {
1149
+ this._toggleEventListeners('add');
1150
+ }
1151
+ /**
1152
+ * Add IntersectionObserver.
1153
+ */ _addIntersectionObserver() {
1154
+ if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
1155
+ return;
1156
+ }
1157
+ this._intersectionObserver = new IntersectionObserver((entries)=>{
1158
+ const { length } = entries;
1159
+ for(let i = 0; i < length; i++){
1160
+ if (!entries[i]?.isIntersecting || document.hidden) {
1161
+ if (this.playerState === PlayerState.Playing) {
1162
+ this._freeze();
1163
+ }
1164
+ this._playerState.visible = false;
1165
+ continue;
1166
+ }
1167
+ if (!this.animateOnScroll && this.playerState === PlayerState.Frozen) {
1168
+ this.play();
1169
+ }
1170
+ /**
1171
+ * If the player is a ways down the page, we need to account for this by
1172
+ * setting _playerState.scrollY to the current scroll position. However, we
1173
+ * also need to check that the player hasn't been scrolled past, so we check
1174
+ * boundingClientRect as well.
1175
+ */ if (!this._playerState.scrollY && (entries[i]?.boundingClientRect.y || 0) > 0) {
1176
+ this._playerState.scrollY = scrollY;
1177
+ }
1178
+ this._playerState.visible = true;
1179
+ }
1180
+ });
1181
+ this._intersectionObserver.observe(this._container);
1182
+ }
1183
+ _complete() {
1184
+ if (!this._lottieInstance) {
1185
+ return;
1186
+ }
1187
+ if (this._animations.length > 1) {
1188
+ if (this._multiAnimationSettings[this._currentAnimation + 1]?.autoplay) {
1189
+ this.next();
1190
+ return;
1191
+ }
1192
+ if (this.loop && this._currentAnimation === this._animations.length - 1) {
1193
+ this._currentAnimation = 0;
1194
+ this._switchInstance();
1195
+ return;
1196
+ }
1197
+ }
1198
+ const { currentFrame, totalFrames } = this._lottieInstance;
1199
+ this._seeker = Math.round(currentFrame / totalFrames * 100);
1200
+ this.playerState = PlayerState.Completed;
1201
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Complete, {
1202
+ detail: {
1203
+ frame: currentFrame,
1204
+ seeker: this._seeker
1205
+ }
1206
+ }));
1207
+ }
1208
+ _dataFailed() {
1209
+ this.playerState = PlayerState.Error;
1210
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
1211
+ }
1212
+ _dataReady() {
1213
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Load));
1214
+ }
1215
+ _DOMLoaded() {
1216
+ this._playerState.loaded = true;
1217
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Ready));
1218
+ }
1219
+ _enterFrame() {
1220
+ if (!this._lottieInstance) {
1221
+ return;
1222
+ }
1223
+ const { currentFrame, totalFrames } = this._lottieInstance;
1224
+ this._seeker = Math.round(currentFrame / totalFrames * 100);
1225
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Frame, {
1226
+ detail: {
1227
+ frame: currentFrame,
1228
+ seeker: this._seeker
1229
+ }
1230
+ }));
1231
+ }
1232
+ /**
1233
+ * Get options from props.
1234
+ */ _getOptions() {
1235
+ if (!this._container) {
1236
+ throw new Error('Container not rendered');
1237
+ }
1238
+ const preserveAspectRatio = this.preserveAspectRatio ?? aspectRatio(this.objectfit), currentAnimationSettings = this._multiAnimationSettings.length > 0 ? this._multiAnimationSettings[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest?.animations[this._currentAnimation];
1239
+ // Loop
1240
+ let hasLoop = Boolean(this.loop);
1241
+ if (currentAnimationManifest?.loop !== undefined) {
1242
+ hasLoop = Boolean(currentAnimationManifest.loop);
1243
+ }
1244
+ if (currentAnimationSettings?.loop !== undefined) {
1245
+ hasLoop = Boolean(currentAnimationSettings.loop);
1246
+ }
1247
+ // Autoplay
1248
+ let hasAutoplay = Boolean(this.autoplay);
1249
+ if (currentAnimationManifest?.autoplay !== undefined) {
1250
+ hasAutoplay = Boolean(currentAnimationManifest.autoplay);
1251
+ }
1252
+ if (currentAnimationSettings?.autoplay !== undefined) {
1253
+ hasAutoplay = Boolean(currentAnimationSettings.autoplay);
1254
+ }
1255
+ if (this.animateOnScroll) {
1256
+ hasAutoplay = false;
1257
+ }
1258
+ // Segment
1259
+ let initialSegment = this._segment;
1260
+ if (this._segment?.every((val)=>val > 0)) {
1261
+ initialSegment = [
1262
+ this._segment[0] - 1,
1263
+ this._segment[1] - 1
1264
+ ];
1265
+ }
1266
+ if (this._segment?.some((val)=>val < 0)) {
1267
+ initialSegment = undefined;
1268
+ }
1269
+ return this.setOptions({
1270
+ container: this._container,
1271
+ hasAutoplay,
1272
+ hasLoop,
1273
+ initialSegment,
1274
+ preserveAspectRatio,
1275
+ rendererType: this.renderer
1276
+ });
1277
+ }
1278
+ /**
1279
+ * Handle scroll.
1280
+ */ _handleScroll() {
1281
+ if (!this.animateOnScroll || !this._lottieInstance) {
1282
+ return;
1283
+ }
1284
+ if (isServer) {
1285
+ console.warn('DotLottie: Scroll animations might not work properly in a Server Side Rendering context. Try to wrap this in a client component.');
1286
+ return;
1287
+ }
1288
+ if (this._playerState.visible) {
1289
+ if (this._playerState.scrollTimeout) {
1290
+ clearTimeout(this._playerState.scrollTimeout);
1291
+ }
1292
+ this._playerState.scrollTimeout = setTimeout(()=>{
1293
+ this.playerState = PlayerState.Paused;
1294
+ }, 400);
1295
+ const adjustedScroll = scrollY > this._playerState.scrollY ? scrollY - this._playerState.scrollY : this._playerState.scrollY - scrollY, clampedScroll = Math.min(Math.max(adjustedScroll / 3, 1), this._lottieInstance.totalFrames * 3), roundedScroll = clampedScroll / 3;
1296
+ requestAnimationFrame(()=>{
1297
+ if (roundedScroll < (this._lottieInstance?.totalFrames ?? 0)) {
1298
+ this.playerState = PlayerState.Playing;
1299
+ this._lottieInstance?.goToAndStop(roundedScroll, true);
1300
+ } else {
1301
+ this.playerState = PlayerState.Paused;
1302
+ }
1303
+ });
1304
+ }
1305
+ }
1306
+ _handleWindowBlur({ type }) {
1307
+ if (this.dontFreezeOnBlur) {
1308
+ return;
1309
+ }
1310
+ if (this.playerState === PlayerState.Playing && type === 'blur') {
1311
+ this._freeze();
1312
+ }
1313
+ if (this.playerState === PlayerState.Frozen && type === 'focus') {
1314
+ this.play();
1315
+ }
1316
+ }
1317
+ _loopComplete() {
1318
+ if (!this._lottieInstance) {
1319
+ return;
1320
+ }
1321
+ const { playDirection, // firstFrame,
1322
+ totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
1323
+ if (this.count) {
1324
+ if (this._isBounce) {
1325
+ this._playerState.count += 0.5;
1326
+ } else {
1327
+ this._playerState.count += 1;
1328
+ }
1329
+ if (this._playerState.count >= this.count) {
1330
+ this.setLoop(false);
1331
+ this.playerState = PlayerState.Completed;
1332
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Complete));
1333
+ return;
1334
+ }
1335
+ }
1336
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
1337
+ if (this._isBounce) {
1338
+ this._lottieInstance.goToAndStop(playDirection === -1 ? inPoint : outPoint * 0.99, true);
1339
+ this._lottieInstance.setDirection(playDirection * -1);
1340
+ return setTimeout(()=>{
1341
+ if (!this.animateOnScroll) {
1342
+ this._lottieInstance?.play();
1343
+ }
1344
+ }, this.intermission);
1345
+ }
1346
+ this._lottieInstance.goToAndStop(playDirection === -1 ? outPoint * 0.99 : inPoint, true);
1347
+ return setTimeout(()=>{
1348
+ if (!this.animateOnScroll) {
1349
+ this._lottieInstance?.play();
1350
+ }
1351
+ }, this.intermission);
1352
+ }
1353
+ /**
1354
+ * Handle MouseEnter.
1355
+ */ _mouseEnter() {
1356
+ if (this.hover && this.playerState !== PlayerState.Playing) {
1357
+ this.play();
1358
+ }
1359
+ }
1360
+ /**
1361
+ * Handle MouseLeave.
1362
+ */ _mouseLeave() {
1363
+ if (this.hover && this.playerState === PlayerState.Playing) {
1364
+ this.stop();
1365
+ }
1366
+ }
1367
+ /**
1368
+ * Handle visibility change events.
1369
+ */ _onVisibilityChange() {
1370
+ if (document.hidden && this.playerState === PlayerState.Playing) {
1371
+ this._freeze();
1372
+ return;
1373
+ }
1374
+ if (this.playerState === PlayerState.Frozen) {
1375
+ this.play();
1376
+ }
1377
+ }
1378
+ /**
1379
+ * Remove event listeners.
1380
+ */ _removeEventListeners() {
1381
+ this._toggleEventListeners('remove');
1382
+ }
1383
+ _switchInstance(isPrevious = false) {
1384
+ // Bail early if there is not animation to play
1385
+ if (!this._animations[this._currentAnimation]) {
1386
+ return;
1387
+ }
1388
+ try {
1389
+ // Clear previous animation
1390
+ if (this._lottieInstance) {
1391
+ this._lottieInstance.destroy();
1392
+ }
1393
+ // Re-initialize lottie player
1394
+ this._lottieInstance = this.loadAnimation({
1395
+ ...this._getOptions(),
1396
+ animationData: this._animations[this._currentAnimation]
1397
+ });
1398
+ // Check play mode for current animation
1399
+ if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
1400
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
1401
+ }
1402
+ // Remove event listeners to new Lottie instance, and add new
1403
+ this._removeEventListeners();
1404
+ this._addEventListeners();
1405
+ this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
1406
+ if (this._multiAnimationSettings[this._currentAnimation]?.autoplay ?? this.autoplay) {
1407
+ if (this.animateOnScroll) {
1408
+ this._lottieInstance.goToAndStop(0, true);
1409
+ this.playerState = PlayerState.Paused;
1410
+ return;
1411
+ }
1412
+ this._lottieInstance.goToAndPlay(0, true);
1413
+ this.playerState = PlayerState.Playing;
1414
+ return;
1415
+ }
1416
+ this._lottieInstance.goToAndStop(0, true);
1417
+ this.playerState = PlayerState.Stopped;
1418
+ } catch (error) {
1419
+ this._errorMessage = handleErrors(error).message;
1420
+ this.playerState = PlayerState.Error;
1421
+ this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
1422
+ }
1423
+ }
1424
+ /**
1425
+ * Toggle event listeners.
1426
+ */ _toggleEventListeners(action) {
1427
+ const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
1428
+ if (this._lottieInstance) {
1429
+ this._lottieInstance[method]('enterFrame', this._enterFrame);
1430
+ this._lottieInstance[method]('complete', this._complete);
1431
+ this._lottieInstance[method]('loopComplete', this._loopComplete);
1432
+ this._lottieInstance[method]('DOMLoaded', this._DOMLoaded);
1433
+ this._lottieInstance[method]('data_ready', this._dataReady);
1434
+ this._lottieInstance[method]('data_failed', this._dataFailed);
1435
+ }
1436
+ if (this._container && this.hover) {
1437
+ this._container[method]('mouseenter', this._mouseEnter);
1438
+ this._container[method]('mouseleave', this._mouseLeave);
1439
+ }
1440
+ window[method]('focus', this._handleWindowBlur, {
1441
+ capture: false,
1442
+ passive: true
1443
+ });
1444
+ window[method]('blur', this._handleWindowBlur, {
1445
+ capture: false,
1446
+ passive: true
1447
+ });
1448
+ if (this.animateOnScroll) {
1449
+ window[method]('scroll', this._handleScroll, {
1450
+ capture: true,
1451
+ passive: true
1452
+ });
1453
+ }
1454
+ }
1455
+ /**
1456
+ * Toggle show Settings.
1457
+ */ _toggleSettings(flag) {
1458
+ if (flag === undefined) {
1459
+ this._isSettingsOpen = !this._isSettingsOpen;
1460
+ return;
1461
+ }
1462
+ this._isSettingsOpen = flag;
1463
+ }
1464
+ }
1465
+
1466
+ /**
1467
+ * DotLottie Player Web Component.
1468
+ */ class DotLottiePlayerSVG extends DotLottiePlayerBase {
1469
+ get renderer() {
1470
+ return RendererType.SVG;
1471
+ }
1472
+ constructor(){
1473
+ super(), // @ts-expect-error: TODO:
1474
+ this.loadAnimation = Lottie.loadAnimation;
1475
+ this.isLight = true;
1476
+ }
1477
+ setOptions({ container, hasAutoplay, hasLoop, initialSegment, preserveAspectRatio }) {
1478
+ const options = {
1479
+ autoplay: hasAutoplay,
1480
+ container,
1481
+ initialSegment,
1482
+ loop: hasLoop,
1483
+ renderer: RendererType.SVG,
1484
+ rendererSettings: {
1485
+ hideOnTransparent: true,
1486
+ imagePreserveAspectRatio: preserveAspectRatio,
1487
+ preserveAspectRatio,
1488
+ progressiveLoad: true
1489
+ }
1490
+ };
1491
+ return options;
1492
+ }
1493
+ }
1494
+
1495
+ /**
1496
+ * Expose DotLottiePlayer class as global variable.
1497
+ */ globalThis.dotLottiePlayer = ()=>new DotLottiePlayerSVG();
1498
+ if (!isServer) {
1499
+ customElements.define(tagName, DotLottiePlayerSVG);
1500
+ }
1501
+
1502
+ export { PlayerState, DotLottiePlayerSVG as default, tagName };