- // ==UserScript==
- // @name pornHelper
- // @namespace npm/vite-plugin-monkey
- // @version 1.0.0
- // @author Kin
- // @description 下载PornHub视频和封面
- // @license MIT
- // @icon https://pornhub.com/favicon.ico
- // @homepage https://github.com/Yorushika-fan/pornHelper
- // @match *://*.pornhub.com/*
- // @require https://cdn.jsdelivr.net/npm/vue@3.5.12/dist/vue.global.prod.js
- // @require https://unpkg.com/vue-demi@latest/lib/index.iife.js
- // @require data:application/javascript,window.Vue%3DVue%3B
- // @require https://cdn.jsdelivr.net/npm/element-plus@2.8.5/dist/index.full.min.js
- // @resource ElementPlus https://cdn.jsdelivr.net/npm/element-plus@2.8.5/dist/index.full.min.css
- // @grant GM_addStyle
- // @grant GM_download
- // @grant GM_getResourceText
- // @grant GM_xmlhttpRequest
- // @grant unsafeWindow
- // ==/UserScript==
-
- (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const r=document.createElement("style");r.textContent=t,document.head.append(r)})(" *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.fixed{position:fixed}.right-4{right:1rem}.top-16{top:4rem}.z-10{z-index:10}.mb-4{margin-bottom:1rem}.flex{display:flex}.flex-grow{flex-grow:1}.flex-row{flex-direction:row}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse: 0;margin-right:calc(.5rem * var(--tw-space-x-reverse));margin-left:calc(.5rem * calc(1 - var(--tw-space-x-reverse)))}.\\!rounded-lg{border-radius:.5rem!important}.rounded{border-radius:.25rem}.\\!bg-\\[\\#ff9900\\]{--tw-bg-opacity: 1 !important;background-color:rgb(255 153 0 / var(--tw-bg-opacity))!important}.\\!bg-gray-200{--tw-bg-opacity: 1 !important;background-color:rgb(229 231 235 / var(--tw-bg-opacity))!important}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity))}.\\!py-3{padding-top:.75rem!important;padding-bottom:.75rem!important}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.\\!text-base{font-size:1rem!important;line-height:1.5rem!important}.\\!font-bold{font-weight:700!important}.font-bold{font-weight:700}.\\!text-black{--tw-text-opacity: 1 !important;color:rgb(0 0 0 / var(--tw-text-opacity))!important}.\\!text-gray-700{--tw-text-opacity: 1 !important;color:rgb(55 65 81 / var(--tw-text-opacity))!important}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.\\!transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.hover\\:\\!bg-\\[\\#ff6600\\]:hover{--tw-bg-opacity: 1 !important;background-color:rgb(255 102 0 / var(--tw-bg-opacity))!important}.hover\\:\\!bg-gray-300:hover{--tw-bg-opacity: 1 !important;background-color:rgb(209 213 219 / var(--tw-bg-opacity))!important}.hover\\:bg-blue-600:hover{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity))}.hover\\:bg-green-600:hover{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity))} ");
-
- (function (vue, elementPlus) {
- 'use strict';
-
- const cssLoader = (e) => {
- const t = GM_getResourceText(e);
- return GM_addStyle(t), t;
- };
- cssLoader("ElementPlus");
- var _GM_download = /* @__PURE__ */ (() => typeof GM_download != "undefined" ? GM_download : void 0)();
- var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
- var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
- var _a;
- const isClient = typeof window !== "undefined";
- const isString = (val) => typeof val === "string";
- const noop = () => {
- };
- isClient && ((_a = window == null ? void 0 : window.navigator) == null ? void 0 : _a.userAgent) && /iP(ad|hone|od)/.test(window.navigator.userAgent);
- function resolveUnref(r) {
- return typeof r === "function" ? r() : vue.unref(r);
- }
- function createFilterWrapper(filter, fn) {
- function wrapper(...args) {
- return new Promise((resolve, reject) => {
- Promise.resolve(filter(() => fn.apply(this, args), { fn, thisArg: this, args })).then(resolve).catch(reject);
- });
- }
- return wrapper;
- }
- function throttleFilter(ms, trailing = true, leading = true, rejectOnCancel = false) {
- let lastExec = 0;
- let timer;
- let isLeading = true;
- let lastRejector = noop;
- let lastValue;
- const clear = () => {
- if (timer) {
- clearTimeout(timer);
- timer = void 0;
- lastRejector();
- lastRejector = noop;
- }
- };
- const filter = (_invoke) => {
- const duration = resolveUnref(ms);
- const elapsed = Date.now() - lastExec;
- const invoke = () => {
- return lastValue = _invoke();
- };
- clear();
- if (duration <= 0) {
- lastExec = Date.now();
- return invoke();
- }
- if (elapsed > duration && (leading || !isLeading)) {
- lastExec = Date.now();
- invoke();
- } else if (trailing) {
- lastValue = new Promise((resolve, reject) => {
- lastRejector = rejectOnCancel ? reject : resolve;
- timer = setTimeout(() => {
- lastExec = Date.now();
- isLeading = true;
- resolve(invoke());
- clear();
- }, Math.max(0, duration - elapsed));
- });
- }
- if (!leading && !timer)
- timer = setTimeout(() => isLeading = true, duration);
- isLeading = false;
- return lastValue;
- };
- return filter;
- }
- function identity(arg) {
- return arg;
- }
- function tryOnScopeDispose(fn) {
- if (vue.getCurrentScope()) {
- vue.onScopeDispose(fn);
- return true;
- }
- return false;
- }
- function useThrottleFn(fn, ms = 200, trailing = false, leading = true, rejectOnCancel = false) {
- return createFilterWrapper(throttleFilter(ms, trailing, leading, rejectOnCancel), fn);
- }
- function tryOnMounted(fn, sync = true) {
- if (vue.getCurrentInstance())
- vue.onMounted(fn);
- else if (sync)
- fn();
- else
- vue.nextTick(fn);
- }
- function useTimeoutFn(cb, interval, options = {}) {
- const {
- immediate = true
- } = options;
- const isPending = vue.ref(false);
- let timer = null;
- function clear() {
- if (timer) {
- clearTimeout(timer);
- timer = null;
- }
- }
- function stop() {
- isPending.value = false;
- clear();
- }
- function start(...args) {
- clear();
- isPending.value = true;
- timer = setTimeout(() => {
- isPending.value = false;
- timer = null;
- cb(...args);
- }, resolveUnref(interval));
- }
- if (immediate) {
- isPending.value = true;
- if (isClient)
- start();
- }
- tryOnScopeDispose(stop);
- return {
- isPending: vue.readonly(isPending),
- start,
- stop
- };
- }
- function unrefElement(elRef) {
- var _a2;
- const plain = resolveUnref(elRef);
- return (_a2 = plain == null ? void 0 : plain.$el) != null ? _a2 : plain;
- }
- const defaultWindow = isClient ? window : void 0;
- const defaultNavigator = isClient ? window.navigator : void 0;
- function useEventListener(...args) {
- let target;
- let events;
- let listeners;
- let options;
- if (isString(args[0]) || Array.isArray(args[0])) {
- [events, listeners, options] = args;
- target = defaultWindow;
- } else {
- [target, events, listeners, options] = args;
- }
- if (!target)
- return noop;
- if (!Array.isArray(events))
- events = [events];
- if (!Array.isArray(listeners))
- listeners = [listeners];
- const cleanups = [];
- const cleanup = () => {
- cleanups.forEach((fn) => fn());
- cleanups.length = 0;
- };
- const register = (el, event, listener, options2) => {
- el.addEventListener(event, listener, options2);
- return () => el.removeEventListener(event, listener, options2);
- };
- const stopWatch = vue.watch(() => [unrefElement(target), resolveUnref(options)], ([el, options2]) => {
- cleanup();
- if (!el)
- return;
- cleanups.push(...events.flatMap((event) => {
- return listeners.map((listener) => register(el, event, listener, options2));
- }));
- }, { immediate: true, flush: "post" });
- const stop = () => {
- stopWatch();
- cleanup();
- };
- tryOnScopeDispose(stop);
- return stop;
- }
- function useSupported(callback, sync = false) {
- const isSupported = vue.ref();
- const update = () => isSupported.value = Boolean(callback());
- update();
- tryOnMounted(update, sync);
- return isSupported;
- }
- function useClipboard(options = {}) {
- const {
- navigator = defaultNavigator,
- read = false,
- source,
- copiedDuring = 1500,
- legacy = false
- } = options;
- const events = ["copy", "cut"];
- const isClipboardApiSupported = useSupported(() => navigator && "clipboard" in navigator);
- const isSupported = vue.computed(() => isClipboardApiSupported.value || legacy);
- const text = vue.ref("");
- const copied = vue.ref(false);
- const timeout = useTimeoutFn(() => copied.value = false, copiedDuring);
- function updateText() {
- if (isClipboardApiSupported.value) {
- navigator.clipboard.readText().then((value) => {
- text.value = value;
- });
- } else {
- text.value = legacyRead();
- }
- }
- if (isSupported.value && read) {
- for (const event of events)
- useEventListener(event, updateText);
- }
- async function copy(value = resolveUnref(source)) {
- if (isSupported.value && value != null) {
- if (isClipboardApiSupported.value)
- await navigator.clipboard.writeText(value);
- else
- legacyCopy(value);
- text.value = value;
- copied.value = true;
- timeout.start();
- }
- }
- function legacyCopy(value) {
- const ta = document.createElement("textarea");
- ta.value = value != null ? value : "";
- ta.style.position = "absolute";
- ta.style.opacity = "0";
- document.body.appendChild(ta);
- ta.select();
- document.execCommand("copy");
- ta.remove();
- }
- function legacyRead() {
- var _a2, _b, _c;
- return (_c = (_b = (_a2 = document == null ? void 0 : document.getSelection) == null ? void 0 : _a2.call(document)) == null ? void 0 : _b.toString()) != null ? _c : "";
- }
- return {
- isSupported,
- text,
- copied,
- copy
- };
- }
- const _global = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
- const globalKey = "__vueuse_ssr_handlers__";
- _global[globalKey] = _global[globalKey] || {};
- var SwipeDirection;
- (function(SwipeDirection2) {
- SwipeDirection2["UP"] = "UP";
- SwipeDirection2["RIGHT"] = "RIGHT";
- SwipeDirection2["DOWN"] = "DOWN";
- SwipeDirection2["LEFT"] = "LEFT";
- SwipeDirection2["NONE"] = "NONE";
- })(SwipeDirection || (SwipeDirection = {}));
- var __defProp = Object.defineProperty;
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
- var __spreadValues = (a, b) => {
- for (var prop in b || (b = {}))
- if (__hasOwnProp.call(b, prop))
- __defNormalProp(a, prop, b[prop]);
- if (__getOwnPropSymbols)
- for (var prop of __getOwnPropSymbols(b)) {
- if (__propIsEnum.call(b, prop))
- __defNormalProp(a, prop, b[prop]);
- }
- return a;
- };
- const _TransitionPresets = {
- easeInSine: [0.12, 0, 0.39, 0],
- easeOutSine: [0.61, 1, 0.88, 1],
- easeInOutSine: [0.37, 0, 0.63, 1],
- easeInQuad: [0.11, 0, 0.5, 0],
- easeOutQuad: [0.5, 1, 0.89, 1],
- easeInOutQuad: [0.45, 0, 0.55, 1],
- easeInCubic: [0.32, 0, 0.67, 0],
- easeOutCubic: [0.33, 1, 0.68, 1],
- easeInOutCubic: [0.65, 0, 0.35, 1],
- easeInQuart: [0.5, 0, 0.75, 0],
- easeOutQuart: [0.25, 1, 0.5, 1],
- easeInOutQuart: [0.76, 0, 0.24, 1],
- easeInQuint: [0.64, 0, 0.78, 0],
- easeOutQuint: [0.22, 1, 0.36, 1],
- easeInOutQuint: [0.83, 0, 0.17, 1],
- easeInExpo: [0.7, 0, 0.84, 0],
- easeOutExpo: [0.16, 1, 0.3, 1],
- easeInOutExpo: [0.87, 0, 0.13, 1],
- easeInCirc: [0.55, 0, 1, 0.45],
- easeOutCirc: [0, 0.55, 0.45, 1],
- easeInOutCirc: [0.85, 0, 0.15, 1],
- easeInBack: [0.36, 0, 0.66, -0.56],
- easeOutBack: [0.34, 1.56, 0.64, 1],
- easeInOutBack: [0.68, -0.6, 0.32, 1.6]
- };
- __spreadValues({
- linear: identity
- }, _TransitionPresets);
- const _hoisted_1 = {
- key: 0,
- class: "fixed top-16 right-4 flex flex-row space-x-2 z-10"
- };
- const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
- __name: "pornhub",
- setup(__props) {
- const isDownloadingVideo = vue.ref(false);
- const isDownloadingCover = vue.ref(false);
- const downloadProgress = vue.ref(0);
- const isDownloading = vue.ref(false);
- vue.onMounted(() => {
- console.log("脚本已加载");
- console.log(`
- ____ _ _ _
- | _ \\ ___ _ __ _ __ | | | |_ _| |__
- | |_) / _ \\| '__| '_ \\| |_| | | | | '_ \\
- | __/ (_) | | | | | | _ | |_| | |_) |
- |_| \\___/|_| |_| |_|_| |_|\\__,_|_.__/
- `);
- });
- const videoList = vue.ref([]);
- const { copy } = useClipboard();
- const getFlashVars = () => {
- const flashvarsRegex = /flashvars_\d+/;
- const flashvarsKey = Object.keys(_unsafeWindow).find((key) => flashvarsRegex.test(key));
- if (flashvarsKey) {
- return _unsafeWindow[flashvarsKey];
- }
- return null;
- };
- const getVideoInfo = () => {
- videoList.value = [];
- console.log(videoList.value);
- const flashvars = getFlashVars();
- if (flashvars) {
- const mediaDefinitions = flashvars.mediaDefinitions;
- Object.values(mediaDefinitions).forEach((media) => {
- if (media.format === "mp4") {
- _GM_xmlhttpRequest({
- url: media.videoUrl,
- method: "GET",
- responseType: "json",
- onload: (response) => {
- response.response.forEach((res) => {
- videoList.value.push({
- videoUrl: res.videoUrl,
- quality: res.quality
- });
- });
- },
- ontimeout: () => elementPlus.ElMessage.error("请求视频超时,请稍后再试"),
- onerror: () => elementPlus.ElMessage.error("请求视频失败,请稍后再试")
- });
- }
- });
- isDownloadingVideo.value = true;
- } else {
- elementPlus.ElMessage.error("没有找到flashvars");
- }
- };
- const downloadVideo = (video) => {
- isDownloading.value = true;
- downloadProgress.value = 0;
- const xhr = new XMLHttpRequest();
- xhr.open("GET", video.videoUrl, true);
- xhr.responseType = "blob";
- xhr.onprogress = (event) => {
- if (event.lengthComputable) {
- downloadProgress.value = event.loaded / event.total * 100;
- }
- };
- xhr.onload = () => {
- if (xhr.status === 200) {
- const blob = xhr.response;
- const url = URL.createObjectURL(blob);
- const a = document.createElement("a");
- a.href = url;
- a.download = `video_${video.quality}.mp4`;
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- URL.revokeObjectURL(url);
- elementPlus.ElMessage.success(`${video.quality} 质量的视频下载成功`);
- } else {
- elementPlus.ElMessage.error(`${video.quality} 质量的视频下载失败`);
- }
- isDownloading.value = false;
- };
- xhr.onerror = () => {
- console.error("下载错误");
- elementPlus.ElMessage.error(`${video.quality} 质量的视频下载失败`);
- isDownloading.value = false;
- };
- xhr.send();
- };
- const downloadCover = useThrottleFn(() => {
- if (isDownloadingCover.value) return;
- isDownloadingCover.value = true;
- const flashvars = getFlashVars();
- if (flashvars) {
- const coverUrl = flashvars.image_url;
- _GM_download({
- url: coverUrl,
- name: "cover.jpg",
- onerror: () => elementPlus.ElMessage.error("封面下载失败"),
- ontimeout: () => elementPlus.ElMessage.error("封面下载超时"),
- onload: () => elementPlus.ElMessage.success("封面下载成功")
- });
- }
- setTimeout(() => {
- isDownloadingCover.value = false;
- }, 2e3);
- }, 2e3);
- const copyVideoLink = (url) => {
- copy(url);
- elementPlus.ElMessage.success("下载链接已复制到剪贴板");
- };
- return (_ctx, _cache) => {
- return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
- getFlashVars() && !isDownloadingVideo.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
- vue.createElementVNode("button", {
- class: "bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded shadow",
- onClick: getVideoInfo
- }, " 下载视频 "),
- vue.createElementVNode("button", {
- class: "bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded shadow",
- onClick: _cache[0] || (_cache[0] = //@ts-ignore
- (...args) => vue.unref(downloadCover) && vue.unref(downloadCover)(...args))
- }, vue.toDisplayString(isDownloadingCover.value ? "下载中..." : "下载封面"), 1)
- ])) : vue.createCommentVNode("", true),
- vue.createVNode(vue.unref(elementPlus.ElDialog), {
- modelValue: isDownloadingVideo.value,
- "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isDownloadingVideo.value = $event),
- title: "下载视频",
- width: "400px"
- }, {
- default: vue.withCtx(() => [
- vue.createVNode(vue.unref(elementPlus.ElSkeleton), {
- loading: videoList.value.length === 0,
- "animated:true": ""
- }, {
- template: vue.withCtx(() => [
- (vue.openBlock(), vue.createElementBlock(vue.Fragment, null, vue.renderList(4, (i) => {
- return vue.createElementVNode("div", {
- key: i,
- class: "mb-4"
- }, [
- vue.createVNode(vue.unref(elementPlus.ElSkeletonItem), {
- variant: "button",
- style: { "width": "100%", "height": "48px" }
- })
- ]);
- }), 64))
- ]),
- default: vue.withCtx(() => [
- !isDownloading.value ? (vue.openBlock(true), vue.createElementBlock(vue.Fragment, { key: 0 }, vue.renderList(videoList.value, (video, index) => {
- return vue.openBlock(), vue.createElementBlock("div", {
- key: index,
- class: "mb-4 flex space-x-2"
- }, [
- vue.createVNode(vue.unref(elementPlus.ElButton), {
- class: vue.normalizeClass([
- "flex-grow !py-3 !text-base !font-bold !rounded-lg !transition-colors",
- "!bg-[#ff9900] hover:!bg-[#ff6600] !text-black"
- ]),
- onClick: ($event) => downloadVideo(video)
- }, {
- default: vue.withCtx(() => [
- vue.createTextVNode(vue.toDisplayString(video.quality + "p"), 1)
- ]),
- _: 2
- }, 1032, ["onClick"]),
- vue.createVNode(vue.unref(elementPlus.ElButton), {
- class: vue.normalizeClass([
- "!py-3 !text-base !font-bold !rounded-lg !transition-colors",
- "!bg-gray-200 hover:!bg-gray-300 !text-gray-700"
- ]),
- onClick: ($event) => copyVideoLink(video.videoUrl)
- }, {
- default: vue.withCtx(() => _cache[2] || (_cache[2] = [
- vue.createTextVNode(" 复制链接 ")
- ])),
- _: 2
- }, 1032, ["onClick"])
- ]);
- }), 128)) : vue.createCommentVNode("", true)
- ]),
- _: 1
- }, 8, ["loading"]),
- isDownloading.value ? (vue.openBlock(), vue.createBlock(vue.unref(elementPlus.ElProgress), {
- key: 0,
- percentage: downloadProgress.value,
- status: "success",
- "stroke-width": 20
- }, null, 8, ["percentage"])) : vue.createCommentVNode("", true)
- ]),
- _: 1
- }, 8, ["modelValue"])
- ], 64);
- };
- }
- });
- const _sfc_main = /* @__PURE__ */ vue.defineComponent({
- __name: "App",
- setup(__props) {
- return (_ctx, _cache) => {
- return vue.openBlock(), vue.createBlock(_sfc_main$1);
- };
- }
- });
- vue.createApp(_sfc_main).mount(
- (() => {
- const app = document.createElement("div");
- document.body.append(app);
- return app;
- })()
- );
-
- })(Vue, ElementPlus);