extract-youtube 1.0.113 → 1.0.115

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/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let e=require("html-entities"),t=require("fast-xml-parser"),r=require("https-proxy-agent");var s,n,o=class e extends Error{constructor(t){super(t),this.name="YouTubeTranscriptApiException",Object.setPrototypeOf(this,e.prototype)}},i=class e extends o{constructor(t){super(""),this.causeMessage="",this.videoId=t,Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}buildErrorMessage(){const t="https://www.youtube.com/watch?v={video_id}".replace("{video_id}",this.videoId);let r=e.ERROR_MESSAGE.replace("{video_url}",t);const s=this.getCause();return s&&(r+=e.CAUSE_MESSAGE_INTRO.replace("{cause}",s),r+=e.GITHUB_REFERRAL),r}getCause(){return this.causeMessage}};(s=i).ERROR_MESSAGE="\nCould not retrieve a transcript for the video {video_url}!",s.CAUSE_MESSAGE_INTRO=" This is most likely caused by:\n\n{cause}",s.GITHUB_REFERRAL="\n\nIf you are sure that the described cause is not responsible for this error and that a transcript should be retrievable, please create an issue at https://github.com/jdepoix/youtube-transcript-api/issues. Please add which version of youtube_transcript_api you are using and provide the information needed to replicate the error. Also make sure that there are no open issues which already describe your problem!";var a=class e extends o{constructor(t){super(t),this.name="CookieError",Object.setPrototypeOf(this,e.prototype)}},l=class e extends i{constructor(t){super(t),this.causeMessage="The data required to fetch the transcript is not parsable. This should not happen, please open an issue (make sure to include the video ID)!",this.name="YouTubeDataUnparsable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},c=class e extends i{constructor(t,r){super(t),this.httpErrorReason=r.message,this.name="YouTubeRequestFailed",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){return`Request to YouTube failed: ${this.httpErrorReason}`}},u=class e extends i{constructor(t,r,s){super(t),this.unplayableReason=r,this.additionalDetails=s,this.name="VideoUnplayable",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){let e=this.unplayableReason??"No reason specified!";if(this.additionalDetails.length>0){e=`${e}\n\nAdditional Details:\n${this.additionalDetails.map(e=>` - ${e}`).join("\n")}`}return`The video is unplayable for the following reason: ${e}`}},p=class e extends i{constructor(t){super(t),this.causeMessage="The video is no longer available",this.name="VideoUnavailable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},h=class e extends i{constructor(t){super(t),this.causeMessage='You provided an invalid video id. Make sure you are using the video id and NOT the url!\n\nDo NOT run: `new YouTubeTranscriptApi().fetch("https://www.youtube.com/watch?v=1234")`\nInstead run: `new YouTubeTranscriptApi().fetch("1234")`',this.name="InvalidVideoId",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},d=class e extends i{constructor(t){super(t),this.causeMessage="This video is age-restricted. Therefore, you are unable to retrieve transcripts for it without authenticating yourself.\n\nUnfortunately, Cookie Authentication is temporarily unsupported in youtube-transcript-api, as recent changes in YouTube's API broke the previous implementation. I will do my best to re-implement it as soon as possible.",this.name="AgeRestricted",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},g=class e extends i{constructor(t){super(t),this.causeMessage="Failed to automatically give consent to saving cookies",this.name="FailedToCreateConsentCookie",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},f=class e extends i{constructor(t){super(t),this.causeMessage="Subtitles are disabled for this video",this.name="TranscriptsDisabled",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},y=class e extends i{constructor(t){super(t),this.causeMessage="The requested language is not translatable",this.name="NotTranslatable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},m=class e extends i{constructor(t){super(t),this.causeMessage="The requested translation language is not available",this.name="TranslationLanguageNotAvailable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},b=class e extends i{constructor(t,r,s){super(t),this.requestedLanguageCodes=r,this.availableTranscriptData=s,this.name="NoTranscriptFound",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){return`No transcripts were found for any of the requested language codes: ${this.requestedLanguageCodes.join(", ")}\n\n`+this.availableTranscriptData.toString()}},w=class e extends i{constructor(t){super(t),this.causeMessage="The requested video cannot be retrieved without a PO Token. If this happens, please open a GitHub issue!",this.name="PoTokenRequired",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},T=class e extends i{constructor(t){super(t),this.proxyConfig=null,this.name="RequestBlocked",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}withProxyConfig(e){return this.proxyConfig=e,this.message=this.buildErrorMessage(),this}getCause(){return this.proxyConfig&&"WebshareProxyConfig"===this.proxyConfig.constructor.name?e.WITH_WEBSHARE_PROXY_CAUSE_MESSAGE:this.proxyConfig&&"GenericProxyConfig"===this.proxyConfig.constructor.name?e.WITH_GENERIC_PROXY_CAUSE_MESSAGE:e.DEFAULT_CAUSE_MESSAGE}};(n=T).BASE_CAUSE_MESSAGE="YouTube is blocking requests from your IP. This usually is due to one of the following reasons:\n- You have done too many requests and your IP has been blocked by YouTube\n- You are doing requests from an IP belonging to a cloud provider (like AWS, Google Cloud Platform, Azure, etc.). Unfortunately, most IPs from cloud providers are blocked by YouTube.\n\n",n.DEFAULT_CAUSE_MESSAGE=n.BASE_CAUSE_MESSAGE+'There are two things you can do to work around this:\n1. Use proxies to hide your IP address, as explained in the "Working around IP bans" section of the README (https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#working-around-ip-bans-requestblocked-or-ipblocked-exception).\n2. (NOT RECOMMENDED) If you authenticate your requests using cookies, you will be able to continue doing requests for a while. However, YouTube will eventually permanently ban the account that you have used to authenticate with! So only do this if you don\'t mind your account being banned!',n.WITH_GENERIC_PROXY_CAUSE_MESSAGE='YouTube is blocking your requests, despite you using proxies. Keep in mind that a proxy is just a way to hide your real IP behind the IP of that proxy, but there is no guarantee that the IP of that proxy won\'t be blocked as well.\n\nThe only truly reliable way to prevent IP blocks is rotating through a large pool of residential IPs, by using a provider like Webshare (https://www.webshare.io/?referral_code=w0xno53eb50g), which provides you with a pool of >30M residential IPs (make sure to purchase "Residential" proxies, NOT "Proxy Server" or "Static Residential"!).\n\nYou will find more information on how to easily integrate Webshare here: https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#using-webshare',n.WITH_WEBSHARE_PROXY_CAUSE_MESSAGE='YouTube is blocking your requests, despite you using Webshare proxies. Please make sure that you have purchased "Residential" proxies and NOT "Proxy Server" or "Static Residential", as those won\'t work as reliably! The free tier also uses "Proxy Server" and will NOT work!\n\nThe only reliable option is using "Residential" proxies (not "Static Residential"), as this allows you to rotate through a pool of over 30M IPs, which means you will always find an IP that hasn\'t been blocked by YouTube yet!\n\nYou can support the development of this open source project by making your Webshare purchases through this affiliate link: https://www.webshare.io/?referral_code=w0xno53eb50g \n\nThank you for your support! <3';var x=class e extends T{constructor(t){super(t),this.causeMessage='YouTube is blocking requests from your IP. This usually is due to one of the following reasons:\n- You have done too many requests and your IP has been blocked by YouTube\n- You are doing requests from an IP belonging to a cloud provider (like AWS, Google Cloud Platform, Azure, etc.). Unfortunately, most IPs from cloud providers are blocked by YouTube.\n\nWays to work around this are explained in the "Working around IP bans" section of the README (https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#working-around-ip-bans-requestblocked-or-ipblocked-exception).\n',this.name="IpBlocked",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}getCause(){return this.causeMessage}},v=class{constructor(e,t,r,s,n){this.snippets=e,this.videoId=t,this.language=r,this.languageCode=s,this.isGenerated=n}[Symbol.iterator](){return this.snippets[Symbol.iterator]()}getSnippetAtIndex(e){return this.snippets[e]}get(e){return this.getSnippetAtIndex(e)}get length(){return this.snippets.length}toRawData(){return this.snippets.map(e=>({text:e.text,start:e.start,duration:e.duration}))}},E=class r{constructor(e=!1){this.htmlRemovalRegex=this.buildHtmlRemovalRegex(e)}buildHtmlRemovalRegex(e){if(e){const e=`<\\/?(?!\\/?(?:${r.FORMATTING_TAGS.join("|")})\\b).*?\\b>`;return new RegExp(e,"gi")}return/<[^>]*>/gi}parseTranscriptXml(e){const r=new t.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_"}).parse(e).transcript?.text||[];return(Array.isArray(r)?r:[r]).filter(e=>e["#text"]).map(e=>this.parseTranscriptSnippet(e))}parseTranscriptSnippet(e){return{text:this.cleanTranscriptText(e["#text"]),start:this.parseFloatAttribute(e["@_start"]),duration:this.parseFloatAttribute(e["@_dur"])}}parseFloatAttribute(e){return parseFloat(e||"0")}cleanTranscriptText(t){return"string"!=typeof t&&(t=String(t||"")),(0,e.decode)(t).replace(this.htmlRemovalRegex,"")}};function A(e,t){if(429===e.status)throw new x(t);if(!e.ok){const r=`HTTP ${e.status}: ${e.statusText}`;throw new c(t,new Error(r))}}E.FORMATTING_TAGS=["strong","em","b","i","mark","small","del","ins","sub","sup"];var C=class e{constructor(e,t,r,s,n,o,i){this.httpClient=e,this.videoId=t,this.transcriptUrl=r,this.language=s,this.languageCode=n,this.isGenerated=o,this.translationLanguages=i,this.translationLanguagesMap=this.buildTranslationLanguagesMap(i)}buildTranslationLanguagesMap(e){const t={};for(const r of e)t[r.language_code]=r.language;return t}async fetch(e=!1){if(this.transcriptUrl.includes("&exp=xpe"))throw new w(this.videoId);const t=await this.httpClient.get(this.transcriptUrl);A(t,this.videoId);const r=await t.text();return new v(new E(e).parseTranscriptXml(r),this.videoId,this.language,this.languageCode,this.isGenerated)}get isTranslatable(){return this.translationLanguages.length>0}translate(t){if(!this.isTranslatable)throw new y(this.videoId);if(!(t in this.translationLanguagesMap))throw new m(this.videoId);const r=`${this.transcriptUrl}&tlang=${t}`,s=this.translationLanguagesMap[t];return new e(this.httpClient,this.videoId,r,s,t,!0,[])}toString(){const e=this.isTranslatable?"[TRANSLATABLE]":"";return`${this.languageCode} ("${this.language}")${e}`}},R=class e{constructor(e,t,r,s){this.videoId=e,this.manuallyCreatedTranscripts=t,this.autoGeneratedTranscripts=r,this.availableTranslationLanguages=s}static buildFromCaptionsJson(t,r,s){const n=e.extractTranslationLanguages(s),{manualTranscripts:o,generatedTranscripts:i}=e.categorizeTranscripts(t,r,s,n);return new e(r,o,i,n)}static extractTranslationLanguages(e){return(e.translationLanguages||[]).map(e=>({language:e.languageName.runs[0].text,language_code:e.languageCode}))}static categorizeTranscripts(e,t,r,s){const n={},o={};for(const i of r.captionTracks){const r="asr"===i.kind,a=r?o:n,l=new C(e,t,i.baseUrl.replace("&fmt=srv3",""),i.name.runs[0].text,i.languageCode,r,i.isTranslatable?s:[]);a[i.languageCode]=l}return{manualTranscripts:n,generatedTranscripts:o}}[Symbol.iterator](){return[...Object.values(this.manuallyCreatedTranscripts),...Object.values(this.autoGeneratedTranscripts)][Symbol.iterator]()}findTranscript(e){return this.findTranscriptInMaps(e,[this.manuallyCreatedTranscripts,this.autoGeneratedTranscripts])}findGeneratedTranscript(e){return this.findTranscriptInMaps(e,[this.autoGeneratedTranscripts])}findManuallyCreatedTranscript(e){return this.findTranscriptInMaps(e,[this.manuallyCreatedTranscripts])}findTranscriptInMaps(e,t){for(const r of e)for(const e of t)if(r in e)return e[r];throw new b(this.videoId,e,this)}toString(){const e=e=>{const t=Object.values(e).map(e=>` - ${e.toString()}`);return t.length>0?t.join("\n"):"None"};return`For this video (${this.videoId}) transcripts are available in the following languages:\n\n(MANUALLY CREATED)\n${e(this.manuallyCreatedTranscripts)}\n\n(GENERATED)\n${e(this.autoGeneratedTranscripts)}\n\n(TRANSLATION LANGUAGES)\n${(()=>{const e=this.availableTranslationLanguages.map(e=>` - ${e.language_code} ("${e.language}")`);return e.length>0?e.join("\n"):"None"})()}`}},S=function(e){return e.OK="OK",e.ERROR="ERROR",e.LOGIN_REQUIRED="LOGIN_REQUIRED",e}({}),P=function(e){return e.BOT_DETECTED="Sign in to confirm you're not a bot",e.AGE_RESTRICTED="This video may be inappropriate for some users.",e.VIDEO_UNAVAILABLE="This video is unavailable",e}({});function O(e,t){!function(e,t){if(!e)return;const r=e.status;if(r===S.OK||!r)return;const s=e.reason;if(r===S.LOGIN_REQUIRED){if(s===P.BOT_DETECTED)throw new T(t);if(s===P.AGE_RESTRICTED)throw new d(t)}if(r===S.ERROR&&s===P.VIDEO_UNAVAILABLE){if(t.startsWith("http://")||t.startsWith("https://"))throw new h(t);throw new p(t)}throw new u(t,s,function(e){const t=e.errorScreen?.playerErrorMessageRenderer?.subreason?.runs;return t&&Array.isArray(t)?t.map(e=>e.text||"").filter(e=>e.length>0):[]}(e))}(e.playabilityStatus,t);const r=e.captions?.playerCaptionsTracklistRenderer;if(!r||!r.captionTracks)throw new f(t);return r}var I={client:{clientName:"ANDROID",clientVersion:"20.10.38"}},k=class{constructor(e,t){this.httpClient=e,this.proxyConfig=t}async fetchTranscriptList(e){const t=await this.fetchCaptionsJsonWithRetry(e);return R.buildFromCaptionsJson(this.httpClient,e,t)}async fetchCaptionsJsonWithRetry(e,t=0){try{const t=function(e,t){const r=e.match(/"INNERTUBE_API_KEY":\s*"([a-zA-Z0-9_-]+)"/);if(r&&2===r.length)return r[1];if(e.includes('class="g-recaptcha"'))throw new x(t);throw new l(t)}(await this.fetchVideoPageHtml(e),e);return O(await this.fetchInnertubePlayerData(e,t),e)}catch(r){if(r instanceof T)return this.handleBlockedRequest(r,e,t);throw r}}async handleBlockedRequest(e,t,r){if(r+1<(this.proxyConfig?.retriesWhenBlocked||0))return this.fetchCaptionsJsonWithRetry(t,r+1);throw e.withProxyConfig(this.proxyConfig)}async fetchVideoPageHtml(e){let t=await this.fetchAndDecodeHtml(e);if(this.isConsentPageDetected(t)&&(this.createConsentCookie(t,e),t=await this.fetchAndDecodeHtml(e),this.isConsentPageDetected(t)))throw new g(e);return t}isConsentPageDetected(e){return e.includes('action="https://consent.youtube.com/s"')}async fetchAndDecodeHtml(t){const r=this.buildWatchUrl(t),s=await this.httpClient.get(r);return A(s,t),(0,e.decode)(await s.text())}buildWatchUrl(e){return"https://www.youtube.com/watch?v={video_id}".replace("{video_id}",e)}createConsentCookie(e,t){if(!e.match(/name="v" value="(.*?)"/))throw new g(t)}async fetchInnertubePlayerData(e,t){const r=this.buildInnertubeApiUrl(t),s=this.buildInnertubeRequestBody(e),n=await this.httpClient.post(r,{headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});return A(n,e),await n.json()}buildInnertubeApiUrl(e){return"https://www.youtube.com/youtubei/v1/player?key={api_key}".replace("{api_key}",e)}buildInnertubeRequestBody(e){return{context:I,videoId:e}}},$={reset:[0,"000000"],black:[30,"1f2937"],red:[31,"dc2626"],green:[32,"2d6a4f"],yellow:[33,"92400e"],blue:[34,"1a56db"],magenta:[35,"6d28d9"],cyan:[36,"0e7490"],white:[37,"374151"],gray:[90,"6b7280"],brightRed:[91,"ef4444"],brightGreen:[92,"059669"],brightYellow:[93,"d97706"],brightBlue:[94,"3b82f6"],brightMagenta:[95,"8b5cf6"],brightCyan:[96,"06b6d4"],brightWhite:[97,"f9fafb"],bgBlack:[40,"111827"],bgRed:[41,"fca5a5"],bgGreen:[42,"a7f3d0"],bgYellow:[43,"fde68a"],bgBlue:[44,"bfdbfe"],bgMagenta:[45,"ddd6fe"],bgCyan:[46,"a5f3fc"],bgWhite:[47,"f9fafb"],bgGray:[100,"d1d5db"],bgBrightRed:[101,"fee2e2"],bgBrightGreen:[102,"d1fae5"],bgBrightYellow:[103,"fef3c7"],bgBrightBlue:[104,"dbeafe"],bgBrightMagenta:[105,"ede9fe"],bgBrightCyan:[106,"cffafe"],bgBrightWhite:[107,"ffffff"]};function L(e="ansi"){const t={};for(const[r,[s,n]]of Object.entries($))t[r]="html"===e?"reset"===r?"</span>":`<span style="color:#${n}">`:"["+s+"m";return t}function M(e,t="ansi"){const r=L(t);return"string"==typeof e?r.yellow:"number"==typeof e?r.cyan:"boolean"==typeof e?r.magenta:"function"==typeof e?r.red:null===e?r.gray:Array.isArray(e)?r.blue:"object"==typeof e?r.green:r.white}function j(e){return"string"==typeof e?'""':"number"==typeof e?"number":"boolean"==typeof e?"bool":"function"==typeof e?"function":null===e?"null":Array.isArray(e)?e.length?"["+j(e[0])+"]":"[]":"object"==typeof e?"{...}":typeof e}function _(e,t=0,r="ansi"){const s=L(r),n="html"===r,o=" ".repeat(t);if("object"!=typeof e||null===e)return M(e,r)+j(e)+s.reset;if(Array.isArray(e)){if(n){let n=[];return e.length&&(n=e.every(t=>typeof t==typeof e[0])?[_(e[0],t+1,r)]:e.map(e=>_(e,t+1,r))),`<details open><summary style="cursor:pointer;display:inline">${s.blue}[${s.reset}&thinsp;${e.length} × ${j(e[0]??void 0)}&thinsp;${s.blue}]${s.reset}</summary>${n.map(e=>`<div style="margin-left:1.5em">${e}</div>`).join("")}</details>`}let i=s.blue+"["+s.reset;return e.length&&(i+="\n"),e.every(t=>typeof t==typeof e[0])?i+=o+" "+_(e[0],t+1,r)+",\n":e.forEach((s,n)=>{i+=o+" "+_(s,t+1,r),n<e.length-1&&(i+=","),i+="\n"}),i+=o+s.blue+"]"+s.reset,i}const i=Object.keys(e);if(n){const n=i.slice(0,4).join(", ")+(i.length>4?"…":"");return`<details open><summary style="cursor:pointer">${s.green}{${s.reset}&nbsp;${n}&nbsp;${s.green}}${s.reset}</summary>${i.map(n=>{const o=e[n],i=M(o,r);return"object"==typeof o&&null!==o?`<div style="margin-left:1.5em">${i}${n}${s.reset}: ${_(o,t+1,r)}</div>`:`<div style="margin-left:1.5em">${i}${n}: ${j(o)}${s.reset}</div>`}).join("")}</details>`}let a=s.green+"{"+s.reset;return i.length&&(a+="\n"),i.forEach((n,l)=>{const c=e[n],u=M(c,r);a+=o+" ",a+="object"==typeof c&&null!==c?u+n+s.reset+": "+_(c,t+1,r):u+n+": "+j(c)+s.reset,l<i.length-1&&(a+=","),a+="\n"}),a+=o+s.green+"}"+s.reset,a}function U(e="",t={}){let{color:r,style:s="color:rgb(54, 165, 220); font-size: 10pt;",hideInProduction:n,startSpinner:o=!1,stopSpinner:i=!1}=t;const a=L();void 0===n&&(n="undefined"!=typeof window&&window?.location.hostname.includes("localhost")),"object"==typeof e&&(e=_(e)+"\n\n"+JSON.stringify(e,null,2)),Array.isArray(r)&&1==r.length&&(r=r[0]),r&&"undefined"!=typeof process&&("string"==typeof e&&e.includes("%c")&&Array.isArray(r)?e=e.replace(/%c/g,(e,t)=>a[r[t]]||""):r&&"string"==typeof r&&(e=(a[r]||"")+e+a.reset));var l=0;return o?globalThis.interval=setInterval(()=>{process.stdout.write((Array.isArray(r)?a[r[0]]:a[r]||"")+"\r"+"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏".split("")[l=++l%10]+" "+e+a.reset)},50):i?(clearInterval(globalThis.interval),process.stdout.write("\r"+(e||" ")+" ".repeat("string"==typeof e?e.length+20:40)+"\n")):"string"==typeof s?(1==s.split(" ").length||r?s=`color: ${r||s}; font-size: 11pt;`:s.match(/^#[0-9a-fA-F]{6}$/)&&(s=`color: ${s}; font-size: 11pt;`),n||console.log((s?"%c":"")+(e||""),s)):"object"==typeof s&&console.log(e,...s),!0}function N(e){if("undefined"==typeof document)return;let t,r=document.getElementById("alert-overlay");if(!r){r=document.body.appendChild(document.createElement("div")),r.id="alert-overlay",r.setAttribute("style","position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center"),r.innerHTML='<div id="alert-box" style="background:#fff;padding:1.5em 2em;border-radius:8px;box-shadow:0 2px 16px #0003;min-width:320px;max-width:90vw;max-height:80vh;position:relative;display:flex;flex-direction:column;">\n <button id="close-alert" style="position:absolute;top:12px;right:20px;font-size:1.5em;background:none;border:none;cursor:pointer;color:black;">&times;</button>\n <div id="alert-list" style="overflow:auto;flex:1;font-family:monospace;font-size:13px;"></div>\n </div>',r.addEventListener("click",e=>e.target==r&&r.remove());const e=document.getElementById("close-alert");e&&(e.onclick=()=>r.remove())}t=document.getElementById("alert-list"),t.innerHTML+=`<div style="border-bottom:1px solid #e5e7eb;margin:0.5em 0;padding-bottom:0.5em">${e}</div>`}function D(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}async function q(e){const{extract:t}=await Promise.resolve().then(()=>require("./archiver-web.es-3EQgnnex.js")),r=await t({archiveBuffer:e}),s={};for(const n of r)s[n.path]=n.content;return s}async function F(e,t){const{parseHTML:r}=await Promise.resolve().then(()=>require("./index-CLlAnStL-DDV_Pgc5.js")),{document:s}=r(e);if(!t||!0===t)return s;const n=s.querySelector(t);return n?n.innerHTML??n.textContent:null}var G=function(e){return async function t(r,s){const n=(o=s,{..."undefined"!=typeof window?window?.grab?.defaults:globalThis?.grab?.defaults||{},...o});var o;let{headers:i,response:a,method:l=(n.post?"POST":n.put?"PUT":n.patch?"PATCH":"GET"),cache:c,timeout:u=30,baseURL:p="undefined"!=typeof process&&process.env.SERVER_API_URL||"/api/",cancelOngoingIfNew:h,cancelNewIfOngoing:d,rateLimit:g,debug:f,infiniteScroll:y,logger:m=U,onRequest:b,onResponse:w,onError:T,onStream:x,unzip:v,dom:E,body:A,post:C,put:R,patch:S,...P}=n;const O=((e,t)=>{let r=e=>t?.startsWith(e)||!1,s=e,n=t;return t?.startsWith("http:")||t?.startsWith("https:")?s="":r("/")||s.endsWith("/")?r("/")&&s.endsWith("/")&&(n=t.slice(1)):n="/"+t,{baseURL:s,path:n}})(p,r);p=O.baseURL,r=O.path;const I=function(e){const t="function"==typeof e?e:null;return{response:!e||t?{}:e,resFunction:t}}(a);let k=I.response,$=I.resFunction;const L=("undefined"!=typeof window?window.grab:globalThis.grab)?.log||[];$?k=$({...k,isLoading:!0}):"object"==typeof k&&(k.isLoading=!0);try{const o=await async function(e,t,r,s){const{debounce:n=0,repeat:o=0,repeatEvery:i=null,setDefaults:a=!1}=r;if(n>0)return await(await(async(e,t)=>{let r;return async function(...s){clearTimeout(r),r=setTimeout(async()=>{clearTimeout(r),await e(...s)},t)}})(async()=>{await s(e,{...t,debounce:0})},1e3*n))(),r.response||{};if(o>1){for(let r=0;r<o;r++)await s(e,{...t,repeat:0});return r.response||{}}if(i)return setInterval(async()=>{await s(e,{...t,repeat:0,repeatEvery:null})},1e3*i),r.response||{};if(a){const e="undefined"!=typeof window?window.grab:globalThis.grab;return e&&(e.defaults={...t,setDefaults:void 0}),r.response||{}}return null}(r,s||{},n,t);if(o)return o;!function(e,t,r,s){if("undefined"==typeof window)return;const{regrabOnStale:n,regrabOnFocus:o,regrabOnNetwork:i,cache:a,cacheForTime:l=60}=r,c=async()=>await s(e,{...t,cache:!1});n&&a&&setTimeout(c,1e3*l),i&&window.addEventListener("online",c),o&&(window.addEventListener("focus",c),document.addEventListener("visibilitychange",async()=>{"visible"===document.visibilityState&&await c()}))}(r,s||{},n,t);let{params:a,priorRequest:T,response:C,paramsAsText:R}=function(e,t,r,s,n,o){const{cache:i,cacheForTime:a,infiniteScroll:l}=r,[c,u]=l||[],p=JSON.stringify(c?{...t,[c]:void 0}:t);let h=o.find(t=>t.request===p&&t.path===e);if(c){let e=(h?.currentPage||0)+1||t?.[c]||1;h?h.currentPage=e:(s[u]=[],e=1),t={...t,[c]:e}}else{for(let e of Object.keys(s))s[e]=void 0;if(i&&h?.response&&(!a||h.lastFetchTime>Date.now()-1e3*a)){for(let e of Object.keys(h.response))s[e]=h.response[e];n&&(s=n(s))}}return{params:t,priorRequest:h,response:s,paramsAsText:p}}(r,P,n,k,$,L);if(P=a,k=C,function(e,t,r,s,n){if("undefined"==typeof window||!r?.length)return;const[o,,i]=r;if(void 0===i)return;let a="string"==typeof i?document.querySelector(i):i;a?(window.scrollListener&&"function"==typeof a.removeEventListener&&a.removeEventListener("scroll",window.scrollListener),window.scrollListener=r=>{const a=r.target;localStorage.setItem("scroll",JSON.stringify([a.scrollTop,a.scrollLeft,i])),a.scrollHeight-a.scrollTop<=a.clientHeight+200&&n(e,{...t,cache:!1,[o]:(s?.currentPage||0)+1})},a.addEventListener("scroll",window.scrollListener)):U("paginateDOM not found",{color:"red"})}(r,s,y,T,t),g>0&&T?.lastFetchTime>Date.now()-1e3*g)throw new Error(`Fetch rate limit exceeded for ${r}. Wait ${g}s between requests.`);if(T?.controller)if(h)T.controller.abort();else if(d)return{isLoading:!0};const S=new AbortController;let O=S.signal;h||"function"!=typeof AbortSignal.timeout||(O=AbortSignal.timeout(1e3*u)),L.unshift({path:r,request:R,lastFetchTime:Date.now(),controller:S});let{fetchParams:I,paramsGETRequest:M}=function(e,t,r,s,n,o){const i=["POST","PUT","PATCH"].includes(e),a={method:e,headers:{"Content-Type":"application/json",Accept:"application/json",...t},body:r||(i?JSON.stringify(s):null),redirect:"follow",cache:n?"force-cache":"no-store",signal:o};let l="";return i||(l=(Object.keys(s).length?"?":"")+new URLSearchParams(s).toString()),{fetchParams:a,paramsGETRequest:l}}(l,i,A,P,!!c,O);if("function"==typeof b){const e=b(r,k,P,I);Array.isArray(e)&&([r,k,P,I]=e)}const j=new Date,N=await e(p,r,M,I,P,x,v,E);if($?k=$({...k,isLoading:void 0}):"object"==typeof k&&delete k.isLoading,"function"==typeof w){const e=w(r,k,P,I);Array.isArray(e)&&([r,k,P,I]=e)}const D=((Number(new Date)-Number(j))/1e3).toFixed(1);f&&m(`Path:${p+r+M}\n${JSON.stringify(s,null,2)}\nTime: ${D}s\nResponse: ${_(N)}`);const[,q]=y||[];return k=function(e,t,r,s){if("object"==typeof e&&null!==e){for(let r of Object.keys(e))t[r]=s===r&&Array.isArray(t[r])?[...t[r],...e[r]]:e[r];t.data=e}else r?t=r({data:e,...e}):"object"==typeof t&&(t.data=e);return t}(N,k,$,q),L[0]&&(L[0].response=k),$&&(k=$(k)),k}catch(M){if("function"==typeof T&&T(M.message,p+r,P),n.retryAttempts&&n.retryAttempts>0)return await t(r,{...s,retryAttempts:--n.retryAttempts});!M.message.includes("signal")&&f&&(m(`Error: ${M.message}\nPath:${p+r}\n`,{color:"red"}),"undefined"!=typeof document&&N(M.message)),k=k||{},k.error=M.message;const e="function"==typeof a?a:null;return e?(k.data=e({isLoading:void 0,error:M.message}),k=k.data):delete k.isLoading,k}}}(async function(e,t,r,s,n,o,i,a){const l=("undefined"!=typeof window?window.grab:globalThis.grab)?.mock?.[t],c=JSON.stringify(n);if(l&&(!l.method||l.method===s.method)&&(!l.params||c===JSON.stringify(l.params)))return await(e=>new Promise(t=>setTimeout(t,1e3*e||0)))(l.delay||0),"function"==typeof l.response?l.response(n):l.response;const u=await fetch(e+t+r,s).catch(e=>{throw new Error(e.message)});if(!u.ok)throw new Error(`HTTP error: ${u.status} ${u.statusText}`);if(o)return await o(u.body),null;const p=u.headers.get("content-type")??"",h=!1!==i&&(p.includes("application/zip")||p.includes("application/x-zip")),d=!1!==a&&("string"==typeof a||p.includes("text/html"));return h?{data:await q(await u.arrayBuffer().catch(e=>{throw new Error("Error reading zip: "+e)}))}:d?{data:await F(await u.text().catch(e=>{throw new Error("Error reading html: "+e)}),"string"!=typeof a||a)}:await(p.includes("application/json")?u.json():p.includes("application/pdf")||p.includes("application/octet-stream")?u.blob():p?u.text():u.json()).catch(e=>{throw new Error("Error parsing response: "+e)})}),W=G;W.instance=(e={})=>(t,r={})=>G(t,{...e,...r}),W.log=[],W.mock={},W.defaults={},"undefined"!=typeof window?(window.log=U,window.grab=W,"undefined"!=typeof document&&document.addEventListener("keydown",e=>{const t=window.grab;if(t&&t.log&&"i"===e.key&&e.ctrlKey&&e.altKey){let e="";for(const r of t.log){const t=new Date(r.lastFetchTime).toLocaleString(),s=_(r.request,0,"html"),n=_(r.response,0,"html"),o=D(JSON.stringify(r.response,null,2));e+=`\n <details open style="margin-bottom:0.75em">\n <summary style="cursor:pointer;font-weight:bold;padding:4px 0;list-style:none;display:flex;justify-content:space-between">\n <span style="color:#1a56db">${D(r.path)}</span>\n <span style="color:#6b7280;font-weight:normal;margin-left:1em">${t}</span>\n </summary>\n <div style="padding-left:1em;margin-top:0.5em">\n <details style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Request</summary>\n <div style="padding:0.4em 0 0 1em">${s}</div>\n </details>\n <details open style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Response (structure)</summary>\n <div style="padding:0.4em 0 0 1em">${n}</div>\n </details>\n <details style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Response (data)</summary>\n <pre style="margin:0.4em 0 0 1em;padding:0.5em;background:#f9fafb;border:1px solid #e5e7eb;border-radius:4px;overflow:auto;max-height:300px;font-size:12px">${o}</pre>\n </details>\n </div>\n </details>`}N(e||"<em>No requests logged yet.</em>")}}),document.addEventListener("DOMContentLoaded",()=>{try{const e=localStorage.getItem("scroll");if(!e)return;const[t,r,s]=JSON.parse(e);if(!t||!s)return;const n=document.querySelector(s);n&&(n.scrollTop=t,n.scrollLeft=r)}catch($){console.warn("Failed to restore scroll position",$)}})):"undefined"!=typeof globalThis&&(globalThis.log=U,globalThis.grab=W);var B,H=class{constructor(){this.requestHeaders={},this.proxyConfiguration={},this.requestHeaders["Accept-Language"]="en-US"}setHeader(e,t){this.requestHeaders[e]=t}setProxies(e){this.proxyConfiguration=e}async get(e,t){const r=this.getProxyAgentForUrl(e);return W(e,{...t,method:"GET",headers:{...this.requestHeaders,...t?.headers},agent:r})}async post(e,t){const r=this.getProxyAgentForUrl(e);return W(e,{...t,method:"POST",headers:{...this.requestHeaders,...t?.headers},agent:r})}getProxyAgentForUrl(e){if(0===Object.keys(this.proxyConfiguration).length)return;const t=e.startsWith("https://")?this.proxyConfiguration.https:this.proxyConfiguration.http;return t?new r.HttpsProxyAgent(t):void 0}};var Y=class e extends Error{constructor(t){super(t),this.name="InvalidProxyConfig",Object.setPrototypeOf(this,e.prototype)}},z=class{get preventKeepingConnectionsAlive(){return!1}get retriesWhenBlocked(){return 0}},J=class extends z{constructor(e){super();const{httpUrl:t,httpsUrl:r}=e;if(!t&&!r)throw new Y("GenericProxyConfig requires you to define at least one of the two: http or https");this._httpUrl=t||null,this._httpsUrl=r||null}get httpUrl(){return this._httpUrl}get httpsUrl(){return this._httpsUrl}toRequestsDict(){return{http:this.httpUrl||this.httpsUrl,https:this.httpsUrl||this.httpUrl}}},V=class e extends J{constructor(t){super({httpUrl:"placeholder"}),this.proxyUsername=t.proxyUsername,this.proxyPassword=t.proxyPassword,this.domainName=t.domainName||e.DEFAULT_DOMAIN_NAME,this.proxyPort=t.proxyPort||e.DEFAULT_PORT,this.filterIpLocations=t.filterIpLocations||[],this._retriesWhenBlocked=t.retriesWhenBlocked??10}get url(){const e=this.filterIpLocations.map(e=>`-${e.toUpperCase()}`).join("");let t=this.proxyUsername;const r="-rotate";return t.endsWith(r)&&(t=t.slice(0,-7)),`http://${t}${e}${r}:${this.proxyPassword}@${this.domainName}:${this.proxyPort}/`}get httpUrl(){return this.url}get httpsUrl(){return this.url}toRequestsDict(){return{http:this.url,https:this.url}}get preventKeepingConnectionsAlive(){return!0}get retriesWhenBlocked(){return this._retriesWhenBlocked}};(B=V).DEFAULT_DOMAIN_NAME="p.webshare.io",B.DEFAULT_PORT=80;var K=class{},X=class extends K{formatTranscript(e){return JSON.stringify(e.toRawData(),null,2)}formatTranscripts(e){return JSON.stringify(e.map(e=>e.toRawData()),null,2)}},Q=class extends K{formatTranscript(e,t){return JSON.stringify(e.toRawData(),null,t?.indent)}formatTranscripts(e,t){return JSON.stringify(e.map(e=>e.toRawData()),null,t?.indent)}},Z=class extends K{formatTranscript(e){return e.snippets.map(e=>e.text).join("\n")}formatTranscripts(e){return e.map(e=>this.formatTranscript(e)).join("\n\n\n")}},ee=class extends K{formatTranscript(e){const t=e.snippets.map(e=>e.text).join(" "),r=[];let s=0;for(const g of e.snippets)r.push([s,g.start]),s+=g.text.length+1;const n={};for(const[g,f]of r){const e=Math.floor(g/f)-10;n[Math.floor(g/100)]=e}const o=Object.keys(n).map(e=>n[parseInt(e)]),i=[],a=[];let l=o[0],c=1;for(let g=1;g<o.length;g++)o[g]===l?c++:(i.push(l),a.push(c),l=o[g],c=1);i.push(l),a.push(c);let u=0;const p=a.map(e=>(u+=e,u)),h=i.join(",")+" "+p.join(","),d=t.replace(/\s+/g," ");return JSON.stringify({text:d,timestamps:h,wordCount:d.split(/\s+/).length,charCount:d.length},null,2)}formatTranscripts(e){return e.map(e=>this.formatTranscript(e)).join("\n\n")}},te=class extends Z{secondsToTimestamp(e){const t=Math.floor(e/3600),r=e%3600,s=Math.floor(r/60),n=Math.floor(r%60),o=Math.round(1e3*(e-Math.floor(e)));return this.formatTimestamp(t,s,n,o)}formatTranscript(e){const t=[];for(let r=0;r<e.snippets.length;r++){const s=e.snippets[r],n=s.start+s.duration,o=r<e.snippets.length-1&&e.snippets[r+1].start<n?e.snippets[r+1].start:n,i=`${this.secondsToTimestamp(s.start)} --\x3e ${this.secondsToTimestamp(o)}`;t.push(this.formatSubtitleEntry(r,i,s))}return this.formatTranscriptHeader(t)}},re=class extends te{formatTimestamp(e,t,r,s){const n=(e,t)=>e.toString().padStart(t,"0");return`${n(e,2)}:${n(t,2)}:${n(r,2)},${n(s,3)}`}formatTranscriptHeader(e){return e.join("\n\n")+"\n"}formatSubtitleEntry(e,t,r){return`${e+1}\n${t}\n${r.text}`}},se=class extends te{formatTimestamp(e,t,r,s){const n=(e,t)=>e.toString().padStart(t,"0");return`${n(e,2)}:${n(t,2)}:${n(r,2)}.${n(s,3)}`}formatTranscriptHeader(e){return"WEBVTT\n\n"+e.join("\n\n")+"\n"}formatSubtitleEntry(e,t,r){return`${t}\n${r.text}`}},ne=class e extends Error{constructor(t){super(`Unknown formatter type: ${t}. Available types: json, text, srt, webvtt, pretty, article`),this.name="UnknownFormatterType",Object.setPrototypeOf(this,e.prototype)}};exports.AgeRestricted=d,exports.ArticleFormatter=ee,exports.CookieError=a,exports.CookieInvalid=class e extends a{constructor(t){super(`The cookies provided are not valid (may have expired): ${t}`),this.name="CookieInvalid",Object.setPrototypeOf(this,e.prototype)}},exports.CookiePathInvalid=class e extends a{constructor(t){super(`Can't load the provided cookie file: ${t}`),this.name="CookiePathInvalid",Object.setPrototypeOf(this,e.prototype)}},exports.CouldNotRetrieveTranscript=i,exports.FailedToCreateConsentCookie=g,exports.FetchedTranscript=v,exports.Formatter=K,exports.FormatterLoader=class{load(e){const t=e?.toLowerCase()||"pretty";switch(t){case"json":return new Q;case"text":return new Z;case"article":return new ee;case"srt":return new re;case"webvtt":return new se;case"pretty":return new X;default:throw new ne(t)}}},exports.GenericProxyConfig=J,exports.InvalidProxyConfig=Y,exports.InvalidVideoId=h,exports.IpBlocked=x,exports.JSONFormatter=Q,exports.NoTranscriptFound=b,exports.NotTranslatable=y,exports.PlayabilityFailedReason=P,exports.PlayabilityStatus=S,exports.PoTokenRequired=w,exports.PrettyPrintFormatter=X,exports.ProxyConfig=z,exports.RequestBlocked=T,exports.SRTFormatter=re,exports.TextFormatter=Z,exports.Transcript=C,exports.TranscriptList=R,exports.TranscriptListFetcher=k,exports.TranscriptsDisabled=f,exports.TranslationLanguageNotAvailable=m,exports.UnknownFormatterType=ne,exports.VideoUnavailable=p,exports.VideoUnplayable=u,exports.WebVTTFormatter=se,exports.WebshareProxyConfig=V,exports.YouTubeDataUnparsable=l,exports.YouTubeRequestFailed=c,exports.YouTubeTranscriptApi=class{constructor(e){const t=this.initializeHttpClient(e);this.configureHttpClientWithProxy(t,e?.proxyConfig),this.transcriptListFetcher=new k(t,e?.proxyConfig||null)}initializeHttpClient(e){return e?.httpClient||new H}configureHttpClientWithProxy(e,t){if(!(t&&e instanceof H))return;const r=t.toRequestsDict();e.setProxies(r),t.preventKeepingConnectionsAlive&&e.setHeader("Connection","close")}async fetchTranscript(e,t){const r=t?.languages||["en"],s=t?.preserveFormatting||!1;return(await this.listTranscripts(e)).findTranscript(r).fetch(s)}async listTranscripts(e){return this.transcriptListFetcher.fetchTranscriptList(e)}async fetch(e,t){return this.fetchTranscript(e,t)}async list(e){return this.listTranscripts(e)}},exports.YouTubeTranscriptApiException=o,exports.decompressTimestampsArray=function(e){const t=[];for(const r of e.split(",")){const[e,s]=r.split("x");t.push(...Array(parseInt(s)).fill(parseInt(e)))}return t},exports.encodeTranscriptSpeeds=function(e,t=!1){let r=0;const s=[],n=[];for(const d of e.snippets)n.push(d.text),r+=d.text.length,d.start>0&&s.push([r,d.start]);const o=n.join(" ").replace(/\s+/g," "),i=o.split(/\s+/).filter(Boolean).length,a=s.map(([e,t])=>Math.floor(e/t)-10);if(0===a.length)return{html:o,word_count:i,speeds:""};const l=[],c=[];let u=a[0],p=1;for(let d=1;d<a.length;d++)a[d]===u?p++:(l.push(u),c.push(p),u=a[d],p=1);l.push(u),c.push(p);const h=l.map((e,t)=>`${e}x${c[t]}`).join(",");return{html:t?`<iframe width="100%" height="315px" data-timestamps="${h}" src="https://www.youtube.com/embed/${e.videoId}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>${o}`:o,word_count:i,speeds:h}},exports.getTimestampAtChar=function(e,t){let r=0;const s=[[0,0]];for(const n of e.snippets)r+=n.text.length+1,s.push([r,n.start]);if(t<=0)return 0;if(t>=s[s.length-1][0])return s[s.length-1][1];for(let n=1;n<s.length;n++)if(s[n][0]>=t){const[e,r]=s[n-1],[o,i]=s[n];return r+(t-e)/(o-e)*(i-r)}return s[s.length-1][1]};
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});let e=require("html-entities"),t=require("fast-xml-parser"),r=require("https-proxy-agent");var s,n,o=class e extends Error{constructor(t){super(t),this.name="YouTubeTranscriptApiException",Object.setPrototypeOf(this,e.prototype)}},i=class e extends o{constructor(t){super(""),this.causeMessage="",this.videoId=t,Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}buildErrorMessage(){const t="https://www.youtube.com/watch?v={video_id}".replace("{video_id}",this.videoId);let r=e.ERROR_MESSAGE.replace("{video_url}",t);const s=this.getCause();return s&&(r+=e.CAUSE_MESSAGE_INTRO.replace("{cause}",s),r+=e.GITHUB_REFERRAL),r}getCause(){return this.causeMessage}};(s=i).ERROR_MESSAGE="\nCould not retrieve a transcript for the video {video_url}!",s.CAUSE_MESSAGE_INTRO=" This is most likely caused by:\n\n{cause}",s.GITHUB_REFERRAL="\n\nIf you are sure that the described cause is not responsible for this error and that a transcript should be retrievable, please create an issue at https://github.com/jdepoix/youtube-transcript-api/issues. Please add which version of youtube_transcript_api you are using and provide the information needed to replicate the error. Also make sure that there are no open issues which already describe your problem!";var a=class e extends o{constructor(t){super(t),this.name="CookieError",Object.setPrototypeOf(this,e.prototype)}},l=class e extends i{constructor(t){super(t),this.causeMessage="The data required to fetch the transcript is not parsable. This should not happen, please open an issue (make sure to include the video ID)!",this.name="YouTubeDataUnparsable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},c=class e extends i{constructor(t,r){super(t),this.httpErrorReason=r.message,this.name="YouTubeRequestFailed",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){return`Request to YouTube failed: ${this.httpErrorReason}`}},u=class e extends i{constructor(t,r,s){super(t),this.unplayableReason=r,this.additionalDetails=s,this.name="VideoUnplayable",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){let e=this.unplayableReason??"No reason specified!";if(this.additionalDetails.length>0){e=`${e}\n\nAdditional Details:\n${this.additionalDetails.map(e=>` - ${e}`).join("\n")}`}return`The video is unplayable for the following reason: ${e}`}},p=class e extends i{constructor(t){super(t),this.causeMessage="The video is no longer available",this.name="VideoUnavailable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},h=class e extends i{constructor(t){super(t),this.causeMessage='You provided an invalid video id. Make sure you are using the video id and NOT the url!\n\nDo NOT run: `new YouTubeTranscriptApi().fetch("https://www.youtube.com/watch?v=1234")`\nInstead run: `new YouTubeTranscriptApi().fetch("1234")`',this.name="InvalidVideoId",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},d=class e extends i{constructor(t){super(t),this.causeMessage="This video is age-restricted. Therefore, you are unable to retrieve transcripts for it without authenticating yourself.\n\nUnfortunately, Cookie Authentication is temporarily unsupported in youtube-transcript-api, as recent changes in YouTube's API broke the previous implementation. I will do my best to re-implement it as soon as possible.",this.name="AgeRestricted",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},g=class e extends i{constructor(t){super(t),this.causeMessage="Failed to automatically give consent to saving cookies",this.name="FailedToCreateConsentCookie",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},f=class e extends i{constructor(t){super(t),this.causeMessage="Subtitles are disabled for this video",this.name="TranscriptsDisabled",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},y=class e extends i{constructor(t){super(t),this.causeMessage="The requested language is not translatable",this.name="NotTranslatable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},m=class e extends i{constructor(t){super(t),this.causeMessage="The requested translation language is not available",this.name="TranslationLanguageNotAvailable",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},b=class e extends i{constructor(t,r,s){super(t),this.requestedLanguageCodes=r,this.availableTranscriptData=s,this.name="NoTranscriptFound",this.message=this.buildErrorMessage(),Object.setPrototypeOf(this,e.prototype)}getCause(){return`No transcripts were found for any of the requested language codes: ${this.requestedLanguageCodes.join(", ")}\n\n`+this.availableTranscriptData.toString()}},w=class e extends i{constructor(t){super(t),this.causeMessage="The requested video cannot be retrieved without a PO Token. If this happens, please open a GitHub issue!",this.name="PoTokenRequired",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}},T=class e extends i{constructor(t){super(t),this.proxyConfig=null,this.name="RequestBlocked",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}withProxyConfig(e){return this.proxyConfig=e,this.message=this.buildErrorMessage(),this}getCause(){return this.proxyConfig&&"WebshareProxyConfig"===this.proxyConfig.constructor.name?e.WITH_WEBSHARE_PROXY_CAUSE_MESSAGE:this.proxyConfig&&"GenericProxyConfig"===this.proxyConfig.constructor.name?e.WITH_GENERIC_PROXY_CAUSE_MESSAGE:e.DEFAULT_CAUSE_MESSAGE}};(n=T).BASE_CAUSE_MESSAGE="YouTube is blocking requests from your IP. This usually is due to one of the following reasons:\n- You have done too many requests and your IP has been blocked by YouTube\n- You are doing requests from an IP belonging to a cloud provider (like AWS, Google Cloud Platform, Azure, etc.). Unfortunately, most IPs from cloud providers are blocked by YouTube.\n\n",n.DEFAULT_CAUSE_MESSAGE=n.BASE_CAUSE_MESSAGE+'There are two things you can do to work around this:\n1. Use proxies to hide your IP address, as explained in the "Working around IP bans" section of the README (https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#working-around-ip-bans-requestblocked-or-ipblocked-exception).\n2. (NOT RECOMMENDED) If you authenticate your requests using cookies, you will be able to continue doing requests for a while. However, YouTube will eventually permanently ban the account that you have used to authenticate with! So only do this if you don\'t mind your account being banned!',n.WITH_GENERIC_PROXY_CAUSE_MESSAGE='YouTube is blocking your requests, despite you using proxies. Keep in mind that a proxy is just a way to hide your real IP behind the IP of that proxy, but there is no guarantee that the IP of that proxy won\'t be blocked as well.\n\nThe only truly reliable way to prevent IP blocks is rotating through a large pool of residential IPs, by using a provider like Webshare (https://www.webshare.io/?referral_code=w0xno53eb50g), which provides you with a pool of >30M residential IPs (make sure to purchase "Residential" proxies, NOT "Proxy Server" or "Static Residential"!).\n\nYou will find more information on how to easily integrate Webshare here: https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#using-webshare',n.WITH_WEBSHARE_PROXY_CAUSE_MESSAGE='YouTube is blocking your requests, despite you using Webshare proxies. Please make sure that you have purchased "Residential" proxies and NOT "Proxy Server" or "Static Residential", as those won\'t work as reliably! The free tier also uses "Proxy Server" and will NOT work!\n\nThe only reliable option is using "Residential" proxies (not "Static Residential"), as this allows you to rotate through a pool of over 30M IPs, which means you will always find an IP that hasn\'t been blocked by YouTube yet!\n\nYou can support the development of this open source project by making your Webshare purchases through this affiliate link: https://www.webshare.io/?referral_code=w0xno53eb50g \n\nThank you for your support! <3';var x=class e extends T{constructor(t){super(t),this.causeMessage='YouTube is blocking requests from your IP. This usually is due to one of the following reasons:\n- You have done too many requests and your IP has been blocked by YouTube\n- You are doing requests from an IP belonging to a cloud provider (like AWS, Google Cloud Platform, Azure, etc.). Unfortunately, most IPs from cloud providers are blocked by YouTube.\n\nWays to work around this are explained in the "Working around IP bans" section of the README (https://github.com/jdepoix/youtube-transcript-api?tab=readme-ov-file#working-around-ip-bans-requestblocked-or-ipblocked-exception).\n',this.name="IpBlocked",Object.setPrototypeOf(this,e.prototype),this.message=this.buildErrorMessage()}getCause(){return this.causeMessage}},v=class{constructor(e,t,r,s,n){this.snippets=e,this.videoId=t,this.language=r,this.languageCode=s,this.isGenerated=n}[Symbol.iterator](){return this.snippets[Symbol.iterator]()}getSnippetAtIndex(e){return this.snippets[e]}get(e){return this.getSnippetAtIndex(e)}get length(){return this.snippets.length}toRawData(){return this.snippets.map(e=>({text:e.text,start:e.start,duration:e.duration}))}},E=class r{constructor(e=!1){this.htmlRemovalRegex=this.buildHtmlRemovalRegex(e)}buildHtmlRemovalRegex(e){if(e){const e=`<\\/?(?!\\/?(?:${r.FORMATTING_TAGS.join("|")})\\b).*?\\b>`;return new RegExp(e,"gi")}return/<[^>]*>/gi}parseTranscriptXml(e){const r=new t.XMLParser({ignoreAttributes:!1,attributeNamePrefix:"@_"}).parse(e).transcript?.text||[];return(Array.isArray(r)?r:[r]).filter(e=>e["#text"]).map(e=>this.parseTranscriptSnippet(e))}parseTranscriptSnippet(e){return{text:this.cleanTranscriptText(e["#text"]),start:this.parseFloatAttribute(e["@_start"]),duration:this.parseFloatAttribute(e["@_dur"])}}parseFloatAttribute(e){return parseFloat(e||"0")}cleanTranscriptText(t){return"string"!=typeof t&&(t=String(t||"")),(0,e.decode)(t).replace(this.htmlRemovalRegex,"")}};function A(e,t){if(429===e.status)throw new x(t);if(!e.ok){const r=`HTTP ${e.status}: ${e.statusText}`;throw new c(t,new Error(r))}}E.FORMATTING_TAGS=["strong","em","b","i","mark","small","del","ins","sub","sup"];var C=class e{constructor(e,t,r,s,n,o,i){this.httpClient=e,this.videoId=t,this.transcriptUrl=r,this.language=s,this.languageCode=n,this.isGenerated=o,this.translationLanguages=i,this.translationLanguagesMap=this.buildTranslationLanguagesMap(i)}buildTranslationLanguagesMap(e){const t={};for(const r of e)t[r.language_code]=r.language;return t}async fetch(e=!1){if(this.transcriptUrl.includes("&exp=xpe"))throw new w(this.videoId);const t=await this.httpClient.get(this.transcriptUrl);A(t,this.videoId);const r=await t.text(),s=new E(e).parseTranscriptXml(r);return new v(s,this.videoId,this.language,this.languageCode,this.isGenerated)}get isTranslatable(){return this.translationLanguages.length>0}translate(t){if(!this.isTranslatable)throw new y(this.videoId);if(!(t in this.translationLanguagesMap))throw new m(this.videoId);const r=`${this.transcriptUrl}&tlang=${t}`,s=this.translationLanguagesMap[t];return new e(this.httpClient,this.videoId,r,s,t,!0,[])}toString(){const e=this.isTranslatable?"[TRANSLATABLE]":"";return`${this.languageCode} ("${this.language}")${e}`}},R=class e{constructor(e,t,r,s){this.videoId=e,this.manuallyCreatedTranscripts=t,this.autoGeneratedTranscripts=r,this.availableTranslationLanguages=s}static buildFromCaptionsJson(t,r,s){const n=e.extractTranslationLanguages(s),{manualTranscripts:o,generatedTranscripts:i}=e.categorizeTranscripts(t,r,s,n);return new e(r,o,i,n)}static extractTranslationLanguages(e){return(e.translationLanguages||[]).map(e=>({language:e.languageName.runs[0].text,language_code:e.languageCode}))}static categorizeTranscripts(e,t,r,s){const n={},o={};for(const i of r.captionTracks){const r="asr"===i.kind,a=r?o:n,l=i.baseUrl.replace("&fmt=srv3",""),c=new C(e,t,l,i.name.runs[0].text,i.languageCode,r,i.isTranslatable?s:[]);a[i.languageCode]=c}return{manualTranscripts:n,generatedTranscripts:o}}[Symbol.iterator](){return[...Object.values(this.manuallyCreatedTranscripts),...Object.values(this.autoGeneratedTranscripts)][Symbol.iterator]()}findTranscript(e){return this.findTranscriptInMaps(e,[this.manuallyCreatedTranscripts,this.autoGeneratedTranscripts])}findGeneratedTranscript(e){return this.findTranscriptInMaps(e,[this.autoGeneratedTranscripts])}findManuallyCreatedTranscript(e){return this.findTranscriptInMaps(e,[this.manuallyCreatedTranscripts])}findTranscriptInMaps(e,t){for(const r of e)for(const e of t)if(r in e)return e[r];throw new b(this.videoId,e,this)}toString(){const e=e=>{const t=Object.values(e).map(e=>` - ${e.toString()}`);return t.length>0?t.join("\n"):"None"};return`For this video (${this.videoId}) transcripts are available in the following languages:\n\n(MANUALLY CREATED)\n${e(this.manuallyCreatedTranscripts)}\n\n(GENERATED)\n${e(this.autoGeneratedTranscripts)}\n\n(TRANSLATION LANGUAGES)\n${(()=>{const e=this.availableTranslationLanguages.map(e=>` - ${e.language_code} ("${e.language}")`);return e.length>0?e.join("\n"):"None"})()}`}},S=function(e){return e.OK="OK",e.ERROR="ERROR",e.LOGIN_REQUIRED="LOGIN_REQUIRED",e}({}),P=function(e){return e.BOT_DETECTED="Sign in to confirm you're not a bot",e.AGE_RESTRICTED="This video may be inappropriate for some users.",e.VIDEO_UNAVAILABLE="This video is unavailable",e}({});function O(e,t){!function(e,t){if(!e)return;const r=e.status;if(r===S.OK||!r)return;const s=e.reason;if(r===S.LOGIN_REQUIRED){if(s===P.BOT_DETECTED)throw new T(t);if(s===P.AGE_RESTRICTED)throw new d(t)}if(r===S.ERROR&&s===P.VIDEO_UNAVAILABLE){if(t.startsWith("http://")||t.startsWith("https://"))throw new h(t);throw new p(t)}const n=function(e){const t=e.errorScreen?.playerErrorMessageRenderer?.subreason?.runs;return t&&Array.isArray(t)?t.map(e=>e.text||"").filter(e=>e.length>0):[]}(e);throw new u(t,s,n)}(e.playabilityStatus,t);const r=e.captions?.playerCaptionsTracklistRenderer;if(!r||!r.captionTracks)throw new f(t);return r}var I={client:{clientName:"ANDROID",clientVersion:"20.10.38"}},k=class{constructor(e,t){this.httpClient=e,this.proxyConfig=t}async fetchTranscriptList(e){const t=await this.fetchCaptionsJsonWithRetry(e);return R.buildFromCaptionsJson(this.httpClient,e,t)}async fetchCaptionsJsonWithRetry(e,t=0){try{const t=function(e,t){const r=e.match(/"INNERTUBE_API_KEY":\s*"([a-zA-Z0-9_-]+)"/);if(r&&2===r.length)return r[1];if(e.includes('class="g-recaptcha"'))throw new x(t);throw new l(t)}(await this.fetchVideoPageHtml(e),e);return O(await this.fetchInnertubePlayerData(e,t),e)}catch(r){if(r instanceof T)return this.handleBlockedRequest(r,e,t);throw r}}async handleBlockedRequest(e,t,r){if(r+1<(this.proxyConfig?.retriesWhenBlocked||0))return this.fetchCaptionsJsonWithRetry(t,r+1);throw e.withProxyConfig(this.proxyConfig)}async fetchVideoPageHtml(e){let t=await this.fetchAndDecodeHtml(e);if(this.isConsentPageDetected(t)&&(this.createConsentCookie(t,e),t=await this.fetchAndDecodeHtml(e),this.isConsentPageDetected(t)))throw new g(e);return t}isConsentPageDetected(e){return e.includes('action="https://consent.youtube.com/s"')}async fetchAndDecodeHtml(t){const r=this.buildWatchUrl(t),s=await this.httpClient.get(r);A(s,t);const n=await s.text();return(0,e.decode)(n)}buildWatchUrl(e){return"https://www.youtube.com/watch?v={video_id}".replace("{video_id}",e)}createConsentCookie(e,t){if(!e.match(/name="v" value="(.*?)"/))throw new g(t)}async fetchInnertubePlayerData(e,t){const r=this.buildInnertubeApiUrl(t),s=this.buildInnertubeRequestBody(e),n=await this.httpClient.post(r,{headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});return A(n,e),await n.json()}buildInnertubeApiUrl(e){return"https://www.youtube.com/youtubei/v1/player?key={api_key}".replace("{api_key}",e)}buildInnertubeRequestBody(e){return{context:I,videoId:e}}},$={reset:[0,"000000"],black:[30,"1f2937"],red:[31,"dc2626"],green:[32,"2d6a4f"],yellow:[33,"92400e"],blue:[34,"1a56db"],magenta:[35,"6d28d9"],cyan:[36,"0e7490"],white:[37,"374151"],gray:[90,"6b7280"],brightRed:[91,"ef4444"],brightGreen:[92,"059669"],brightYellow:[93,"d97706"],brightBlue:[94,"3b82f6"],brightMagenta:[95,"8b5cf6"],brightCyan:[96,"06b6d4"],brightWhite:[97,"f9fafb"],bgBlack:[40,"111827"],bgRed:[41,"fca5a5"],bgGreen:[42,"a7f3d0"],bgYellow:[43,"fde68a"],bgBlue:[44,"bfdbfe"],bgMagenta:[45,"ddd6fe"],bgCyan:[46,"a5f3fc"],bgWhite:[47,"f9fafb"],bgGray:[100,"d1d5db"],bgBrightRed:[101,"fee2e2"],bgBrightGreen:[102,"d1fae5"],bgBrightYellow:[103,"fef3c7"],bgBrightBlue:[104,"dbeafe"],bgBrightMagenta:[105,"ede9fe"],bgBrightCyan:[106,"cffafe"],bgBrightWhite:[107,"ffffff"]};function L(e="ansi"){const t={};for(const[r,[s,n]]of Object.entries($))t[r]="html"===e?"reset"===r?"</span>":`<span style="color:#${n}">`:"["+s+"m";return t}function M(e,t="ansi"){const r=L(t);return"string"==typeof e?r.yellow:"number"==typeof e?r.cyan:"boolean"==typeof e?r.magenta:"function"==typeof e?r.red:null===e?r.gray:Array.isArray(e)?r.blue:"object"==typeof e?r.green:r.white}function j(e){return"string"==typeof e?'""':"number"==typeof e?"number":"boolean"==typeof e?"bool":"function"==typeof e?"function":null===e?"null":Array.isArray(e)?e.length?"["+j(e[0])+"]":"[]":"object"==typeof e?"{...}":typeof e}function _(e,t=0,r="ansi"){const s=L(r),n="html"===r,o=" ".repeat(t);if("object"!=typeof e||null===e)return M(e,r)+j(e)+s.reset;if(Array.isArray(e)){if(n){let n=[];return e.length&&(n=e.every(t=>typeof t==typeof e[0])?[_(e[0],t+1,r)]:e.map(e=>_(e,t+1,r))),`<details open><summary style="cursor:pointer;display:inline">${s.blue}[${s.reset}&thinsp;${e.length} × ${j(e[0]??void 0)}&thinsp;${s.blue}]${s.reset}</summary>${n.map(e=>`<div style="margin-left:1.5em">${e}</div>`).join("")}</details>`}let i=s.blue+"["+s.reset;return e.length&&(i+="\n"),e.every(t=>typeof t==typeof e[0])?i+=o+" "+_(e[0],t+1,r)+",\n":e.forEach((s,n)=>{i+=o+" "+_(s,t+1,r),n<e.length-1&&(i+=","),i+="\n"}),i+=o+s.blue+"]"+s.reset,i}const i=Object.keys(e);if(n){const n=i.slice(0,4).join(", ")+(i.length>4?"…":"");return`<details open><summary style="cursor:pointer">${s.green}{${s.reset}&nbsp;${n}&nbsp;${s.green}}${s.reset}</summary>${i.map(n=>{const o=e[n],i=M(o,r);return"object"==typeof o&&null!==o?`<div style="margin-left:1.5em">${i}${n}${s.reset}: ${_(o,t+1,r)}</div>`:`<div style="margin-left:1.5em">${i}${n}: ${j(o)}${s.reset}</div>`}).join("")}</details>`}let a=s.green+"{"+s.reset;return i.length&&(a+="\n"),i.forEach((n,l)=>{const c=e[n],u=M(c,r);a+=o+" ",a+="object"==typeof c&&null!==c?u+n+s.reset+": "+_(c,t+1,r):u+n+": "+j(c)+s.reset,l<i.length-1&&(a+=","),a+="\n"}),a+=o+s.green+"}"+s.reset,a}function U(e="",t={}){let{color:r,style:s="color:rgb(54, 165, 220); font-size: 10pt;",hideInProduction:n,startSpinner:o=!1,stopSpinner:i=!1}=t;const a=L();void 0===n&&(n="undefined"!=typeof window&&window?.location.hostname.includes("localhost")),"object"==typeof e&&(e=_(e)+"\n\n"+JSON.stringify(e,null,2)),Array.isArray(r)&&1==r.length&&(r=r[0]),r&&"undefined"!=typeof process&&("string"==typeof e&&e.includes("%c")&&Array.isArray(r)?e=e.replace(/%c/g,(e,t)=>a[r[t]]||""):r&&"string"==typeof r&&(e=(a[r]||"")+e+a.reset));var l=0;return o?globalThis.interval=setInterval(()=>{process.stdout.write((Array.isArray(r)?a[r[0]]:a[r]||"")+"\r"+"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏".split("")[l=++l%10]+" "+e+a.reset)},50):i?(clearInterval(globalThis.interval),process.stdout.write("\r"+(e||" ")+" ".repeat("string"==typeof e?e.length+20:40)+"\n")):"string"==typeof s?(1==s.split(" ").length||r?s=`color: ${r||s}; font-size: 11pt;`:s.match(/^#[0-9a-fA-F]{6}$/)&&(s=`color: ${s}; font-size: 11pt;`),n||console.log((s?"%c":"")+(e||""),s)):"object"==typeof s&&console.log(e,...s),!0}function N(e){if("undefined"==typeof document)return;let t,r=document.getElementById("alert-overlay");if(!r){r=document.body.appendChild(document.createElement("div")),r.id="alert-overlay",r.setAttribute("style","position:fixed;inset:0;z-index:9999;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center"),r.innerHTML='<div id="alert-box" style="background:#fff;padding:1.5em 2em;border-radius:8px;box-shadow:0 2px 16px #0003;min-width:320px;max-width:90vw;max-height:80vh;position:relative;display:flex;flex-direction:column;">\n <button id="close-alert" style="position:absolute;top:12px;right:20px;font-size:1.5em;background:none;border:none;cursor:pointer;color:black;">&times;</button>\n <div id="alert-list" style="overflow:auto;flex:1;font-family:monospace;font-size:13px;"></div>\n </div>',r.addEventListener("click",e=>e.target==r&&r.remove());const e=document.getElementById("close-alert");e&&(e.onclick=()=>r.remove())}t=document.getElementById("alert-list"),t.innerHTML+=`<div style="border-bottom:1px solid #e5e7eb;margin:0.5em 0;padding-bottom:0.5em">${e}</div>`}function D(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}async function q(e){const{extract:t}=await Promise.resolve().then(()=>require("./archiver-web.es-DoAYzzd1.js")),r=await t({archiveBuffer:e}),s={};for(const n of r)s[n.path]=n.content;return s}async function F(e,t){const{parseHTML:r}=await Promise.resolve().then(()=>require("./index-CLlAnStL-DDV_Pgc5.js")),{document:s}=r(e);if(!t||!0===t)return s;const n=s.querySelector(t);return n?n.innerHTML??n.textContent:null}var G=function(e){return async function t(r,s){const n=(o=s,{..."undefined"!=typeof window?window?.grab?.defaults:globalThis?.grab?.defaults||{},...o});var o;let{headers:i,response:a,method:l=(n.post?"POST":n.put?"PUT":n.patch?"PATCH":"GET"),cache:c,timeout:u=30,baseURL:p="undefined"!=typeof process&&process.env.SERVER_API_URL||"/api/",cancelOngoingIfNew:h,cancelNewIfOngoing:d,rateLimit:g,debug:f,infiniteScroll:y,logger:m=U,onRequest:b,onResponse:w,onError:T,onStream:x,unzip:v,dom:E,body:A,post:C,put:R,patch:S,...P}=n;const O=((e,t)=>{let r=e=>t?.startsWith(e)||!1,s=e,n=t;return t?.startsWith("http:")||t?.startsWith("https:")?s="":r("/")||s.endsWith("/")?r("/")&&s.endsWith("/")&&(n=t.slice(1)):n="/"+t,{baseURL:s,path:n}})(p,r);p=O.baseURL,r=O.path;const I=function(e){const t="function"==typeof e?e:null;return{response:!e||t?{}:e,resFunction:t}}(a);let k=I.response,$=I.resFunction;const L=("undefined"!=typeof window?window.grab:globalThis.grab)?.log||[];$?k=$({...k,isLoading:!0}):"object"==typeof k&&(k.isLoading=!0);try{const o=await async function(e,t,r,s){const{debounce:n=0,repeat:o=0,repeatEvery:i=null,setDefaults:a=!1}=r;if(n>0)return await(await(async(e,t)=>{let r;return async function(...s){clearTimeout(r),r=setTimeout(async()=>{clearTimeout(r),await e(...s)},t)}})(async()=>{await s(e,{...t,debounce:0})},1e3*n))(),r.response||{};if(o>1){for(let r=0;r<o;r++)await s(e,{...t,repeat:0});return r.response||{}}if(i)return setInterval(async()=>{await s(e,{...t,repeat:0,repeatEvery:null})},1e3*i),r.response||{};if(a){const e="undefined"!=typeof window?window.grab:globalThis.grab;return e&&(e.defaults={...t,setDefaults:void 0}),r.response||{}}return null}(r,s||{},n,t);if(o)return o;!function(e,t,r,s){if("undefined"==typeof window)return;const{regrabOnStale:n,regrabOnFocus:o,regrabOnNetwork:i,cache:a,cacheForTime:l=60}=r,c=async()=>await s(e,{...t,cache:!1});n&&a&&setTimeout(c,1e3*l),i&&window.addEventListener("online",c),o&&(window.addEventListener("focus",c),document.addEventListener("visibilitychange",async()=>{"visible"===document.visibilityState&&await c()}))}(r,s||{},n,t);let{params:a,priorRequest:T,response:C,paramsAsText:R}=function(e,t,r,s,n,o){const{cache:i,cacheForTime:a,infiniteScroll:l}=r,[c,u]=l||[],p=JSON.stringify(c?{...t,[c]:void 0}:t);let h=o.find(t=>t.request===p&&t.path===e);if(c){let e=(h?.currentPage||0)+1||t?.[c]||1;h?h.currentPage=e:(s[u]=[],e=1),t={...t,[c]:e}}else{for(let e of Object.keys(s))s[e]=void 0;if(i&&h?.response&&(!a||h.lastFetchTime>Date.now()-1e3*a)){for(let e of Object.keys(h.response))s[e]=h.response[e];n&&(s=n(s))}}return{params:t,priorRequest:h,response:s,paramsAsText:p}}(r,P,n,k,$,L);if(P=a,k=C,function(e,t,r,s,n){if("undefined"==typeof window||!r?.length)return;const[o,,i]=r;if(void 0===i)return;let a="string"==typeof i?document.querySelector(i):i;a?(window.scrollListener&&"function"==typeof a.removeEventListener&&a.removeEventListener("scroll",window.scrollListener),window.scrollListener=r=>{const a=r.target;localStorage.setItem("scroll",JSON.stringify([a.scrollTop,a.scrollLeft,i])),a.scrollHeight-a.scrollTop<=a.clientHeight+200&&n(e,{...t,cache:!1,[o]:(s?.currentPage||0)+1})},a.addEventListener("scroll",window.scrollListener)):U("paginateDOM not found",{color:"red"})}(r,s,y,T,t),g>0&&T?.lastFetchTime>Date.now()-1e3*g)throw new Error(`Fetch rate limit exceeded for ${r}. Wait ${g}s between requests.`);if(T?.controller)if(h)T.controller.abort();else if(d)return{isLoading:!0};const S=new AbortController;let O=S.signal;h||"function"!=typeof AbortSignal.timeout||(O=AbortSignal.timeout(1e3*u)),L.unshift({path:r,request:R,lastFetchTime:Date.now(),controller:S});let{fetchParams:I,paramsGETRequest:M}=function(e,t,r,s,n,o){const i=["POST","PUT","PATCH"].includes(e),a={method:e,headers:{"Content-Type":"application/json",Accept:"application/json",...t},body:r||(i?JSON.stringify(s):null),redirect:"follow",cache:n?"force-cache":"no-store",signal:o};let l="";return i||(l=(Object.keys(s).length?"?":"")+new URLSearchParams(s).toString()),{fetchParams:a,paramsGETRequest:l}}(l,i,A,P,!!c,O);if("function"==typeof b){const e=b(r,k,P,I);Array.isArray(e)&&([r,k,P,I]=e)}const j=new Date,N=await e(p,r,M,I,P,x,v,E);if($?k=$({...k,isLoading:void 0}):"object"==typeof k&&delete k.isLoading,"function"==typeof w){const e=w(r,k,P,I);Array.isArray(e)&&([r,k,P,I]=e)}const D=((Number(new Date)-Number(j))/1e3).toFixed(1);f&&m(`Path:${p+r+M}\n${JSON.stringify(s,null,2)}\nTime: ${D}s\nResponse: ${_(N)}`);const[,q]=y||[];return k=function(e,t,r,s){if("object"==typeof e&&null!==e){for(let r of Object.keys(e))t[r]=s===r&&Array.isArray(t[r])?[...t[r],...e[r]]:e[r];t.data=e}else r?t=r({data:e,...e}):"object"==typeof t&&(t.data=e);return t}(N,k,$,q),L[0]&&(L[0].response=k),$&&(k=$(k)),k}catch(M){if("function"==typeof T&&T(M.message,p+r,P),n.retryAttempts&&n.retryAttempts>0)return await t(r,{...s,retryAttempts:--n.retryAttempts});!M.message.includes("signal")&&f&&(m(`Error: ${M.message}\nPath:${p+r}\n`,{color:"red"}),"undefined"!=typeof document&&N(M.message)),k=k||{},k.error=M.message;const e="function"==typeof a?a:null;return e?(k.data=e({isLoading:void 0,error:M.message}),k=k.data):delete k.isLoading,k}}}(async function(e,t,r,s,n,o,i,a){const l=("undefined"!=typeof window?window.grab:globalThis.grab)?.mock?.[t],c=JSON.stringify(n);if(l&&(!l.method||l.method===s.method)&&(!l.params||c===JSON.stringify(l.params)))return await(e=>new Promise(t=>setTimeout(t,1e3*e||0)))(l.delay||0),"function"==typeof l.response?l.response(n):l.response;const u=await fetch(e+t+r,s).catch(e=>{throw new Error(e.message)});if(!u.ok)throw new Error(`HTTP error: ${u.status} ${u.statusText}`);if(o)return await o(u.body),null;const p=u.headers.get("content-type")??"",h=!1!==i&&(p.includes("application/zip")||p.includes("application/x-zip")),d=!1!==a&&("string"==typeof a||p.includes("text/html"));return h?{data:await q(await u.arrayBuffer().catch(e=>{throw new Error("Error reading zip: "+e)}))}:d?{data:await F(await u.text().catch(e=>{throw new Error("Error reading html: "+e)}),"string"!=typeof a||a)}:await(p.includes("application/json")?u.json():p.includes("application/pdf")||p.includes("application/octet-stream")?u.blob():p?u.text():u.json()).catch(e=>{throw new Error("Error parsing response: "+e)})}),W=G;W.instance=(e={})=>(t,r={})=>G(t,{...e,...r}),W.log=[],W.mock={},W.defaults={},"undefined"!=typeof window?(window.log=U,window.grab=W,"undefined"!=typeof document&&document.addEventListener("keydown",e=>{const t=window.grab;if(t&&t.log&&"i"===e.key&&e.ctrlKey&&e.altKey){let e="";for(const r of t.log){const t=new Date(r.lastFetchTime).toLocaleString(),s=_(r.request,0,"html"),n=_(r.response,0,"html"),o=D(JSON.stringify(r.response,null,2));e+=`\n <details open style="margin-bottom:0.75em">\n <summary style="cursor:pointer;font-weight:bold;padding:4px 0;list-style:none;display:flex;justify-content:space-between">\n <span style="color:#1a56db">${D(r.path)}</span>\n <span style="color:#6b7280;font-weight:normal;margin-left:1em">${t}</span>\n </summary>\n <div style="padding-left:1em;margin-top:0.5em">\n <details style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Request</summary>\n <div style="padding:0.4em 0 0 1em">${s}</div>\n </details>\n <details open style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Response (structure)</summary>\n <div style="padding:0.4em 0 0 1em">${n}</div>\n </details>\n <details style="margin-bottom:0.4em">\n <summary style="cursor:pointer;color:#6b7280;font-size:0.9em">Response (data)</summary>\n <pre style="margin:0.4em 0 0 1em;padding:0.5em;background:#f9fafb;border:1px solid #e5e7eb;border-radius:4px;overflow:auto;max-height:300px;font-size:12px">${o}</pre>\n </details>\n </div>\n </details>`}N(e||"<em>No requests logged yet.</em>")}}),document.addEventListener("DOMContentLoaded",()=>{try{const e=localStorage.getItem("scroll");if(!e)return;const[t,r,s]=JSON.parse(e);if(!t||!s)return;const n=document.querySelector(s);n&&(n.scrollTop=t,n.scrollLeft=r)}catch($){console.warn("Failed to restore scroll position",$)}})):"undefined"!=typeof globalThis&&(globalThis.log=U,globalThis.grab=W);var B,H=class{constructor(){this.requestHeaders={},this.proxyConfiguration={},this.requestHeaders["Accept-Language"]="en-US"}setHeader(e,t){this.requestHeaders[e]=t}setProxies(e){this.proxyConfiguration=e}async get(e,t){const r=this.getProxyAgentForUrl(e);return W(e,{...t,method:"GET",headers:{...this.requestHeaders,...t?.headers},agent:r})}async post(e,t){const r=this.getProxyAgentForUrl(e);return W(e,{...t,method:"POST",headers:{...this.requestHeaders,...t?.headers},agent:r})}getProxyAgentForUrl(e){if(0===Object.keys(this.proxyConfiguration).length)return;const t=e.startsWith("https://")?this.proxyConfiguration.https:this.proxyConfiguration.http;return t?new r.HttpsProxyAgent(t):void 0}};var Y=class e extends Error{constructor(t){super(t),this.name="InvalidProxyConfig",Object.setPrototypeOf(this,e.prototype)}},z=class{get preventKeepingConnectionsAlive(){return!1}get retriesWhenBlocked(){return 0}},J=class extends z{constructor(e){super();const{httpUrl:t,httpsUrl:r}=e;if(!t&&!r)throw new Y("GenericProxyConfig requires you to define at least one of the two: http or https");this._httpUrl=t||null,this._httpsUrl=r||null}get httpUrl(){return this._httpUrl}get httpsUrl(){return this._httpsUrl}toRequestsDict(){return{http:this.httpUrl||this.httpsUrl,https:this.httpsUrl||this.httpUrl}}},V=class e extends J{constructor(t){super({httpUrl:"placeholder"}),this.proxyUsername=t.proxyUsername,this.proxyPassword=t.proxyPassword,this.domainName=t.domainName||e.DEFAULT_DOMAIN_NAME,this.proxyPort=t.proxyPort||e.DEFAULT_PORT,this.filterIpLocations=t.filterIpLocations||[],this._retriesWhenBlocked=t.retriesWhenBlocked??10}get url(){const e=this.filterIpLocations.map(e=>`-${e.toUpperCase()}`).join("");let t=this.proxyUsername;const r="-rotate";return t.endsWith(r)&&(t=t.slice(0,-7)),`http://${t}${e}${r}:${this.proxyPassword}@${this.domainName}:${this.proxyPort}/`}get httpUrl(){return this.url}get httpsUrl(){return this.url}toRequestsDict(){return{http:this.url,https:this.url}}get preventKeepingConnectionsAlive(){return!0}get retriesWhenBlocked(){return this._retriesWhenBlocked}};(B=V).DEFAULT_DOMAIN_NAME="p.webshare.io",B.DEFAULT_PORT=80;var K=class{},X=class extends K{formatTranscript(e){return JSON.stringify(e.toRawData(),null,2)}formatTranscripts(e){return JSON.stringify(e.map(e=>e.toRawData()),null,2)}},Q=class extends K{formatTranscript(e,t){return JSON.stringify(e.toRawData(),null,t?.indent)}formatTranscripts(e,t){return JSON.stringify(e.map(e=>e.toRawData()),null,t?.indent)}},Z=class extends K{formatTranscript(e){return e.snippets.map(e=>e.text).join("\n")}formatTranscripts(e){return e.map(e=>this.formatTranscript(e)).join("\n\n\n")}},ee=class extends K{formatTranscript(e){const t=e.snippets.map(e=>e.text).join(" "),r=[];let s=0;for(const g of e.snippets)r.push([s,g.start]),s+=g.text.length+1;const n={};for(const[g,f]of r){const e=Math.floor(g/f)-10;n[Math.floor(g/100)]=e}const o=Object.keys(n).map(e=>n[parseInt(e)]),i=[],a=[];let l=o[0],c=1;for(let g=1;g<o.length;g++)o[g]===l?c++:(i.push(l),a.push(c),l=o[g],c=1);i.push(l),a.push(c);let u=0;const p=a.map(e=>(u+=e,u)),h=i.join(",")+" "+p.join(","),d=t.replace(/\s+/g," ");return JSON.stringify({text:d,timestamps:h,wordCount:d.split(/\s+/).length,charCount:d.length},null,2)}formatTranscripts(e){return e.map(e=>this.formatTranscript(e)).join("\n\n")}},te=class extends Z{secondsToTimestamp(e){const t=Math.floor(e/3600),r=e%3600,s=Math.floor(r/60),n=Math.floor(r%60),o=Math.round(1e3*(e-Math.floor(e)));return this.formatTimestamp(t,s,n,o)}formatTranscript(e){const t=[];for(let r=0;r<e.snippets.length;r++){const s=e.snippets[r],n=s.start+s.duration,o=r<e.snippets.length-1&&e.snippets[r+1].start<n?e.snippets[r+1].start:n,i=`${this.secondsToTimestamp(s.start)} --\x3e ${this.secondsToTimestamp(o)}`;t.push(this.formatSubtitleEntry(r,i,s))}return this.formatTranscriptHeader(t)}},re=class extends te{formatTimestamp(e,t,r,s){const n=(e,t)=>e.toString().padStart(t,"0");return`${n(e,2)}:${n(t,2)}:${n(r,2)},${n(s,3)}`}formatTranscriptHeader(e){return e.join("\n\n")+"\n"}formatSubtitleEntry(e,t,r){return`${e+1}\n${t}\n${r.text}`}},se=class extends te{formatTimestamp(e,t,r,s){const n=(e,t)=>e.toString().padStart(t,"0");return`${n(e,2)}:${n(t,2)}:${n(r,2)}.${n(s,3)}`}formatTranscriptHeader(e){return"WEBVTT\n\n"+e.join("\n\n")+"\n"}formatSubtitleEntry(e,t,r){return`${t}\n${r.text}`}},ne=class e extends Error{constructor(t){super(`Unknown formatter type: ${t}. Available types: json, text, srt, webvtt, pretty, article`),this.name="UnknownFormatterType",Object.setPrototypeOf(this,e.prototype)}};exports.AgeRestricted=d,exports.ArticleFormatter=ee,exports.CookieError=a,exports.CookieInvalid=class e extends a{constructor(t){super(`The cookies provided are not valid (may have expired): ${t}`),this.name="CookieInvalid",Object.setPrototypeOf(this,e.prototype)}},exports.CookiePathInvalid=class e extends a{constructor(t){super(`Can't load the provided cookie file: ${t}`),this.name="CookiePathInvalid",Object.setPrototypeOf(this,e.prototype)}},exports.CouldNotRetrieveTranscript=i,exports.FailedToCreateConsentCookie=g,exports.FetchedTranscript=v,exports.Formatter=K,exports.FormatterLoader=class{load(e){const t=e?.toLowerCase()||"pretty";switch(t){case"json":return new Q;case"text":return new Z;case"article":return new ee;case"srt":return new re;case"webvtt":return new se;case"pretty":return new X;default:throw new ne(t)}}},exports.GenericProxyConfig=J,exports.InvalidProxyConfig=Y,exports.InvalidVideoId=h,exports.IpBlocked=x,exports.JSONFormatter=Q,exports.NoTranscriptFound=b,exports.NotTranslatable=y,exports.PlayabilityFailedReason=P,exports.PlayabilityStatus=S,exports.PoTokenRequired=w,exports.PrettyPrintFormatter=X,exports.ProxyConfig=z,exports.RequestBlocked=T,exports.SRTFormatter=re,exports.TextFormatter=Z,exports.Transcript=C,exports.TranscriptList=R,exports.TranscriptListFetcher=k,exports.TranscriptsDisabled=f,exports.TranslationLanguageNotAvailable=m,exports.UnknownFormatterType=ne,exports.VideoUnavailable=p,exports.VideoUnplayable=u,exports.WebVTTFormatter=se,exports.WebshareProxyConfig=V,exports.YouTubeDataUnparsable=l,exports.YouTubeRequestFailed=c,exports.YouTubeTranscriptApi=class{constructor(e){const t=this.initializeHttpClient(e);this.configureHttpClientWithProxy(t,e?.proxyConfig),this.transcriptListFetcher=new k(t,e?.proxyConfig||null)}initializeHttpClient(e){return e?.httpClient||new H}configureHttpClientWithProxy(e,t){if(!(t&&e instanceof H))return;const r=t.toRequestsDict();e.setProxies(r),t.preventKeepingConnectionsAlive&&e.setHeader("Connection","close")}async fetchTranscript(e,t){const r=t?.languages||["en"],s=t?.preserveFormatting||!1;return(await this.listTranscripts(e)).findTranscript(r).fetch(s)}async listTranscripts(e){return this.transcriptListFetcher.fetchTranscriptList(e)}async fetch(e,t){return this.fetchTranscript(e,t)}async list(e){return this.listTranscripts(e)}},exports.YouTubeTranscriptApiException=o,exports.decompressTimestampsArray=function(e){const t=[];for(const r of e.split(",")){const[e,s]=r.split("x");t.push(...Array(parseInt(s)).fill(parseInt(e)))}return t},exports.encodeTranscriptSpeeds=function(e,t=!1){let r=0;const s=[],n=[];for(const d of e.snippets)n.push(d.text),r+=d.text.length,d.start>0&&s.push([r,d.start]);const o=n.join(" ").replace(/\s+/g," "),i=o.split(/\s+/).filter(Boolean).length,a=s.map(([e,t])=>Math.floor(e/t)-10);if(0===a.length)return{html:o,word_count:i,speeds:""};const l=[],c=[];let u=a[0],p=1;for(let d=1;d<a.length;d++)a[d]===u?p++:(l.push(u),c.push(p),u=a[d],p=1);l.push(u),c.push(p);const h=l.map((e,t)=>`${e}x${c[t]}`).join(",");return{html:t?`<iframe width="100%" height="315px" data-timestamps="${h}" src="https://www.youtube.com/embed/${e.videoId}" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>${o}`:o,word_count:i,speeds:h}},exports.getTimestampAtChar=function(e,t){let r=0;const s=[[0,0]];for(const n of e.snippets)r+=n.text.length+1,s.push([r,n.start]);if(t<=0)return 0;if(t>=s[s.length-1][0])return s[s.length-1][1];for(let n=1;n<s.length;n++)if(s[n][0]>=t){const[e,r]=s[n-1],[o,i]=s[n];return r+(t-e)/(o-e)*(i-r)}return s[s.length-1][1]};
2
2
  //# sourceMappingURL=index.cjs.map