@editframe/elements 0.21.0-beta.0 → 0.23.6-beta.0
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/EF_FRAMEGEN.js +2 -3
- package/dist/attachContextRoot.d.ts +1 -0
- package/dist/attachContextRoot.js +9 -0
- package/dist/elements/ContextProxiesController.d.ts +1 -2
- package/dist/elements/EFAudio.js +2 -2
- package/dist/elements/EFCaptions.d.ts +1 -3
- package/dist/elements/EFCaptions.js +59 -51
- package/dist/elements/EFImage.js +2 -2
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +1 -2
- package/dist/elements/EFMedia/AssetMediaEngine.js +1 -3
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +2 -4
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +4 -7
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +1 -2
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +5 -9
- package/dist/elements/EFMedia/shared/BufferUtils.js +1 -3
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +4 -7
- package/dist/elements/EFMedia.d.ts +19 -0
- package/dist/elements/EFMedia.js +19 -2
- package/dist/elements/EFSourceMixin.js +1 -1
- package/dist/elements/EFSurface.js +1 -1
- package/dist/elements/EFTemporal.browsertest.d.ts +11 -0
- package/dist/elements/EFTemporal.d.ts +10 -0
- package/dist/elements/EFTemporal.js +82 -5
- package/dist/elements/EFThumbnailStrip.js +9 -16
- package/dist/elements/EFTimegroup.browsertest.d.ts +3 -3
- package/dist/elements/EFTimegroup.d.ts +35 -14
- package/dist/elements/EFTimegroup.js +72 -120
- package/dist/elements/EFVideo.d.ts +10 -0
- package/dist/elements/EFVideo.js +15 -2
- package/dist/elements/EFWaveform.js +10 -18
- package/dist/elements/SampleBuffer.js +1 -2
- package/dist/elements/TargetController.js +2 -2
- package/dist/elements/renderTemporalAudio.d.ts +10 -0
- package/dist/elements/renderTemporalAudio.js +35 -0
- package/dist/elements/updateAnimations.js +7 -10
- package/dist/gui/ContextMixin.d.ts +5 -5
- package/dist/gui/ContextMixin.js +151 -117
- package/dist/gui/Controllable.browsertest.d.ts +0 -0
- package/dist/gui/Controllable.d.ts +15 -0
- package/dist/gui/Controllable.js +9 -0
- package/dist/gui/EFConfiguration.js +1 -1
- package/dist/gui/EFControls.browsertest.d.ts +11 -0
- package/dist/gui/EFControls.d.ts +18 -4
- package/dist/gui/EFControls.js +67 -25
- package/dist/gui/EFDial.browsertest.d.ts +0 -0
- package/dist/gui/EFDial.d.ts +18 -0
- package/dist/gui/EFDial.js +141 -0
- package/dist/gui/EFFilmstrip.browsertest.d.ts +11 -0
- package/dist/gui/EFFilmstrip.d.ts +12 -2
- package/dist/gui/EFFilmstrip.js +140 -34
- package/dist/gui/EFFitScale.js +2 -4
- package/dist/gui/EFFocusOverlay.js +1 -1
- package/dist/gui/EFPause.browsertest.d.ts +0 -0
- package/dist/gui/EFPause.d.ts +23 -0
- package/dist/gui/EFPause.js +59 -0
- package/dist/gui/EFPlay.browsertest.d.ts +0 -0
- package/dist/gui/EFPlay.d.ts +23 -0
- package/dist/gui/EFPlay.js +59 -0
- package/dist/gui/EFPreview.d.ts +4 -0
- package/dist/gui/EFPreview.js +15 -6
- package/dist/gui/EFResizableBox.browsertest.d.ts +0 -0
- package/dist/gui/EFResizableBox.d.ts +34 -0
- package/dist/gui/EFResizableBox.js +547 -0
- package/dist/gui/EFScrubber.d.ts +9 -3
- package/dist/gui/EFScrubber.js +7 -7
- package/dist/gui/EFTimeDisplay.d.ts +7 -1
- package/dist/gui/EFTimeDisplay.js +5 -5
- package/dist/gui/EFToggleLoop.d.ts +9 -3
- package/dist/gui/EFToggleLoop.js +6 -4
- package/dist/gui/EFTogglePlay.d.ts +12 -4
- package/dist/gui/EFTogglePlay.js +24 -19
- package/dist/gui/EFWorkbench.js +1 -1
- package/dist/gui/PlaybackController.d.ts +67 -0
- package/dist/gui/PlaybackController.js +310 -0
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TargetOrContextMixin.d.ts +10 -0
- package/dist/gui/TargetOrContextMixin.js +98 -0
- package/dist/gui/efContext.d.ts +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -1
- package/dist/otel/setupBrowserTracing.d.ts +1 -1
- package/dist/otel/setupBrowserTracing.js +6 -4
- package/dist/otel/tracingHelpers.js +1 -2
- package/dist/style.css +1 -1
- package/package.json +5 -5
- package/src/elements/ContextProxiesController.ts +10 -10
- package/src/elements/EFAudio.ts +1 -0
- package/src/elements/EFCaptions.browsertest.ts +128 -58
- package/src/elements/EFCaptions.ts +60 -34
- package/src/elements/EFImage.browsertest.ts +1 -2
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +3 -0
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +1 -1
- package/src/elements/EFMedia.browsertest.ts +8 -15
- package/src/elements/EFMedia.ts +38 -7
- package/src/elements/EFSurface.browsertest.ts +2 -6
- package/src/elements/EFSurface.ts +1 -0
- package/src/elements/EFTemporal.browsertest.ts +58 -1
- package/src/elements/EFTemporal.ts +140 -4
- package/src/elements/EFThumbnailStrip.browsertest.ts +2 -8
- package/src/elements/EFThumbnailStrip.ts +1 -0
- package/src/elements/EFTimegroup.browsertest.ts +6 -7
- package/src/elements/EFTimegroup.ts +162 -244
- package/src/elements/EFVideo.browsertest.ts +143 -47
- package/src/elements/EFVideo.ts +26 -0
- package/src/elements/FetchContext.browsertest.ts +7 -2
- package/src/elements/TargetController.browsertest.ts +1 -0
- package/src/elements/TargetController.ts +1 -0
- package/src/elements/renderTemporalAudio.ts +108 -0
- package/src/elements/updateAnimations.browsertest.ts +181 -6
- package/src/elements/updateAnimations.ts +6 -6
- package/src/gui/ContextMixin.browsertest.ts +274 -27
- package/src/gui/ContextMixin.ts +230 -175
- package/src/gui/Controllable.browsertest.ts +258 -0
- package/src/gui/Controllable.ts +41 -0
- package/src/gui/EFControls.browsertest.ts +294 -80
- package/src/gui/EFControls.ts +139 -28
- package/src/gui/EFDial.browsertest.ts +84 -0
- package/src/gui/EFDial.ts +172 -0
- package/src/gui/EFFilmstrip.browsertest.ts +712 -0
- package/src/gui/EFFilmstrip.ts +213 -23
- package/src/gui/EFPause.browsertest.ts +202 -0
- package/src/gui/EFPause.ts +73 -0
- package/src/gui/EFPlay.browsertest.ts +202 -0
- package/src/gui/EFPlay.ts +73 -0
- package/src/gui/EFPreview.ts +20 -5
- package/src/gui/EFResizableBox.browsertest.ts +79 -0
- package/src/gui/EFResizableBox.ts +898 -0
- package/src/gui/EFScrubber.ts +7 -5
- package/src/gui/EFTimeDisplay.browsertest.ts +19 -19
- package/src/gui/EFTimeDisplay.ts +3 -1
- package/src/gui/EFToggleLoop.ts +6 -5
- package/src/gui/EFTogglePlay.ts +30 -23
- package/src/gui/PlaybackController.ts +522 -0
- package/src/gui/TWMixin.css +3 -0
- package/src/gui/TargetOrContextMixin.ts +185 -0
- package/src/gui/efContext.ts +2 -2
- package/src/otel/setupBrowserTracing.ts +17 -12
- package/test/cache-integration-verification.browsertest.ts +1 -1
- package/types.json +1 -1
- package/dist/elements/ContextProxiesController.js +0 -49
- /package/dist/_virtual/{_@oxc-project_runtime@0.93.0 → _@oxc-project_runtime@0.94.0}/helpers/decorate.js +0 -0
|
@@ -93,10 +93,20 @@ export declare class EFVideo extends EFVideo_base {
|
|
|
93
93
|
* Still used by EFCaptions - maps to unified video seek task
|
|
94
94
|
*/
|
|
95
95
|
get fragmentIndexTask(): Task<readonly [number], import('mediabunny').VideoSample | undefined>;
|
|
96
|
+
/**
|
|
97
|
+
* Helper method for tests: wait for the current frame to be ready
|
|
98
|
+
* This encapsulates the complexity of ensuring the video has updated
|
|
99
|
+
* and its frameTask has completed.
|
|
100
|
+
*
|
|
101
|
+
* @returns Promise that resolves when the frame is ready
|
|
102
|
+
*/
|
|
103
|
+
waitForFrameReady(): Promise<void>;
|
|
96
104
|
/**
|
|
97
105
|
* Clean up resources when component is disconnected
|
|
98
106
|
*/
|
|
99
107
|
disconnectedCallback(): void;
|
|
108
|
+
didBecomeRoot(): void;
|
|
109
|
+
didBecomeChild(): void;
|
|
100
110
|
}
|
|
101
111
|
declare global {
|
|
102
112
|
interface HTMLElementTagNameMap {
|
package/dist/elements/EFVideo.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.
|
|
1
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
2
|
+
import { TWMixin } from "../gui/TWMixin2.js";
|
|
2
3
|
import { withSpan, withSpanSync } from "../otel/tracingHelpers.js";
|
|
3
4
|
import { EFMedia } from "./EFMedia.js";
|
|
4
|
-
import {
|
|
5
|
+
import { updateAnimations } from "./updateAnimations.js";
|
|
5
6
|
import { DelayedLoadingState } from "../DelayedLoadingState.js";
|
|
6
7
|
import { makeScrubVideoBufferTask } from "./EFMedia/videoTasks/makeScrubVideoBufferTask.js";
|
|
7
8
|
import { makeScrubVideoInitSegmentFetchTask } from "./EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js";
|
|
@@ -125,6 +126,8 @@ var EFVideo = class EFVideo$1 extends TWMixin(EFMedia) {
|
|
|
125
126
|
span.setAttribute("aborted", true);
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
129
|
+
this.paint(this.desiredSeekTimeMs, span);
|
|
130
|
+
if (!this.parentTimegroup) updateAnimations(this);
|
|
128
131
|
const t4 = performance.now();
|
|
129
132
|
this.paint(_desiredSeekTimeMs, span);
|
|
130
133
|
const t5 = performance.now();
|
|
@@ -303,10 +306,20 @@ var EFVideo = class EFVideo$1 extends TWMixin(EFMedia) {
|
|
|
303
306
|
get fragmentIndexTask() {
|
|
304
307
|
return this.unifiedVideoSeekTask;
|
|
305
308
|
}
|
|
309
|
+
async waitForFrameReady() {
|
|
310
|
+
await this.updateComplete;
|
|
311
|
+
await this.frameTask.run();
|
|
312
|
+
}
|
|
306
313
|
disconnectedCallback() {
|
|
307
314
|
super.disconnectedCallback();
|
|
308
315
|
this.delayedLoadingState.clearAllLoading();
|
|
309
316
|
}
|
|
317
|
+
didBecomeRoot() {
|
|
318
|
+
super.didBecomeRoot();
|
|
319
|
+
}
|
|
320
|
+
didBecomeChild() {
|
|
321
|
+
super.didBecomeChild();
|
|
322
|
+
}
|
|
310
323
|
};
|
|
311
324
|
__decorate([property({
|
|
312
325
|
type: Number,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
2
|
-
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.
|
|
2
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
3
3
|
import { EFTemporal } from "./EFTemporal.js";
|
|
4
|
-
import { TargetController } from "./TargetController.js";
|
|
5
4
|
import { TWMixin } from "../gui/TWMixin2.js";
|
|
5
|
+
import { TargetController } from "./TargetController.js";
|
|
6
6
|
import { CrossUpdateController } from "./CrossUpdateController.js";
|
|
7
7
|
import { Task } from "@lit/task";
|
|
8
8
|
import { LitElement, css, html } from "lit";
|
|
@@ -271,13 +271,11 @@ var EFWaveform = class EFWaveform$1 extends EFTemporal(TWMixin(LitElement)) {
|
|
|
271
271
|
frequencyData.forEach((value, i) => {
|
|
272
272
|
const normalizedValue = Math.min(value / 255 * 2, 1);
|
|
273
273
|
const x = startX + i / (frequencyData.length - 1) * availableWidth;
|
|
274
|
-
const
|
|
275
|
-
const y = (waveHeight - barHeight) / 2;
|
|
274
|
+
const y = (waveHeight - normalizedValue * waveHeight) / 2;
|
|
276
275
|
if (i === 0) path.moveTo(x, y);
|
|
277
276
|
else {
|
|
278
277
|
const prevX = startX + (i - 1) / (frequencyData.length - 1) * availableWidth;
|
|
279
|
-
const
|
|
280
|
-
const prevY = (waveHeight - prevBarHeight) / 2;
|
|
278
|
+
const prevY = (waveHeight - Math.min((frequencyData[i - 1] ?? 0) / 255 * 2, 1) * waveHeight) / 2;
|
|
281
279
|
const xc = (prevX + x) / 2;
|
|
282
280
|
const yc = (prevY + y) / 2;
|
|
283
281
|
path.quadraticCurveTo(prevX, prevY, xc, yc);
|
|
@@ -286,13 +284,11 @@ var EFWaveform = class EFWaveform$1 extends EFTemporal(TWMixin(LitElement)) {
|
|
|
286
284
|
for (let i = frequencyData.length - 1; i >= 0; i--) {
|
|
287
285
|
const normalizedValue = Math.min((frequencyData[i] ?? 0) / 255 * 2, 1);
|
|
288
286
|
const x = startX + i / (frequencyData.length - 1) * availableWidth;
|
|
289
|
-
const
|
|
290
|
-
const y = (waveHeight + barHeight) / 2;
|
|
287
|
+
const y = (waveHeight + normalizedValue * waveHeight) / 2;
|
|
291
288
|
if (i === frequencyData.length - 1) path.lineTo(x, y);
|
|
292
289
|
else {
|
|
293
290
|
const nextX = startX + (i + 1) / (frequencyData.length - 1) * availableWidth;
|
|
294
|
-
const
|
|
295
|
-
const nextY = (waveHeight + nextBarHeight) / 2;
|
|
291
|
+
const nextY = (waveHeight + Math.min((frequencyData[i + 1] ?? 0) / 255 * 2, 1) * waveHeight) / 2;
|
|
296
292
|
const xc = (nextX + x) / 2;
|
|
297
293
|
const yc = (nextY + y) / 2;
|
|
298
294
|
path.quadraticCurveTo(nextX, nextY, xc, yc);
|
|
@@ -319,13 +315,11 @@ var EFWaveform = class EFWaveform$1 extends EFTemporal(TWMixin(LitElement)) {
|
|
|
319
315
|
frequencyData.forEach((value, i) => {
|
|
320
316
|
const normalizedValue = Math.min(value / 255 * 2, 1);
|
|
321
317
|
const x = startX + i / (frequencyData.length - 1) * availableWidth;
|
|
322
|
-
const
|
|
323
|
-
const y = (waveHeight - barHeight * 2) / 2;
|
|
318
|
+
const y = (waveHeight - normalizedValue * (waveHeight / 2) * 2) / 2;
|
|
324
319
|
if (i === 0) path.moveTo(x, y);
|
|
325
320
|
else {
|
|
326
321
|
const prevX = startX + (i - 1) / (frequencyData.length - 1) * availableWidth;
|
|
327
|
-
const
|
|
328
|
-
const prevY = (waveHeight - prevBarHeight * 2) / 2;
|
|
322
|
+
const prevY = (waveHeight - (frequencyData[i - 1] ?? 0) / 255 * (waveHeight / 2) * 2) / 2;
|
|
329
323
|
const xc = (prevX + x) / 2;
|
|
330
324
|
const yc = (prevY + y) / 2;
|
|
331
325
|
path.quadraticCurveTo(prevX, prevY, xc, yc);
|
|
@@ -334,13 +328,11 @@ var EFWaveform = class EFWaveform$1 extends EFTemporal(TWMixin(LitElement)) {
|
|
|
334
328
|
for (let i = frequencyData.length - 1; i >= 0; i--) {
|
|
335
329
|
const normalizedValue = Math.min((frequencyData[i] ?? 0) / 255 * 2, 1);
|
|
336
330
|
const x = startX + i / (frequencyData.length - 1) * availableWidth;
|
|
337
|
-
const
|
|
338
|
-
const y = (waveHeight + barHeight * 2) / 2;
|
|
331
|
+
const y = (waveHeight + normalizedValue * (waveHeight / 2) * 2) / 2;
|
|
339
332
|
if (i === frequencyData.length - 1) path.lineTo(x, y);
|
|
340
333
|
else {
|
|
341
334
|
const nextX = startX + (i + 1) / (frequencyData.length - 1) * availableWidth;
|
|
342
|
-
const
|
|
343
|
-
const nextY = (waveHeight + nextBarHeight * 2) / 2;
|
|
335
|
+
const nextY = (waveHeight + (frequencyData[i + 1] ?? 0) / 255 * (waveHeight / 2) * 2) / 2;
|
|
344
336
|
const xc = (nextX + x) / 2;
|
|
345
337
|
const yc = (nextY + y) / 2;
|
|
346
338
|
path.quadraticCurveTo(nextX, nextY, xc, yc);
|
|
@@ -31,8 +31,7 @@ var SampleBuffer = class {
|
|
|
31
31
|
const targetTimeMs = roundToMilliseconds(desiredSeekTimeMs);
|
|
32
32
|
for (const sample of currentBuffer) {
|
|
33
33
|
const sampleStartMs = roundToMilliseconds((sample.timestamp || 0) * 1e3);
|
|
34
|
-
const
|
|
35
|
-
const sampleEndMs = roundToMilliseconds(sampleStartMs + sampleDurationMs);
|
|
34
|
+
const sampleEndMs = roundToMilliseconds(sampleStartMs + roundToMilliseconds((sample.duration || 0) * 1e3));
|
|
36
35
|
if (targetTimeMs >= sampleStartMs && targetTimeMs < sampleEndMs) return sample;
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -103,6 +103,7 @@ var TargetController = class {
|
|
|
103
103
|
this.disconnectFromTarget();
|
|
104
104
|
this.host.targetElement = newTarget ?? null;
|
|
105
105
|
this.connectToTarget();
|
|
106
|
+
this.host.requestUpdate("targetElement");
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
connectToTarget() {
|
|
@@ -118,8 +119,7 @@ var TargetController = class {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
get registry() {
|
|
121
|
-
|
|
122
|
-
return getRegistry(root);
|
|
122
|
+
return getRegistry(this.host.getRootNode());
|
|
123
123
|
}
|
|
124
124
|
hostDisconnected() {
|
|
125
125
|
this.disconnectFromTarget();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EFMedia } from './EFMedia.js';
|
|
2
|
+
interface TemporalAudioHost {
|
|
3
|
+
startTimeMs: number;
|
|
4
|
+
endTimeMs: number;
|
|
5
|
+
durationMs: number;
|
|
6
|
+
getMediaElements(): EFMedia[];
|
|
7
|
+
waitForMediaDurations?(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare function renderTemporalAudio(host: TemporalAudioHost, fromMs: number, toMs: number): Promise<AudioBuffer>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
async function renderTemporalAudio(host, fromMs, toMs) {
|
|
2
|
+
const aacFrames = 48e3 * ((toMs - fromMs) / 1e3) / 1024;
|
|
3
|
+
const contextSize = Math.round(aacFrames) * 1024;
|
|
4
|
+
if (contextSize <= 0) throw new Error(`Duration must be greater than 0 when rendering audio. ${contextSize}ms`);
|
|
5
|
+
const audioContext = new OfflineAudioContext(2, contextSize, 48e3);
|
|
6
|
+
if (host.waitForMediaDurations) await host.waitForMediaDurations();
|
|
7
|
+
const abortController = new AbortController();
|
|
8
|
+
await Promise.all(host.getMediaElements().map(async (mediaElement) => {
|
|
9
|
+
if (mediaElement.mute) return;
|
|
10
|
+
const mediaStartsBeforeEnd = mediaElement.startTimeMs <= toMs;
|
|
11
|
+
const mediaEndsAfterStart = mediaElement.endTimeMs >= fromMs;
|
|
12
|
+
if (!(mediaStartsBeforeEnd && mediaEndsAfterStart)) return;
|
|
13
|
+
const mediaLocalFromMs = Math.max(0, fromMs - mediaElement.startTimeMs);
|
|
14
|
+
const mediaLocalToMs = Math.min(mediaElement.endTimeMs - mediaElement.startTimeMs, toMs - mediaElement.startTimeMs);
|
|
15
|
+
if (mediaLocalFromMs >= mediaLocalToMs) return;
|
|
16
|
+
const sourceInMs = mediaElement.sourceInMs || mediaElement.trimStartMs || 0;
|
|
17
|
+
const mediaSourceFromMs = mediaLocalFromMs + sourceInMs;
|
|
18
|
+
const mediaSourceToMs = mediaLocalToMs + sourceInMs;
|
|
19
|
+
const audio = await mediaElement.fetchAudioSpanningTime(mediaSourceFromMs, mediaSourceToMs, abortController.signal);
|
|
20
|
+
if (!audio) return;
|
|
21
|
+
const bufferSource = audioContext.createBufferSource();
|
|
22
|
+
bufferSource.buffer = await audioContext.decodeAudioData(await audio.blob.arrayBuffer());
|
|
23
|
+
bufferSource.connect(audioContext.destination);
|
|
24
|
+
const ctxStartMs = Math.max(0, mediaElement.startTimeMs - fromMs);
|
|
25
|
+
const offsetInBufferMs = mediaSourceFromMs - audio.startMs;
|
|
26
|
+
const safeOffsetMs = Math.max(0, offsetInBufferMs);
|
|
27
|
+
const requestedDurationMs = mediaSourceToMs - mediaSourceFromMs;
|
|
28
|
+
const availableAudioMs = audio.endMs - audio.startMs;
|
|
29
|
+
const actualDurationMs = Math.min(requestedDurationMs, availableAudioMs - safeOffsetMs);
|
|
30
|
+
if (actualDurationMs <= 0) return;
|
|
31
|
+
bufferSource.start(ctxStartMs / 1e3, safeOffsetMs / 1e3, actualDurationMs / 1e3);
|
|
32
|
+
}));
|
|
33
|
+
return audioContext.startRendering();
|
|
34
|
+
}
|
|
35
|
+
export { renderTemporalAudio };
|
|
@@ -5,25 +5,23 @@ var PROGRESS_PROPERTY = "--ef-progress";
|
|
|
5
5
|
var DURATION_PROPERTY = "--ef-duration";
|
|
6
6
|
var TRANSITION_DURATION_PROPERTY = "--ef-transition-duration";
|
|
7
7
|
var TRANSITION_OUT_START_PROPERTY = "--ef-transition-out-start";
|
|
8
|
-
var TIMEGROUP_TAGNAME = "ef-timegroup";
|
|
9
8
|
const evaluateTemporalState = (element) => {
|
|
10
9
|
const timelineTimeMs = (element.rootTimegroup ?? element).currentTimeMs;
|
|
11
10
|
const progress = element.durationMs <= 0 ? 1 : Math.max(0, Math.min(1, element.currentTimeMs / element.durationMs));
|
|
12
|
-
const
|
|
13
|
-
const
|
|
11
|
+
const isRootElement = !element.parentTimegroup;
|
|
12
|
+
const isLastElementInComposition = element.endTimeMs === element.rootTimegroup?.endTimeMs;
|
|
13
|
+
const useInclusiveEnd = isRootElement || isLastElementInComposition;
|
|
14
14
|
return {
|
|
15
15
|
progress,
|
|
16
|
-
isVisible,
|
|
16
|
+
isVisible: element.startTimeMs <= timelineTimeMs && (useInclusiveEnd ? element.endTimeMs >= timelineTimeMs : element.endTimeMs > timelineTimeMs),
|
|
17
17
|
timelineTimeMs
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
20
|
const evaluateTemporalStateForAnimation = (element) => {
|
|
21
21
|
const timelineTimeMs = (element.rootTimegroup ?? element).currentTimeMs;
|
|
22
|
-
const progress = element.durationMs <= 0 ? 1 : Math.max(0, Math.min(1, element.currentTimeMs / element.durationMs));
|
|
23
|
-
const isVisible = element.startTimeMs <= timelineTimeMs && element.endTimeMs >= timelineTimeMs;
|
|
24
22
|
return {
|
|
25
|
-
progress,
|
|
26
|
-
isVisible,
|
|
23
|
+
progress: element.durationMs <= 0 ? 1 : Math.max(0, Math.min(1, element.currentTimeMs / element.durationMs)),
|
|
24
|
+
isVisible: element.startTimeMs <= timelineTimeMs && element.endTimeMs >= timelineTimeMs,
|
|
27
25
|
timelineTimeMs
|
|
28
26
|
};
|
|
29
27
|
};
|
|
@@ -72,8 +70,7 @@ var coordinateAnimationsForSingleElement = (element) => {
|
|
|
72
70
|
const updateAnimations = (element) => {
|
|
73
71
|
const temporalState = evaluateTemporalState(element);
|
|
74
72
|
deepGetTemporalElements(element).forEach((temporalElement) => {
|
|
75
|
-
|
|
76
|
-
updateVisualState(temporalElement, temporalState$1);
|
|
73
|
+
updateVisualState(temporalElement, evaluateTemporalState(temporalElement));
|
|
77
74
|
});
|
|
78
75
|
updateVisualState(element, temporalState);
|
|
79
76
|
if (evaluateTemporalStateForAnimation(element).isVisible) coordinateAnimationsForSingleElement(element);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
|
-
import {
|
|
3
|
-
export declare const
|
|
4
|
-
__context__:
|
|
2
|
+
import { TemporalMixinInterface } from '../elements/EFTemporal.js';
|
|
3
|
+
export declare const targetTemporalContext: {
|
|
4
|
+
__context__: TemporalMixinInterface | null;
|
|
5
5
|
};
|
|
6
6
|
export declare class ContextMixinInterface extends LitElement {
|
|
7
7
|
signingURL?: string;
|
|
@@ -11,8 +11,8 @@ export declare class ContextMixinInterface extends LitElement {
|
|
|
11
11
|
loop: boolean;
|
|
12
12
|
currentTimeMs: number;
|
|
13
13
|
focusedElement?: HTMLElement;
|
|
14
|
-
|
|
15
|
-
play(): void
|
|
14
|
+
targetTemporal: TemporalMixinInterface | null;
|
|
15
|
+
play(): Promise<void>;
|
|
16
16
|
pause(): void;
|
|
17
17
|
}
|
|
18
18
|
export declare function isContextMixin(value: any): value is ContextMixinInterface;
|
package/dist/gui/ContextMixin.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
2
|
-
import { globalURLTokenDeduplicator } from "../transcoding/cache/URLTokenDeduplicator.js";
|
|
3
2
|
import { currentTimeContext } from "./currentTimeContext.js";
|
|
4
3
|
import { durationContext } from "./durationContext.js";
|
|
5
|
-
import {
|
|
4
|
+
import { loopContext, playingContext } from "./playingContext.js";
|
|
5
|
+
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
|
|
6
|
+
import { isEFTemporal } from "../elements/EFTemporal.js";
|
|
7
|
+
import { globalURLTokenDeduplicator } from "../transcoding/cache/URLTokenDeduplicator.js";
|
|
6
8
|
import { efConfigurationContext } from "./EFConfiguration.js";
|
|
7
9
|
import { efContext } from "./efContext.js";
|
|
8
10
|
import { fetchContext } from "./fetchContext.js";
|
|
9
11
|
import { focusContext } from "./focusContext.js";
|
|
10
12
|
import { focusedElementContext } from "./focusedElementContext.js";
|
|
11
|
-
import {
|
|
12
|
-
import { consume, createContext, provide } from "@lit/context";
|
|
13
|
+
import { ContextProvider, consume, createContext, provide } from "@lit/context";
|
|
13
14
|
import { property, state } from "lit/decorators.js";
|
|
14
|
-
const
|
|
15
|
+
const targetTemporalContext = createContext(Symbol("target-temporal"));
|
|
15
16
|
var contextMixinSymbol = Symbol("contextMixin");
|
|
16
17
|
function isContextMixin(value) {
|
|
17
18
|
return typeof value === "object" && value !== null && contextMixinSymbol in value.constructor;
|
|
@@ -23,7 +24,6 @@ function ContextMixin(superClass) {
|
|
|
23
24
|
this.efConfiguration = null;
|
|
24
25
|
this.focusContext = this;
|
|
25
26
|
this.efContext = this;
|
|
26
|
-
this.targetTimegroup = null;
|
|
27
27
|
this.durationMs = 0;
|
|
28
28
|
this.endTimeMs = 0;
|
|
29
29
|
this.fetch = async (url, init = {}) => {
|
|
@@ -53,14 +53,16 @@ function ContextMixin(superClass) {
|
|
|
53
53
|
throw error;
|
|
54
54
|
}
|
|
55
55
|
};
|
|
56
|
-
this.playing = false;
|
|
57
|
-
this.loop = false;
|
|
58
56
|
this.rendering = false;
|
|
59
|
-
this.currentTimeMs = NaN;
|
|
60
57
|
}
|
|
61
58
|
static {
|
|
62
59
|
this[contextMixinSymbol] = true;
|
|
63
60
|
}
|
|
61
|
+
#playingProvider;
|
|
62
|
+
#loopProvider;
|
|
63
|
+
#currentTimeMsProvider;
|
|
64
|
+
#targetTemporalProvider;
|
|
65
|
+
#loop = false;
|
|
64
66
|
#apiHost;
|
|
65
67
|
get apiHost() {
|
|
66
68
|
return this.#apiHost ?? this.efConfiguration?.apiHost ?? "";
|
|
@@ -68,6 +70,56 @@ function ContextMixin(superClass) {
|
|
|
68
70
|
set apiHost(value) {
|
|
69
71
|
this.#apiHost = value;
|
|
70
72
|
}
|
|
73
|
+
#targetTemporal = null;
|
|
74
|
+
get targetTemporal() {
|
|
75
|
+
return this.#targetTemporal;
|
|
76
|
+
}
|
|
77
|
+
#controllerSubscribed = false;
|
|
78
|
+
findRootTemporal() {
|
|
79
|
+
const findRecursive = (element) => {
|
|
80
|
+
if (isEFTemporal(element)) return element;
|
|
81
|
+
for (const child of element.children) {
|
|
82
|
+
const found = findRecursive(child);
|
|
83
|
+
if (found) return found;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
87
|
+
for (const child of this.children) {
|
|
88
|
+
const found = findRecursive(child);
|
|
89
|
+
if (found) return found;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
set targetTemporal(value) {
|
|
94
|
+
if (this.#targetTemporal === value) return;
|
|
95
|
+
if (this.#targetTemporal?.playbackController) {
|
|
96
|
+
this.#targetTemporal.playbackController.removeListener(this.#onControllerUpdate);
|
|
97
|
+
this.#controllerSubscribed = false;
|
|
98
|
+
}
|
|
99
|
+
this.#targetTemporal = value;
|
|
100
|
+
this.#targetTemporalProvider?.setValue(value);
|
|
101
|
+
this.requestUpdate("targetTemporal");
|
|
102
|
+
this.requestUpdate("playing");
|
|
103
|
+
this.requestUpdate("loop");
|
|
104
|
+
this.requestUpdate("currentTimeMs");
|
|
105
|
+
if (value?.playbackController && this.#loop) value.playbackController.setLoop(this.#loop);
|
|
106
|
+
if (value && !value.playbackController) value.updateComplete?.then(() => {
|
|
107
|
+
if (value === this.#targetTemporal && !this.#controllerSubscribed) this.requestUpdate();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
#onControllerUpdate = (event) => {
|
|
111
|
+
switch (event.property) {
|
|
112
|
+
case "playing":
|
|
113
|
+
this.#playingProvider.setValue(event.value);
|
|
114
|
+
break;
|
|
115
|
+
case "loop":
|
|
116
|
+
this.#loopProvider.setValue(event.value);
|
|
117
|
+
break;
|
|
118
|
+
case "currentTimeMs":
|
|
119
|
+
this.#currentTimeMsProvider.setValue(event.value);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
71
123
|
#getTokenCacheKey(url) {
|
|
72
124
|
try {
|
|
73
125
|
const urlObj = new URL(url);
|
|
@@ -120,16 +172,35 @@ function ContextMixin(superClass) {
|
|
|
120
172
|
set signingURL(value) {
|
|
121
173
|
this.#signingURL = value;
|
|
122
174
|
}
|
|
123
|
-
|
|
124
|
-
|
|
175
|
+
get playing() {
|
|
176
|
+
return this.targetTemporal?.playbackController?.playing ?? false;
|
|
177
|
+
}
|
|
178
|
+
set playing(value) {
|
|
179
|
+
if (this.targetTemporal?.playbackController) this.targetTemporal.playbackController.setPlaying(value);
|
|
180
|
+
}
|
|
181
|
+
get loop() {
|
|
182
|
+
return this.targetTemporal?.playbackController?.loop ?? this.#loop;
|
|
183
|
+
}
|
|
184
|
+
set loop(value) {
|
|
185
|
+
const oldValue = this.#loop;
|
|
186
|
+
this.#loop = value;
|
|
187
|
+
if (this.targetTemporal?.playbackController) this.targetTemporal.playbackController.setLoop(value);
|
|
188
|
+
this.requestUpdate("loop", oldValue);
|
|
189
|
+
}
|
|
190
|
+
get currentTimeMs() {
|
|
191
|
+
return this.targetTemporal?.playbackController?.currentTimeMs ?? NaN;
|
|
192
|
+
}
|
|
193
|
+
set currentTimeMs(value) {
|
|
194
|
+
if (this.targetTemporal?.playbackController) this.targetTemporal.playbackController.setCurrentTimeMs(value);
|
|
195
|
+
}
|
|
125
196
|
#timegroupObserver = new MutationObserver((mutations) => {
|
|
126
197
|
let shouldUpdate = false;
|
|
127
198
|
for (const mutation of mutations) if (mutation.type === "childList") {
|
|
128
|
-
const
|
|
129
|
-
if (
|
|
130
|
-
this.
|
|
199
|
+
const newTemporal = this.findRootTemporal();
|
|
200
|
+
if (newTemporal !== this.targetTemporal) {
|
|
201
|
+
this.targetTemporal = newTemporal;
|
|
131
202
|
shouldUpdate = true;
|
|
132
|
-
} else if (mutation.target instanceof Element && (mutation.target
|
|
203
|
+
} else if (mutation.target instanceof Element && isEFTemporal(mutation.target)) shouldUpdate = true;
|
|
133
204
|
} else if (mutation.type === "attributes") {
|
|
134
205
|
if ([
|
|
135
206
|
"duration",
|
|
@@ -138,128 +209,90 @@ function ContextMixin(superClass) {
|
|
|
138
209
|
"trimend",
|
|
139
210
|
"sourcein",
|
|
140
211
|
"sourceout"
|
|
141
|
-
].includes(mutation.attributeName || "") || mutation.target instanceof Element && (mutation.target
|
|
212
|
+
].includes(mutation.attributeName || "") || mutation.target instanceof Element && isEFTemporal(mutation.target)) shouldUpdate = true;
|
|
142
213
|
}
|
|
143
214
|
if (shouldUpdate) queueMicrotask(() => {
|
|
144
215
|
this.updateDurationProperties();
|
|
145
216
|
this.requestUpdate();
|
|
146
|
-
if (this.
|
|
217
|
+
if (this.targetTemporal) this.targetTemporal.requestUpdate();
|
|
147
218
|
});
|
|
148
219
|
});
|
|
149
220
|
updateDurationProperties() {
|
|
150
|
-
const newDuration = this.
|
|
151
|
-
const newEndTime = this.
|
|
221
|
+
const newDuration = this.targetTemporal?.durationMs ?? 0;
|
|
222
|
+
const newEndTime = this.targetTemporal?.endTimeMs ?? 0;
|
|
152
223
|
if (this.durationMs !== newDuration) this.durationMs = newDuration;
|
|
153
224
|
if (this.endTimeMs !== newEndTime) this.endTimeMs = newEndTime;
|
|
154
225
|
}
|
|
155
226
|
connectedCallback() {
|
|
156
227
|
super.connectedCallback();
|
|
157
|
-
this
|
|
228
|
+
this.#playingProvider = new ContextProvider(this, {
|
|
229
|
+
context: playingContext,
|
|
230
|
+
initialValue: this.playing
|
|
231
|
+
});
|
|
232
|
+
this.#loopProvider = new ContextProvider(this, {
|
|
233
|
+
context: loopContext,
|
|
234
|
+
initialValue: this.loop
|
|
235
|
+
});
|
|
236
|
+
this.#currentTimeMsProvider = new ContextProvider(this, {
|
|
237
|
+
context: currentTimeContext,
|
|
238
|
+
initialValue: this.currentTimeMs
|
|
239
|
+
});
|
|
240
|
+
this.#targetTemporalProvider = new ContextProvider(this, {
|
|
241
|
+
context: targetTemporalContext,
|
|
242
|
+
initialValue: this.targetTemporal
|
|
243
|
+
});
|
|
244
|
+
this.targetTemporal = this.findRootTemporal();
|
|
158
245
|
this.updateDurationProperties();
|
|
159
246
|
this.#timegroupObserver.observe(this, {
|
|
160
247
|
childList: true,
|
|
161
248
|
subtree: true,
|
|
162
249
|
attributes: true
|
|
163
250
|
});
|
|
164
|
-
if (this.playing) this.startPlayback();
|
|
165
251
|
}
|
|
166
252
|
disconnectedCallback() {
|
|
167
253
|
super.disconnectedCallback();
|
|
168
254
|
this.#timegroupObserver.disconnect();
|
|
169
|
-
this
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (changedProperties.has("playing")) if (this.playing) this.startPlayback();
|
|
173
|
-
else this.stopPlayback();
|
|
174
|
-
if (changedProperties.has("currentTimeMs") && this.targetTimegroup && !Number.isNaN(this.currentTimeMs)) {
|
|
175
|
-
if (this.targetTimegroup.currentTimeMs !== this.currentTimeMs) {
|
|
176
|
-
if (this.isConnected) {
|
|
177
|
-
if (this.targetTimegroup.currentTimeMs === this.currentTimeMs) return;
|
|
178
|
-
this.targetTimegroup.currentTimeMs = this.currentTimeMs;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
255
|
+
if (this.#targetTemporal?.playbackController) {
|
|
256
|
+
this.#targetTemporal.playbackController.removeListener(this.#onControllerUpdate);
|
|
257
|
+
this.#controllerSubscribed = false;
|
|
181
258
|
}
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
play() {
|
|
185
|
-
this.playing = true;
|
|
259
|
+
this.pause();
|
|
186
260
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (nextTimeMs !== this.currentTimeMs) this.currentTimeMs = nextTimeMs;
|
|
197
|
-
this.#playbackAnimationFrameRequest = requestAnimationFrame(() => {
|
|
198
|
-
this.#syncPlayheadToAudioContext(target, startMs);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
async stopPlayback() {
|
|
202
|
-
if (this.#playbackAudioContext) {
|
|
203
|
-
if (this.#playbackAudioContext.state !== "closed") await this.#playbackAudioContext.close();
|
|
261
|
+
updated(changedProperties) {
|
|
262
|
+
super.updated?.(changedProperties);
|
|
263
|
+
if (!this.#controllerSubscribed && this.#targetTemporal?.playbackController) {
|
|
264
|
+
this.#targetTemporal.playbackController.addListener(this.#onControllerUpdate);
|
|
265
|
+
this.#controllerSubscribed = true;
|
|
266
|
+
if (this.#loop) this.#targetTemporal.playbackController.setLoop(this.#loop);
|
|
267
|
+
this.#playingProvider.setValue(this.playing);
|
|
268
|
+
this.#loopProvider.setValue(this.loop);
|
|
269
|
+
this.#currentTimeMsProvider.setValue(this.currentTimeMs);
|
|
204
270
|
}
|
|
205
|
-
if (this.#playbackAnimationFrameRequest) cancelAnimationFrame(this.#playbackAnimationFrameRequest);
|
|
206
|
-
this.#playbackAudioContext = null;
|
|
207
|
-
this.#playbackAnimationFrameRequest = null;
|
|
208
271
|
}
|
|
209
|
-
async
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
272
|
+
async play() {
|
|
273
|
+
if (!this.targetTemporal) {
|
|
274
|
+
const potentialTemporalTags = Array.from(this.children).map((el) => el.tagName.toLowerCase()).filter((tag) => tag.startsWith("ef-"));
|
|
275
|
+
await Promise.all(potentialTemporalTags.map((tag) => customElements.whenDefined(tag).catch(() => {})));
|
|
276
|
+
const foundTemporal = this.findRootTemporal();
|
|
277
|
+
if (foundTemporal) {
|
|
278
|
+
this.targetTemporal = foundTemporal;
|
|
279
|
+
await foundTemporal.updateComplete;
|
|
280
|
+
} else {
|
|
281
|
+
console.warn("No temporal element found to play");
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
220
284
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
console.warn("AudioContext is suspended, media playback will not work until user has interacted with page.");
|
|
228
|
-
this.playing = false;
|
|
229
|
-
return;
|
|
285
|
+
if (!this.targetTemporal.playbackController) {
|
|
286
|
+
await this.targetTemporal.updateComplete;
|
|
287
|
+
if (!this.targetTemporal.playbackController) {
|
|
288
|
+
console.warn("PlaybackController not available for temporal element");
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
230
291
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
};
|
|
236
|
-
const queueBufferSource = async () => {
|
|
237
|
-
if (currentMs >= toMs) return false;
|
|
238
|
-
const startMs = currentMs;
|
|
239
|
-
const endMs = currentMs + this.#AUDIO_PLAYBACK_SLICE_MS;
|
|
240
|
-
currentMs += this.#AUDIO_PLAYBACK_SLICE_MS;
|
|
241
|
-
const audioBuffer = await timegroup.renderAudio(startMs, endMs);
|
|
242
|
-
bufferCount++;
|
|
243
|
-
const source = playbackContext.createBufferSource();
|
|
244
|
-
source.buffer = audioBuffer;
|
|
245
|
-
source.connect(playbackContext.destination);
|
|
246
|
-
source.start((startMs - fromMs) / 1e3);
|
|
247
|
-
source.onended = () => {
|
|
248
|
-
bufferCount--;
|
|
249
|
-
if (endMs >= toMs) {
|
|
250
|
-
this.pause();
|
|
251
|
-
if (this.loop) this.updateComplete.then(() => {
|
|
252
|
-
this.currentTimeMs = 0;
|
|
253
|
-
this.updateComplete.then(() => {
|
|
254
|
-
this.play();
|
|
255
|
-
});
|
|
256
|
-
});
|
|
257
|
-
} else fillBuffer();
|
|
258
|
-
};
|
|
259
|
-
return true;
|
|
260
|
-
};
|
|
261
|
-
await fillBuffer();
|
|
262
|
-
await playbackContext.resume();
|
|
292
|
+
this.targetTemporal.playbackController.play();
|
|
293
|
+
}
|
|
294
|
+
pause() {
|
|
295
|
+
if (this.targetTemporal?.playbackController) this.targetTemporal.playbackController.pause();
|
|
263
296
|
}
|
|
264
297
|
}
|
|
265
298
|
__decorate([consume({
|
|
@@ -273,7 +306,7 @@ function ContextMixin(superClass) {
|
|
|
273
306
|
attribute: "api-host"
|
|
274
307
|
})], ContextElement.prototype, "apiHost", null);
|
|
275
308
|
__decorate([provide({ context: efContext })], ContextElement.prototype, "efContext", void 0);
|
|
276
|
-
__decorate([
|
|
309
|
+
__decorate([state()], ContextElement.prototype, "targetTemporal", null);
|
|
277
310
|
__decorate([provide({ context: durationContext }), property({ type: Number })], ContextElement.prototype, "durationMs", void 0);
|
|
278
311
|
__decorate([property({ type: Number })], ContextElement.prototype, "endTimeMs", void 0);
|
|
279
312
|
__decorate([provide({ context: fetchContext })], ContextElement.prototype, "fetch", void 0);
|
|
@@ -281,16 +314,17 @@ function ContextMixin(superClass) {
|
|
|
281
314
|
type: String,
|
|
282
315
|
attribute: "signing-url"
|
|
283
316
|
})], ContextElement.prototype, "signingURL", null);
|
|
284
|
-
__decorate([
|
|
317
|
+
__decorate([property({
|
|
285
318
|
type: Boolean,
|
|
286
319
|
reflect: true
|
|
287
|
-
})], ContextElement.prototype, "playing",
|
|
288
|
-
__decorate([
|
|
320
|
+
})], ContextElement.prototype, "playing", null);
|
|
321
|
+
__decorate([property({
|
|
289
322
|
type: Boolean,
|
|
290
|
-
reflect: true
|
|
291
|
-
|
|
323
|
+
reflect: true,
|
|
324
|
+
attribute: "loop"
|
|
325
|
+
})], ContextElement.prototype, "loop", null);
|
|
292
326
|
__decorate([property({ type: Boolean })], ContextElement.prototype, "rendering", void 0);
|
|
293
|
-
__decorate([
|
|
327
|
+
__decorate([property({ type: Number })], ContextElement.prototype, "currentTimeMs", null);
|
|
294
328
|
return ContextElement;
|
|
295
329
|
}
|
|
296
|
-
export { ContextMixin, isContextMixin,
|
|
330
|
+
export { ContextMixin, isContextMixin, targetTemporalContext };
|
|
File without changes
|