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.