PageSourceSearch

https://jasongzy-make-it-animatable-v2.hf.space/assets/VideoPreview-DqE2DF2X.js

js jasongzy-make-it-animatable-v2.hf.space collected 2026-10-03 17:01:02 UTC 31,456 bytes, 1,242 lines download raw bytes

1import { p as prop, i as if_block, k as each, a as set_attribute, u as index, f as set_style, b as set_class, t as remove_input_defaults, d as bind_this, F as set_value } from './i18n-dpAHICcw.js';
2import { ak as delegate, R as push, u as state, v as proxy, y as user_effect, w as get, ab as onMount, af as onDestroy, V as child, Y as reset, a as append, T as pop, a5 as user_derived, x as set, X as sibling, t as template_effect, Z as event, W as from_html, S as first_child, a0 as set_text, a6 as comment, av as prepare_files, N as tick } from './index-CDZuCcOm.js';
3import { k as key } from './key-BkIRB637.js';
4import { I as IconButton, V as Video$1 } from './ScrollFade.svelte_svelte_type_style_lang-DUvCSfRk.js';
5import './MarkdownCode.svelte_svelte_type_style_lang-GeNUGzep.js';
6import { B as BlockLabel } from './BlockLabel-D4yjUUAn.js';
7import { D as DownloadLink } from './DownloadLink-CmpyjDGR.js';
8import { E as Empty } from './Empty-617iGDfy.js';
9import { S as ShareButton } from './ShareButton-c5E0ChlI.js';
10import { D as Download } from './Download-bn1Yc3QR.js';
11import { I as IconButtonWrapper } from './IconButtonWrapper-KjCt2Pl8.js';
12import { f as format_time, u as uploadToHuggingFace } from './utils.svelte-CyWLYi-B.js';
13import { M as Maximize } from './Maximize-CNFXHhlb.js';
14import { T as Trim, V as VolumeLevels, P as Pause } from './VolumeLevels-B3gQy5XO.js';
15import { P as Play } from './Play-BtgJXiAa.js';
16import { U as Undo } from './Undo-BTdg4xEQ.js';
17import { b as loadFfmpeg, t as trimVideo, V as Video } from './Video-BadoRrLY.js';
18import './Upload-BlCAnBIo.js';
19import { M as ModifyUpload } from './ModifyUpload-iCnymq9K.js';
20
21var root_1$2 = from_html(`<div class="load-wrap svelte-mctcyk"><span aria-label="loading timeline" class="loader svelte-mctcyk"></span></div>`);
22var root_3$2 = from_html(`<img draggable="false" class="svelte-mctcyk"/>`);
23var root_2$2 = from_html(`<div id="timeline" class="thumbnail-wrapper svelte-mctcyk"><button aria-label="start drag handle for trimming video" class="handle left svelte-mctcyk"></button> <div class="opaque-layer svelte-mctcyk"></div> <!> <button aria-label="end drag handle for trimming video" class="handle right svelte-mctcyk"></button></div>`);
24var root$3 = from_html(`<div class="container svelte-mctcyk"><!></div>`);
25
26function VideoTimeline($$anchor, $$props) {
27	push($$props, true);
28
29	let videoElement = prop($$props, 'videoElement', 7),
30		trimmedDuration = prop($$props, 'trimmedDuration', 15, null),
31		dragStart = prop($$props, 'dragStart', 15, 0),
32		dragEnd = prop($$props, 'dragEnd', 15, 0),
33		loadingTimeline = prop($$props, 'loadingTimeline', 15, false);
34
35	let thumbnails = state(proxy([]));
36	let numberOfThumbnails = 10;
37	let videoDuration;
38	let leftHandlePosition = state(0);
39	let rightHandlePosition = state(100);
40	let dragging = state(null);
41
42	const startDragging = (side) => {
43		set(dragging, side, true);
44	};
45
46	let loadingTimelineValue = user_derived(() => get(thumbnails).length !== numberOfThumbnails);
47
48	user_effect(() => {
49		loadingTimeline(get(loadingTimelineValue));
50	});
51
52	const stopDragging = () => {
53		set(dragging, null);
54	};
55
56	const drag = (event, distance) => {
57		if (get(dragging)) {
58			const timeline = document.getElementById("timeline");
59
60			if (!timeline) return;
61
62			const rect = timeline.getBoundingClientRect();
63			let newPercentage = (event.clientX - rect.left) / rect.width * 100;
64
65			if (distance) {
66				// Move handle based on arrow key press
67				newPercentage = get(dragging) === "left"
68					? get(leftHandlePosition) + distance
69					: get(rightHandlePosition) + distance;
70			} else {
71				// Move handle based on mouse drag
72				newPercentage = (event.clientX - rect.left) / rect.width * 100;
73			}
74
75			newPercentage = Math.max(0, Math.min(newPercentage, 100)); // Keep within 0 and 100
76
77			if (get(dragging) === "left") {
78				set(leftHandlePosition, Math.min(newPercentage, get(rightHandlePosition)), true);
79
80				// Calculate the new time and set it for the videoElement
81				const newTimeLeft = get(leftHandlePosition) / 100 * videoDuration;
82
83				videoElement().currentTime = newTimeLeft;
84				dragStart(newTimeLeft);
85			} else if (get(dragging) === "right") {
86				set(rightHandlePosition, Math.max(newPercentage, get(leftHandlePosition)), true);
87
88				const newTimeRight = get(rightHandlePosition) / 100 * videoDuration;
89
90				videoElement().currentTime = newTimeRight;
91				dragEnd(newTimeRight);
92			}
93
94			const startTime = get(leftHandlePosition) / 100 * videoDuration;
95			const endTime = get(rightHandlePosition) / 100 * videoDuration;
96
97			trimmedDuration(endTime - startTime);
98			set(leftHandlePosition, get(leftHandlePosition), true);
99			set(rightHandlePosition, get(rightHandlePosition), true);
100		}
101	};
102
103	const moveHandle = (e) => {
104		if (get(dragging)) {
105			// Calculate the movement distance as a percentage of the video duration
106			const distance = 1 / videoDuration * 100;
107
108			if (e.key === "ArrowLeft") {
109				drag({ clientX: 0 }, -distance);
110			} else if (e.key === "ArrowRight") {
111				drag({ clientX: 0 }, distance);
112			}
113		}
114	};
115
116	const generateThumbnail = () => {
117		const canvas = document.createElement("canvas");
118		const ctx = canvas.getContext("2d");
119
120		if (!ctx) return;
121
122		canvas.width = videoElement().videoWidth;
123		canvas.height = videoElement().videoHeight;
124		ctx.drawImage(videoElement(), 0, 0, canvas.width, canvas.height);
125
126		const thumbnail = canvas.toDataURL("image/jpeg", 0.7);
127
128		set(thumbnails, [...get(thumbnails), thumbnail], true);
129	};
130
131	onMount(() => {
132		const loadMetadata = () => {
133			videoDuration = videoElement().duration;
134
135			const interval = videoDuration / numberOfThumbnails;
136			let captures = 0;
137
138			const onSeeked = () => {
139				generateThumbnail();
140				captures++;
141
142				if (captures < numberOfThumbnails) {
143					videoElement().currentTime += interval;
144				} else {
145					videoElement().removeEventListener("seeked", onSeeked);
146				}
147			};
148
149			videoElement().addEventListener("seeked", onSeeked);
150			videoElement().currentTime = 0;
151		};
152
153		if (videoElement().readyState >= 1) {
154			loadMetadata();
155		} else {
156			videoElement().addEventListener("loadedmetadata", loadMetadata);
157		}
158	});
159
160	onDestroy(() => {
161		window.removeEventListener("mousemove", drag);
162		window.removeEventListener("mouseup", stopDragging);
163		window.removeEventListener("keydown", moveHandle);
164	});
165
166	onMount(() => {
167		window.addEventListener("mousemove", drag);
168		window.addEventListener("mouseup", stopDragging);
169		window.addEventListener("keydown", moveHandle);
170	});
171
172	var div = root$3();
173	var node = child(div);
174
175	{
176		var consequent = ($$anchor) => {
177			var div_1 = root_1$2();
178
179			append($$anchor, div_1);
180		};
181
182		var alternate = ($$anchor) => {
183			var div_2 = root_2$2();
184			var button = child(div_2);
185
186			button.__mousedown = () => startDragging("left");
187
188			button.__keydown = (e) => {
189				if (e.key === "ArrowLeft" || e.key == "ArrowRight") {
190					startDragging("left");
191				}
192			};
193
194			var div_3 = sibling(button, 2);
195			var node_1 = sibling(div_3, 2);
196
197			each(node_1, 17, () => get(thumbnails), index, ($$anchor, thumbnail, i) => {
198				var img = root_3$2();
199
200				set_attribute(img, 'alt', `frame-${i}`);
201				template_effect(() => set_attribute(img, 'src', get(thumbnail)));
202				append($$anchor, img);
203			});
204
205			var button_1 = sibling(node_1, 2);
206
207			button_1.__mousedown = () => startDragging("right");
208
209			button_1.__keydown = (e) => {
210				if (e.key === "ArrowLeft" || e.key == "ArrowRight") {
211					startDragging("right");
212				}
213			};
214
215			reset(div_2);
216
217			template_effect(() => {
218				set_style(button, `left: ${get(leftHandlePosition) ?? ''}%;`);
219				set_style(div_3, `left: ${get(leftHandlePosition) ?? ''}%; right: ${100 - get(rightHandlePosition)}%`);
220				set_style(button_1, `left: ${get(rightHandlePosition) ?? ''}%;`);
221			});
222
223			event('blur', button, stopDragging);
224			event('blur', button_1, stopDragging);
225			append($$anchor, div_2);
226		};
227
228		if_block(node, ($$render) => {
229			if (get(loadingTimelineValue)) $$render(consequent); else $$render(alternate, false);
230		});
231	}
232
233	reset(div);
234	append($$anchor, div);
235	pop();
236}
237
238delegate(['mousedown', 'keydown']);
239
240var root_1$1 = from_html(`<div class="timeline-wrapper svelte-1orxdv"><!></div>`);
241var root_2$1 = from_html(`<time aria-label="duration of selected region in seconds"> </time> <div class="edit-buttons svelte-1orxdv"><button>Trim</button> <button>Cancel</button></div>`, 1);
242var root_3$1 = from_html(`<div class="svelte-1orxdv"></div>`);
243var root_4 = from_html(`<!> <!>`, 1);
244var root$2 = from_html(`<div><!> <div class="controls svelte-1orxdv" data-testid="waveform-controls"><!></div></div> <!>`, 1);
245
246function VideoControls($$anchor, $$props) {
247	push($$props, true);
248
249	let videoElement = prop($$props, 'videoElement', 3, undefined),
250		showRedo = prop($$props, 'showRedo', 3, false),
251		interactive = prop($$props, 'interactive', 3, true),
252		mode = prop($$props, 'mode', 15, ""),
253		processingVideo = prop($$props, 'processingVideo', 15, false),
254		value = prop($$props, 'value', 3, null),
255		show_download_button = prop($$props, 'show_download_button', 3, false),
256		handle_clear = prop($$props, 'handle_clear', 3, () => {}),
257		has_change_history = prop($$props, 'has_change_history', 3, false);
258
259	let ffmpeg;
260
261	onMount(async () => {
262		ffmpeg = await loadFfmpeg();
263	});
264
265	user_effect(() => {
266		if (mode() === "edit" && get(trimmedDuration) === null && videoElement()) {
267			set(trimmedDuration, videoElement().duration, true);
268		}
269	});
270
271	let trimmedDuration = state(null);
272	let dragStart = state(0);
273	let dragEnd = state(0);
274	let loadingTimeline = state(false);
275
276	const toggleTrimmingMode = () => {
277		if (mode() === "edit") {
278			mode("");
279
280			if (videoElement()) {
281				set(trimmedDuration, videoElement().duration, true);
282			}
283		} else {
284			mode("edit");
285		}
286	};
287
288	var fragment = root$2();
289	var div = first_child(fragment);
290	let classes;
291	var node = child(div);
292
293	{
294		var consequent = ($$anchor) => {
295			var div_1 = root_1$1();
296			var node_1 = child(div_1);
297
298			VideoTimeline(node_1, {
299				get videoElement() {
300					return videoElement();
301				},
302
303				get dragStart() {
304					return get(dragStart);
305				},
306
307				set dragStart($$value) {
308					set(dragStart, $$value, true);
309				},
310
311				get dragEnd() {
312					return get(dragEnd);
313				},
314
315				set dragEnd($$value) {
316					set(dragEnd, $$value, true);
317				},
318
319				get trimmedDuration() {
320					return get(trimmedDuration);
321				},
322
323				set trimmedDuration($$value) {
324					set(trimmedDuration, $$value, true);
325				},
326
327				get loadingTimeline() {
328					return get(loadingTimeline);
329				},
330
331				set loadingTimeline($$value) {
332					set(loadingTimeline, $$value, true);
333				}
334			});
335
336			reset(div_1);
337			append($$anchor, div_1);
338		};
339
340		if_block(node, ($$render) => {
341			if (mode() === "edit" && videoElement()) $$render(consequent);
342		});
343	}
344
345	var div_2 = sibling(node, 2);
346	var node_2 = child(div_2);
347
348	{
349		var consequent_1 = ($$anchor) => {
350			var fragment_1 = root_2$1();
351			var time = first_child(fragment_1);
352			let classes_1;
353			var text = child(time, true);
354
355			reset(time);
356
357			var div_3 = sibling(time, 2);
358			var button = child(div_3);
359			let classes_2;
360
361			button.__click = () => {
362				if (!videoElement()) return;
363
364				mode("");
365				processingVideo(true);
366
367				trimVideo(ffmpeg, get(dragStart), get(dragEnd), videoElement()).then((videoBlob) => {
368					$$props.handle_trim_video(videoBlob);
369				}).then(() => {
370					processingVideo(false);
371				});
372			};
373
374			var button_1 = sibling(button, 2);
375			let classes_3;
376
377			button_1.__click = toggleTrimmingMode;
378			reset(div_3);
379
380			template_effect(
381				($0) => {
382					classes_1 = set_class(time, 1, 'svelte-1orxdv', null, classes_1, { hidden: get(loadingTimeline) });
383					set_text(text, $0);
384					classes_2 = set_class(button, 1, 'text-button svelte-1orxdv', null, classes_2, { hidden: get(loadingTimeline) });
385					classes_3 = set_class(button_1, 1, 'text-button svelte-1orxdv', null, classes_3, { hidden: get(loadingTimeline) });
386				},
387				[() => format_time(get(trimmedDuration))]
388			);
389
390			append($$anchor, fragment_1);
391		};
392
393		var alternate = ($$anchor) => {
394			var div_4 = root_3$1();
395
396			append($$anchor, div_4);
397		};
398
399		if_block(node_2, ($$render) => {
400			if (mode() === "edit" && get(trimmedDuration) !== null) $$render(consequent_1); else $$render(alternate, false);
401		});
402	}
403
404	reset(div_2);
405	reset(div);
406
407	var node_3 = sibling(div, 2);
408
409	{
410		let $0 = user_derived(() => show_download_button() ? value()?.url : null);
411
412		ModifyUpload(node_3, {
413			get i18n() {
414				return $$props.i18n;
415			},
416			onclear: () => handle_clear()(),
417			get download() {
418				return get($0);
419			},
420
421			children: ($$anchor, $$slotProps) => {
422				var fragment_2 = root_4();
423				var node_4 = first_child(fragment_2);
424
425				{
426					var consequent_2 = ($$anchor) => {
427						{
428							let $0 = user_derived(() => processingVideo() || !has_change_history());
429
430							IconButton($$anchor, {
431								get Icon() {
432									return Undo;
433								},
434								label: 'Reset video to initial value',
435								get disabled() {
436									return get($0);
437								},
438
439								onclick: () => {
440									$$props.handle_reset_value();
441									mode("");
442								}
443							});
444						}
445					};
446
447					if_block(node_4, ($$render) => {
448						if (showRedo() && mode() === "") $$render(consequent_2);
449					});
450				}
451
452				var node_5 = sibling(node_4, 2);
453
454				{
455					var consequent_3 = ($$anchor) => {
456						IconButton($$anchor, {
457							get Icon() {
458								return Trim;
459							},
460							label: 'Trim video to selection',
461							get disabled() {
462								return processingVideo();
463							},
464							onclick: toggleTrimmingMode
465						});
466					};
467
468					if_block(node_5, ($$render) => {
469						if (interactive() && mode() === "") $$render(consequent_3);
470					});
471				}
472
473				append($$anchor, fragment_2);
474			},
475			$$slots: { default: true }
476		});
477	}
478
479	template_effect(() => classes = set_class(div, 1, 'container svelte-1orxdv', null, classes, { hidden: mode() !== "edit" }));
480	append($$anchor, fragment);
481	pop();
482}
483
484delegate(['click']);
485
486var root$1 = from_html(`<input id="volume" class="volume-slider svelte-h4x5cd" type="range" min="0" max="1" step="0.01"/>`);
487
488function VolumeControl($$anchor, $$props) {
489	push($$props, true);
490
491	let current_volume = prop($$props, 'current_volume', 15, 1),
492		show_volume_slider = prop($$props, 'show_volume_slider', 15, false);
493
494	let volume_element = state(void 0);
495
496	onMount(() => {
497		adjustSlider();
498	});
499
500	const adjustSlider = () => {
501		let slider = get(volume_element);
502
503		if (!slider) return;
504
505		slider.style.background = `linear-gradient(to right, white ${current_volume() * 100}%, rgba(255, 255, 255, 0.3) ${current_volume() * 100}%)`;
506	};
507
508	user_effect(() => {
509		current_volume();
510		adjustSlider();
511	});
512
513	var input = root$1();
514
515	remove_input_defaults(input);
516	input.__focusout = () => show_volume_slider(false);
517
518	input.__input = (e) => {
519		if (e.target instanceof HTMLInputElement) {
520			current_volume(parseFloat(e.target.value));
521		}
522	};
523
524	bind_this(input, ($$value) => set(volume_element, $$value), () => get(volume_element));
525	template_effect(() => set_value(input, current_volume()));
526	append($$anchor, input);
527	pop();
528}
529
530delegate(['focusout', 'input']);
531
532var root_2 = from_html(`<track kind="captions" default/>`);
533var root_8 = from_html(`<div role="button" tabindex="0" class="icon svelte-1k28h7x" aria-label="full-screen"><!></div>`);
534var root_1 = from_html(`<div class="wrap svelte-1k28h7x"><div><!></div> <div class="controls svelte-1k28h7x"><div class="inner svelte-1k28h7x"><span role="button" tabindex="0" class="icon svelte-1k28h7x" aria-label="play-pause-replay-button"><!></span> <span class="time svelte-1k28h7x"> </span>  <progress class="svelte-1k28h7x"></progress> <div class="volume-control-wrapper svelte-1k28h7x"><button class="icon volume-button svelte-1k28h7x" aria-label="Adjust volume"><!></button> <!></div> <!></div></div></div> <!>`, 1);
535
536function Player($$anchor, $$props) {
537	push($$props, true);
538
539	let root = prop($$props, 'root', 3, ""),
540		subtitle = prop($$props, 'subtitle', 3, null),
541		label = prop($$props, 'label', 3, "test"),
542		interactive = prop($$props, 'interactive', 3, false),
543		handle_change = prop($$props, 'handle_change', 3, () => {}),
544		handle_reset_value = prop($$props, 'handle_reset_value', 3, () => {}),
545		is_stream = prop($$props, 'is_stream', 3, undefined),
546		show_download_button = prop($$props, 'show_download_button', 3, false),
547		value = prop($$props, 'value', 3, null),
548		handle_clear = prop($$props, 'handle_clear', 3, () => {}),
549		has_change_history = prop($$props, 'has_change_history', 3, false),
550		playback_position = prop($$props, 'playback_position', 15);
551
552	let time = state(0);
553	let duration = state(0);
554	let paused = state(true);
555	let video = state(void 0);
556	let processingVideo = state(false);
557	let show_volume_slider = state(false);
558	let current_volume = state(1);
559	let is_fullscreen = state(false);
560
561	function handleMove(e) {
562		if (!get(duration)) return;
563
564		if (e.type === "click") {
565			handle_click(e);
566
567			return;
568		}
569
570		if (e.type !== "touchmove" && !(e.buttons & 1)) return;
571
572		const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
573		const { left, right } = e.currentTarget.getBoundingClientRect();
574
575		set(time, get(duration) * (clientX - left) / (right - left));
576	}
577
578	async function play_pause() {
579		if (!get(video)) return;
580
581		if (document.fullscreenElement != get(video)) {
582			const isPlaying = get(video).currentTime > 0 && !get(video).paused && !get(video).ended && get(video).readyState > get(video).HAVE_CURRENT_DATA;
583
584			if (!isPlaying) {
585				await get(video).play();
586			} else get(video).pause();
587		}
588	}
589
590	function handle_click(e) {
591		if (!get(duration)) return;
592
593		const { left, right } = e.currentTarget.getBoundingClientRect();
594
595		set(time, get(duration) * (e.clientX - left) / (right - left));
596	}
597
598	function handle_end() {
599		$$props.onstop?.();
600		$$props.onend?.();
601	}
602
603	const handle_trim_video = async (videoBlob) => {
604		let _video_blob = new File([videoBlob], "video.mp4");
605		const val = await prepare_files([_video_blob]);
606		let value = (await $$props.upload(val, root()))?.filter(Boolean)[0];
607
608		handle_change()(value);
609	};
610
611	function open_full_screen() {
612		if (!get(video)) return;
613
614		if (!get(is_fullscreen)) {
615			get(video).requestFullscreen();
616		} else {
617			document.exitFullscreen();
618		}
619	}
620
621	function handleFullscreenChange() {
622		set(is_fullscreen, document.fullscreenElement === get(video));
623
624		if (get(video)) {
625			get(video).controls = get(is_fullscreen);
626		}
627	}
628
629	let last_synced_volume = 1;
630	let previous_video;
631
632	// Tolerance for floating-point comparison of volume values
633	const VOLUME_EPSILON = 0.001;
634
635	function handleVolumeChange() {
636		if (get(video) && Math.abs(get(video).volume - last_synced_volume) > VOLUME_EPSILON) {
637			set(current_volume, get(video).volume, true);
638			last_synced_volume = get(video).volume;
639		}
640	}
641
642	onMount(() => {
643		document.addEventListener("fullscreenchange", handleFullscreenChange);
644
645		return () => {
646			document.removeEventListener("fullscreenchange", handleFullscreenChange);
647		};
648	});
649
650	onDestroy(() => {
651		if (get(video)) {
652			get(video).removeEventListener("volumechange", handleVolumeChange);
653		}
654	});
655
656	user_effect(() => {
657		if (get(video) && get(video) !== previous_video) {
658			if (previous_video) {
659				previous_video.removeEventListener("volumechange", handleVolumeChange);
660			}
661
662			get(video).addEventListener("volumechange", handleVolumeChange);
663			previous_video = get(video);
664		}
665	});
666
667	user_effect(() => {
668		playback_position(get(time));
669	});
670
671	user_effect(() => {
672		if (playback_position() !== get(time) && get(video)) {
673			get(video).currentTime = playback_position();
674		}
675	});
676
677	user_effect(() => {
678		if (get(video) && !get(is_fullscreen)) {
679			if (Math.abs(get(video).volume - get(current_volume)) > VOLUME_EPSILON) {
680				get(video).volume = get(current_volume);
681				last_synced_volume = get(current_volume);
682			}
683
684			get(video).controls = false;
685		}
686	});
687
688	user_effect(() => {
689		if (get(video) && get(is_fullscreen)) {
690			last_synced_volume = get(video).volume;
691		}
692	});
693
694	var fragment = root_1();
695	var div = first_child(fragment);
696	var div_1 = child(div);
697	let classes;
698	var node = child(div_1);
699
700	{
701		let $0 = user_derived(() => `${label()}-player`);
702
703		Video(node, {
704			get src() {
705				return $$props.src;
706			},
707			preload: 'auto',
708			get autoplay() {
709				return $$props.autoplay;
710			},
711
712			get loop() {
713				return $$props.loop;
714			},
715
716			get is_stream() {
717				return is_stream();
718			},
719
720			get controls() {
721				return get(is_fullscreen);
722			},
723			onclick: play_pause,
724			onplay: () => $$props.onplay?.(),
725			onpause: () => $$props.onpause?.(),
726			onerror: (error) => $$props.onerror?.(error),
727			onended: handle_end,
728			get 'data-testid'() {
729				return get($0);
730			},
731
732			get processingVideo() {
733				return get(processingVideo);
734			},
735			onloadstart: () => $$props.onloadstart?.(),
736			onloadeddata: () => $$props.onloadeddata?.(),
737			onloadedmetadata: () => $$props.onloadedmetadata?.(),
738			get currentTime() {
739				return get(time);
740			},
741
742			set currentTime($$value) {
743				set(time, $$value, true);
744			},
745
746			get duration() {
747				return get(duration);
748			},
749
750			set duration($$value) {
751				set(duration, $$value, true);
752			},
753
754			get paused() {
755				return get(paused);
756			},
757
758			set paused($$value) {
759				set(paused, $$value, true);
760			},
761
762			get node() {
763				return get(video);
764			},
765
766			set node($$value) {
767				set(video, $$value, true);
768			},
769
770			children: ($$anchor, $$slotProps) => {
771				var track = root_2();
772
773				template_effect(() => set_attribute(track, 'src', subtitle()));
774				append($$anchor, track);
775			},
776			$$slots: { default: true }
777		});
778	}
779
780	reset(div_1);
781
782	var div_2 = sibling(div_1, 2);
783	var div_3 = child(div_2);
784	var span = child(div_3);
785
786	span.__click = play_pause;
787	span.__keydown = play_pause;
788
789	var node_1 = child(span);
790
791	{
792		var consequent = ($$anchor) => {
793			Undo($$anchor);
794		};
795
796		var alternate_1 = ($$anchor) => {
797			var fragment_2 = comment();
798			var node_2 = first_child(fragment_2);
799
800			{
801				var consequent_1 = ($$anchor) => {
802					Play($$anchor);
803				};
804
805				var alternate = ($$anchor) => {
806					Pause($$anchor);
807				};
808
809				if_block(
810					node_2,
811					($$render) => {
812						if (get(paused)) $$render(consequent_1); else $$render(alternate, false);
813					},
814					true
815				);
816			}
817
818			append($$anchor, fragment_2);
819		};
820
821		if_block(node_1, ($$render) => {
822			if (get(time) === get(duration)) $$render(consequent); else $$render(alternate_1, false);
823		});
824	}
825
826	reset(span);
827
828	var span_1 = sibling(span, 2);
829	var text = child(span_1);
830
831	reset(span_1);
832
833	var progress = sibling(span_1, 2);
834
835	progress.__mousemove = handleMove;
836
837	progress.__touchmove = (e) => {
838		e.preventDefault();
839		handleMove(e);
840	};
841
842	progress.__click = (e) => {
843		e.stopPropagation();
844		e.preventDefault();
845		handle_click(e);
846	};
847
848	var div_4 = sibling(progress, 2);
849	var button = child(div_4);
850
851	button.__click = () => set(show_volume_slider, !get(show_volume_slider));
852
853	let styles;
854	var node_3 = child(button);
855
856	VolumeLevels(node_3, {
857		get currentVolume() {
858			return get(current_volume);
859		}
860	});
861
862	reset(button);
863
864	var node_4 = sibling(button, 2);
865
866	{
867		var consequent_2 = ($$anchor) => {
868			VolumeControl($$anchor, {
869				get current_volume() {
870					return get(current_volume);
871				},
872
873				set current_volume($$value) {
874					set(current_volume, $$value, true);
875				},
876
877				get show_volume_slider() {
878					return get(show_volume_slider);
879				},
880
881				set show_volume_slider($$value) {
882					set(show_volume_slider, $$value, true);
883				}
884			});
885		};
886
887		if_block(node_4, ($$render) => {
888			if (get(show_volume_slider)) $$render(consequent_2);
889		});
890	}
891
892	reset(div_4);
893
894	var node_5 = sibling(div_4, 2);
895
896	{
897		var consequent_3 = ($$anchor) => {
898			var div_5 = root_8();
899
900			div_5.__click = open_full_screen;
901
902			var node_6 = child(div_5);
903
904			Maximize(node_6);
905			reset(div_5);
906			event('keypress', div_5, open_full_screen);
907			append($$anchor, div_5);
908		};
909
910		if_block(node_5, ($$render) => {
911			if (!get(show_volume_slider)) $$render(consequent_3);
912		});
913	}
914
915	reset(div_3);
916	reset(div_2);
917	reset(div);
918
919	var node_7 = sibling(div, 2);
920
921	{
922		var consequent_4 = ($$anchor) => {
923			VideoControls($$anchor, {
924				get videoElement() {
925					return get(video);
926				},
927				showRedo: true,
928				handle_trim_video,
929				get handle_reset_value() {
930					return handle_reset_value();
931				},
932
933				get value() {
934					return value();
935				},
936
937				get i18n() {
938					return $$props.i18n;
939				},
940
941				get show_download_button() {
942					return show_download_button();
943				},
944
945				get handle_clear() {
946					return handle_clear();
947				},
948
949				get has_change_history() {
950					return has_change_history();
951				},
952
953				get processingVideo() {
954					return get(processingVideo);
955				},
956
957				set processingVideo($$value) {
958					set(processingVideo, $$value, true);
959				}
960			});
961		};
962
963		if_block(node_7, ($$render) => {
964			if (interactive()) $$render(consequent_4);
965		});
966	}
967
968	template_effect(
969		($0, $1) => {
970			classes = set_class(div_1, 1, 'mirror-wrap svelte-1k28h7x', null, classes, { mirror: $$props.mirror });
971			set_text(text, `${$0 ?? ''} / ${$1 ?? ''}`);
972			set_value(progress, get(time) / get(duration) || 0);
973
974			styles = set_style(button, '', styles, {
975				color: get(show_volume_slider) ? "var(--color-accent)" : "white"
976			});
977		},
978		[
979			() => format_time(get(time)),
980			() => format_time(get(duration))
981		]
982	);
983
984	append($$anchor, fragment);
985	pop();
986}
987
988delegate(['click', 'keydown', 'mousemove', 'touchmove']);
989
990var root_5 = from_html(`<!> <!>`, 1);
991var root_3 = from_html(`<!> <div data-testid="download-div"><!></div>`, 1);
992var root = from_html(`<!> <!>`, 1);
993
994function VideoPreview($$anchor, $$props) {
995	push($$props, true);
996
997	let value = prop($$props, 'value', 15, null),
998		subtitle = prop($$props, 'subtitle', 3, null),
999		label = prop($$props, 'label', 3, undefined),
1000		show_label = prop($$props, 'show_label', 3, true),
1001		buttons = prop($$props, 'buttons', 3, null),
1002		on_custom_button_click = prop($$props, 'on_custom_button_click', 3, null),
1003		display_icon_button_wrapper_top_corner = prop($$props, 'display_icon_button_wrapper_top_corner', 3, false),
1004		playback_position = prop($$props, 'playback_position', 15);
1005
1006	let old_value = state(null);
1007	let old_subtitle = state(null);
1008
1009	user_effect(() => {
1010		if (value()) {
1011			$$props.onchange?.(value());
1012		}
1013	});
1014
1015	user_effect(() => {
1016		async function updateValue() {
1017			// needed to bust subtitle caching issues on Chrome
1018			if (value() !== get(old_value) && subtitle() !== get(old_subtitle) && get(old_subtitle) !== null) {
1019				set(old_value, value(), true);
1020				value(null);
1021				await tick();
1022				value(get(old_value));
1023			}
1024
1025			set(old_value, value(), true);
1026			set(old_subtitle, subtitle());
1027		}
1028
1029		updateValue();
1030	});
1031
1032	var fragment = root();
1033	var node = first_child(fragment);
1034
1035	{
1036		let $0 = user_derived(() => label() || "Video");
1037
1038		BlockLabel(node, {
1039			get show_label() {
1040				return show_label();
1041			},
1042
1043			get Icon() {
1044				return Video$1;
1045			},
1046
1047			get label() {
1048				return get($0);
1049			}
1050		});
1051	}
1052
1053	var node_1 = sibling(node, 2);
1054
1055	{
1056		var consequent = ($$anchor) => {
1057			Empty($$anchor, {
1058				unpadded_box: true,
1059				size: 'large',
1060				children: ($$anchor, $$slotProps) => {
1061					Video$1($$anchor);
1062				},
1063				$$slots: { default: true }
1064			});
1065		};
1066
1067		var alternate = ($$anchor) => {
1068			var fragment_3 = root_3();
1069			var node_2 = first_child(fragment_3);
1070
1071			key(node_2, () => value().url, ($$anchor) => {
1072				{
1073					let $0 = user_derived(() => subtitle()?.url);
1074
1075					Player($$anchor, {
1076						get src() {
1077							return value().url;
1078						},
1079
1080						get subtitle() {
1081							return get($0);
1082						},
1083
1084						get is_stream() {
1085							return value().is_stream;
1086						},
1087
1088						get autoplay() {
1089							return $$props.autoplay;
1090						},
1091						onplay: () => $$props.onplay?.(),
1092						onpause: () => $$props.onpause?.(),
1093						onstop: () => $$props.onstop?.(),
1094						onend: () => $$props.onend?.(),
1095						onloadedmetadata: () => {
1096							// Deal with `<video>`'s `loadedmetadata` event as `VideoPreview`'s `load` event
1097							// to represent not only the video is loaded but also the metadata is loaded
1098							// so its dimensions (w/h) are known. This is used for Chatbot's auto scroll.
1099							$$props.onload?.();
1100						},
1101						mirror: false,
1102						get label() {
1103							return label();
1104						},
1105
1106						get loop() {
1107							return $$props.loop;
1108						},
1109						interactive: false,
1110						get upload() {
1111							return $$props.upload;
1112						},
1113
1114						get i18n() {
1115							return $$props.i18n;
1116						},
1117
1118						get playback_position() {
1119							return playback_position();
1120						},
1121
1122						set playback_position($$value) {
1123							playback_position($$value);
1124						}
1125					});
1126				}
1127			});
1128
1129			var div = sibling(node_2, 2);
1130			var node_3 = child(div);
1131
1132			{
1133				let $0 = user_derived(() => buttons() ?? ["download", "share"]);
1134
1135				IconButtonWrapper(node_3, {
1136					get display_top_corner() {
1137						return display_icon_button_wrapper_top_corner();
1138					},
1139
1140					get buttons() {
1141						return get($0);
1142					},
1143
1144					get on_custom_button_click() {
1145						return on_custom_button_click();
1146					},
1147
1148					children: ($$anchor, $$slotProps) => {
1149						var fragment_5 = root_5();
1150						var node_4 = first_child(fragment_5);
1151
1152						{
1153							var consequent_1 = ($$anchor) => {
1154								{
1155									let $0 = user_derived(() => value().is_stream
1156										? value().url?.replace("playlist.m3u8", "playlist-file")
1157										: value().url);
1158
1159									let $1 = user_derived(() => value().orig_name || value().path);
1160
1161									DownloadLink($$anchor, {
1162										get href() {
1163											return get($0);
1164										},
1165
1166										get download() {
1167											return get($1);
1168										},
1169
1170										children: ($$anchor, $$slotProps) => {
1171											IconButton($$anchor, {
1172												get Icon() {
1173													return Download;
1174												},
1175												label: 'Download'
1176											});
1177										},
1178										$$slots: { default: true }
1179									});
1180								}
1181							};
1182
1183							if_block(node_4, ($$render) => {
1184								if (buttons()?.some((btn) => typeof btn === "string" && btn === "download")) $$render(consequent_1);
1185							});
1186						}
1187
1188						var node_5 = sibling(node_4, 2);
1189
1190						{
1191							var consequent_2 = ($$anchor) => {
1192								ShareButton($$anchor, {
1193									get i18n() {
1194										return $$props.i18n;
1195									},
1196									onerror: (detail) => $$props.onerror?.(detail),
1197									onshare: (detail) => $$props.onshare?.(detail),
1198									get value() {
1199										return value();
1200									},
1201
1202									formatter: async (value) => {
1203										if (!value) return "";
1204
1205										let url = await uploadToHuggingFace(value.data);
1206
1207										return url;
1208									}
1209								});
1210							};
1211
1212							if_block(node_5, ($$render) => {
1213								if (buttons()?.some((btn) => typeof btn === "string" && btn === "share")) $$render(consequent_2);
1214							});
1215						}
1216
1217						append($$anchor, fragment_5);
1218					},
1219					$$slots: { default: true }
1220				});
1221			}
1222
1223			reset(div);
1224			append($$anchor, fragment_3);
1225		};
1226
1227		if_block(node_1, ($$render) => {
1228			if (!value() || value().url === undefined) $$render(consequent); else $$render(alternate, false);
1229		});
1230	}
1231
1232	append($$anchor, fragment);
1233	pop();
1234}
1235
1236const VideoPreview$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
1237	__proto__: null,
1238	default: VideoPreview
1239}, Symbol.toStringTag, { value: 'Module' }));
1240
1241export { Player as P, VideoPreview as V, VideoPreview$1 as a };
1242//# sourceMappingURL=VideoPreview-DqE2DF2X.js.map

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