diff --git a/main.js b/main.js index dbde200..51312f6 100644 --- a/main.js +++ b/main.js @@ -108,4 +108,4 @@ ${e.trim()}`}if(r.backend==="codex"){let t=D("codex",r.cliPath),{stdout:e}=await ${e.trim()}`}return Rt(m.requestUrl,r)}var Te=class extends m.PluginSettingTab{constructor(t,e){super(t,e),this.plugin=e}tr(t,e){return this.plugin.t(t,e)}display(){let{containerEl:t}=this;t.empty(),new m.Setting(t).setName(this.tr("settingsTitle")).setHeading(),this.renderGeneralSection(t);let e=this.plugin.settings.backend==="claude-code"||this.plugin.settings.backend==="codex";this.renderBackendSection(t,e),this.renderPromptSection(t,e),this.renderActionsSection(t,e),this.renderCacheSection(t)}renderGeneralSection(t){new m.Setting(t).setName(this.tr("settingUiLanguageName")).setDesc(this.tr("settingUiLanguageDesc")).addDropdown(e=>{for(let[n,i]of Object.entries(Ne))e.addOption(n,i);return e.setValue(this.plugin.settings.uiLanguage||f.uiLanguage).onChange(async n=>{this.plugin.settings.uiLanguage=n,await this.plugin.saveSettings(),this.display()})}),new m.Setting(t).setName(this.tr("settingBackendName")).setDesc(this.tr("settingBackendDesc")).addDropdown(e=>e.addOption("api","API / provider").addOption("claude-code","Claude code CLI").addOption("codex","Codex CLI").setValue(this.plugin.settings.backend).onChange(async n=>{this.plugin.settings.backend=n,n==="api"&&!this.plugin.settings.apiBaseUrl&&Oe(this.plugin.settings,this.plugin.settings.apiProvider||"anthropic"),await this.plugin.saveSettings(),this.display()}))}renderBackendSection(t,e){if(e){new m.Setting(t).setName(this.tr("settingCliPathName")).setDesc(this.tr("settingCliPathDesc")).addText(i=>i.setPlaceholder(this.tr("settingCliPathPlaceholder")).setValue(this.plugin.settings.cliPath).onChange(a=>{this.plugin.settings.cliPath=a.trim(),this.plugin.saveSettingsDebounced()}));return}let n=x(this.plugin.settings);new m.Setting(t).setName(this.tr("apiProviderHeader")).setHeading(),new m.Setting(t).setName(this.tr("settingProviderPresetName")).setDesc(this.tr("settingProviderPresetDesc")).addDropdown(i=>{for(let[a,s]of Object.entries(R))i.addOption(a,s.label);return i.setValue(this.plugin.settings.apiProvider).onChange(async a=>{Oe(this.plugin.settings,a),await this.plugin.saveSettings(),this.display()})}),new m.Setting(t).setName(this.tr("settingApiFormatName")).setDesc(this.tr("settingApiFormatDesc")).addDropdown(i=>{for(let[a,s]of Object.entries(T))i.addOption(a,s.label);return i.setValue(P(this.plugin.settings)).onChange(async a=>{this.plugin.settings.apiFormat=a,await this.plugin.saveSettings(),this.display()})}),new m.Setting(t).setName(this.tr("settingBaseUrlName")).setDesc(this.tr("settingBaseUrlDesc")).addText(i=>i.setPlaceholder((this.plugin.settings.apiProvider||"").startsWith("custom-")?"https://your-provider.example/v1":n.baseUrl||T[P(this.plugin.settings)].defaultBaseUrl).setValue(this.plugin.settings.apiBaseUrl).onChange(a=>{this.plugin.settings.apiBaseUrl=a.trim(),this.plugin.saveSettingsDebounced()})),new m.Setting(t).setName(this.tr("settingApiKeyName")).setDesc(this.tr("settingApiKeyDesc")).addText(i=>(i.inputEl.type="password",i.setValue(this.plugin.settings.apiKey).onChange(a=>{this.plugin.settings.apiKey=a.trim(),this.plugin.saveSettingsDebounced()}))),new m.Setting(t).setName(this.tr("settingApiKeyEnvName")).setDesc(this.tr("settingApiKeyEnvDesc")).addText(i=>i.setPlaceholder(n.envVar||"OPENAI_API_KEY").setValue(this.plugin.settings.apiKeyEnvVar).onChange(a=>{this.plugin.settings.apiKeyEnvVar=a.trim(),this.plugin.saveSettingsDebounced()})),new m.Setting(t).setName(this.tr("settingAuthTypeName")).setDesc(this.tr("settingAuthTypeDesc")).addDropdown(i=>{for(let[a,s]of Object.entries(Ie))i.addOption(a,s);return i.setValue(this.plugin.settings.apiAuthType||"auto").onChange(async a=>{this.plugin.settings.apiAuthType=a,await this.plugin.saveSettings()})}),new m.Setting(t).setName(this.tr("settingHeadersName")).setDesc(this.tr("settingHeadersDesc")).addTextArea(i=>i.setValue(this.plugin.settings.apiHeaders).onChange(a=>{this.plugin.settings.apiHeaders=a,this.plugin.saveSettingsDebounced()})),new m.Setting(t).setName(this.tr("settingMaxTokensName")).addText(i=>i.setValue(String(this.plugin.settings.apiMaxTokens)).onChange(a=>{let s=parseInt(a,10);!Number.isNaN(s)&&s>0&&(this.plugin.settings.apiMaxTokens=s,this.plugin.saveSettingsDebounced())})),new m.Setting(t).setName(this.tr("settingStreamingName")).setDesc(this.tr("settingStreamingDesc")).addToggle(i=>i.setValue(this.plugin.settings.streaming??!0).onChange(async a=>{this.plugin.settings.streaming=a,await this.plugin.saveSettings()})),new m.Setting(t).setName(this.tr("settingStreamingTimeoutName")).setDesc(this.tr("settingStreamingTimeoutDesc")).addText(i=>i.setPlaceholder(String(f.streamingTimeoutMs)).setValue(String(this.plugin.settings.streamingTimeoutMs||f.streamingTimeoutMs)).onChange(a=>{this.plugin.settings.streamingTimeoutMs=K(a),this.plugin.saveSettingsDebounced()}))}renderPromptSection(t,e){new m.Setting(t).setName(this.tr("settingModelName")).setDesc(e?this.tr("settingModelDescCli"):this.tr("settingModelDescApi")).addText(n=>n.setPlaceholder(e?f.model:x(this.plugin.settings).model||"Model-id").setValue(this.plugin.settings.model).onChange(i=>{this.plugin.settings.model=i.trim()||(e?f.model:""),this.plugin.saveSettingsDebounced()})),new m.Setting(t).setName(this.tr("settingMaxInputName")).setDesc(this.tr("settingMaxInputDesc")).addText(n=>n.setValue(String(this.plugin.settings.maxDocChars||f.maxDocChars)).onChange(i=>{let a=parseInt(i,10);!Number.isNaN(a)&&a>=1e3&&(this.plugin.settings.maxDocChars=a,this.plugin.saveSettingsDebounced())})),new m.Setting(t).setName(this.tr("promptHeader")).setHeading(),new m.Setting(t).setName(this.tr("settingPromptLanguageName")).setDesc(this.tr("settingPromptLanguageDesc")).addDropdown(n=>{for(let[i,a]of Object.entries($))n.addOption(i,a);return n.setValue(this.plugin.settings.promptLanguage||f.promptLanguage).onChange(async i=>{this.plugin.settings.promptLanguage=i,await this.plugin.saveSettings()})}),new m.Setting(t).setName(this.tr("settingCardRangeName")).setDesc(this.tr("settingCardRangeDesc")).addText(n=>n.setPlaceholder("Min").setValue(String(this.plugin.settings.minCards||f.minCards)).onChange(i=>{let a=parseInt(i,10);!Number.isNaN(a)&&a>0&&(this.plugin.settings.minCards=a,this.plugin.settings.maxCardsn.setPlaceholder("Max").setValue(String(this.plugin.settings.maxCards||f.maxCards)).onChange(i=>{let a=parseInt(i,10);!Number.isNaN(a)&&a>0&&(this.plugin.settings.maxCards=Math.max(a,this.plugin.settings.minCards||f.minCards),this.plugin.saveSettingsDebounced())})),new m.Setting(t).setName(this.tr("settingCustomPromptName")).setDesc(this.tr("settingCustomPromptDesc")).addTextArea(n=>(n.inputEl.rows=8,n.setPlaceholder(this.tr("settingCustomPromptPlaceholder")).setValue(this.plugin.settings.customSystemPrompt||"").onChange(i=>{this.plugin.settings.customSystemPrompt=i,this.plugin.saveSettingsDebounced()})))}renderActionsSection(t,e){new m.Setting(t).setName(this.tr("settingTestBackendName")).setDesc(e?this.tr("settingTestBackendDescCli"):this.tr("settingTestBackendDescApi")).addButton(n=>n.setButtonText("Test").onClick(async()=>{try{let i=await hr(this.plugin.settings);new m.Notice(`\u2713 ${i.slice(0,180)}`,8e3)}catch(i){new m.Notice(this.tr("backendTestFailed",{error:i.message}),1e4)}})),new m.Setting(t).setName(this.tr("settingExportFolderName")).setDesc(this.tr("settingExportFolderDesc")).addText(n=>n.setValue(this.plugin.settings.exportFolder).onChange(i=>{this.plugin.settings.exportFolder=i.trim()||f.exportFolder,this.plugin.saveSettingsDebounced()}))}renderCacheSection(t){new m.Setting(t).setName(this.tr("cacheHeader")).setHeading(),new m.Setting(t).setName(this.tr("settingMaxCacheName")).setDesc(this.tr("settingMaxCacheDesc")).addText(n=>{n.setValue(String(this.plugin.settings.maxCacheEntries||U));let i=async()=>{let a=parseInt(n.getValue(),10);if(Number.isFinite(a)&&a>0){this.plugin.settings.maxCacheEntries=a,await this.plugin.saveSettings();let s=await this.plugin.pruneCacheIfNeeded();s.length>0&&new m.Notice(this.tr("cachePruned",{count:s.length})),this.display()}};return n.inputEl.addEventListener("change",()=>{i()}),n.inputEl.addEventListener("keydown",a=>{a.key==="Enter"&&n.inputEl.blur()}),n});let e=Object.keys(this.plugin.cache).length;new m.Setting(t).setName(this.tr("cachedNotesName",{count:e})).setDesc(this.tr("cachedNotesDesc")).addButton(n=>n.setButtonText(this.tr("clearAllCacheButton")).setWarning().onClick(async()=>{let i=Object.keys(this.plugin.cache).length;await this.plugin.cacheClear(),new m.Notice(this.tr("cacheClearedAll",{count:i})),this.display()}))}};var F=require("obsidian");function M(r,t,e,n){let i=r.createEl("button",{cls:"parallel-reader-icon-button",attr:{type:"button","aria-label":e}});return i.title=e,typeof F.setIcon=="function"?(0,F.setIcon)(i,t):i.textContent=e,i.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),Promise.resolve(n()).catch(s=>{console.error(s),new F.Notice(`${e} failed: ${s instanceof Error?s.message:String(s)}`)})}),i}function N(r,t,e,n,i){let a=r.createEl("button",{cls:i||"parallel-reader-text-button",attr:{type:"button"}});return t&&typeof F.setIcon=="function"&&(0,F.setIcon)(a,t),a.createSpan({text:e}),a.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),Promise.resolve(n()).catch(c=>{console.error(c),new F.Notice(`${e} failed: ${c instanceof Error?c.message:String(c)}`)})}),a}async function O(r,t){try{await navigator.clipboard.writeText(r),new F.Notice(t)}catch(e){new F.Notice(`Copy failed: ${e instanceof Error?e.message:String(e)}`)}}function st(r){return String(r||"").split("/").map(t=>t.trim()).filter(t=>!!t&&t!==".."&&t!==".").join("/")}function ot(r){let t=st(r);if(!t)return[];let e=t.split("/");return e.map((n,i)=>e.slice(0,i+1).join("/"))}async function It(r,t){for(let e of ot(t))if(!r.vault.getAbstractFileByPath(e))try{await r.vault.createFolder(e)}catch(n){if(!r.vault.getAbstractFileByPath(e))throw n}}var A=require("obsidian");var Dt=require("obsidian");var ke=class extends Dt.Modal{constructor(t,e,n,i){super(t),this.plugin=e,this.card=n||{},this.onSave=i}onOpen(){let{contentEl:t}=this;t.empty(),t.createEl("h2",{text:this.plugin.t("editCardTitle")});let e=this.createLabeledInput(t,this.plugin.t("editCardTitleField"),this.card.title||""),n=this.createLabeledTextarea(t,this.plugin.t("editCardGistField"),this.card.gist||"",3),i=this.createLabeledTextarea(t,this.plugin.t("editCardBulletsField"),(this.card.bullets||[]).join(` `),8),a=t.createDiv({cls:"parallel-reader-modal-actions"});N(a,null,this.plugin.t("editCardCancel"),()=>this.close(),"parallel-reader-text-button"),N(a,null,this.plugin.t("editCardSave"),async()=>{await this.onSave({title:e.value.trim()||this.card.title||"",gist:n.value.trim(),bullets:i.value.split(/\r?\n/).map(s=>s.trim()).filter(Boolean)}),this.close()},"parallel-reader-text-button")}createLabeledInput(t,e,n){let i=t.createDiv({cls:"parallel-reader-modal-field"});i.createEl("label",{text:e});let a=i.createEl("input",{attr:{type:"text"}});return a.value=n,a}createLabeledTextarea(t,e,n,i){let a=t.createDiv({cls:"parallel-reader-modal-field"});a.createEl("label",{text:e});let s=a.createEl("textarea");return s.rows=i,s.value=n,s}};var B="parallel-reader-view",Fe=class extends A.ItemView{constructor(e,n){super(e);this.stale=!1;this.loadingMessage="";this.errorMessage="";this.plugin=n,this.sections=[],this.sourceFile=null,this.cards=[],this.activeIdx=-1}getViewType(){return B}getDisplayText(){return this.plugin.t("displayName")}getIcon(){return"book-open"}onOpen(){let e=this.containerEl.children[1];return e.empty(),e.addClass("parallel-reader-container"),e.setAttr("tabindex","0"),e.addEventListener("keydown",n=>this.handleKeydown(n)),this.renderEmpty(),this.focusSummaryPane(),Promise.resolve()}onClose(){return Promise.resolve()}renderEmpty(){this.sourceFile=null,this.sections=[],this.stale=!1,this.loadingMessage="",this.errorMessage="";let e=this.containerEl.children[1];e.empty();let n=e.createDiv({cls:"parallel-reader-empty"});n.createEl("h3",{text:this.plugin.t("appTitle")}),n.createEl("p",{text:this.plugin.t("emptyOpenNote")}),n.createEl("code",{text:this.plugin.t("commandGenerate")})}focusSummaryPane(){let e=this.containerEl.children[1];return!e||typeof e.focus!="function"?!1:(e.focus({preventScroll:!0}),!0)}loadFor(e,n,i){this.sourceFile=e,this.sections=n,this.stale=!!i,this.loadingMessage="",this.errorMessage="",this.render()}renderLoading(e,n){this.sourceFile=e,this.sections=[],this.stale=!1,this.loadingMessage=n||this.plugin.t("loadingDefault"),this.errorMessage="",this.render()}renderStreamingPreview(e,n){this.sourceFile?.path!==e.path&&(this.sourceFile=e);let i=this.containerEl.children[1],a=i.querySelector(".parallel-reader-streaming-preview");if(a){let y=a.querySelector("pre");y&&(y.textContent=n.slice(-2e3));let p=a.querySelector(".parallel-reader-stream-counter");p&&(p.textContent=`${n.length} chars`);return}i.empty();let c=i.createDiv({cls:"parallel-reader-header"}).createDiv({cls:"parallel-reader-header-row"});c.createEl("div",{text:e.basename,cls:"parallel-reader-title"});let o=c.createDiv({cls:"parallel-reader-actions"});M(o,"square",this.plugin.t("actionCancel"),()=>{this.plugin.cancelGenerationForFile(e)});let d=i.createDiv({cls:"parallel-reader-state parallel-reader-loading parallel-reader-streaming-preview"});d.createDiv({cls:"parallel-reader-spinner"});let l=d.createEl("div",{cls:"parallel-reader-state-title"});l.createSpan({text:this.plugin.t("loadingGenerating")+" "}),l.createSpan({cls:"parallel-reader-stream-counter",text:`${n.length} chars`});let u=d.createEl("pre",{cls:"parallel-reader-stream-text"});u.textContent=n.slice(-2e3)}renderError(e,n){this.sourceFile=e,this.sections=[],this.stale=!1,this.loadingMessage="",this.errorMessage=n||this.plugin.t("errorTitle"),this.render()}renderEmptyWithHint(e){this.sourceFile=e,this.sections=[],this.stale=!1,this.loadingMessage="",this.errorMessage="";let n=this.containerEl.children[1];n.empty();let i=n.createDiv({cls:"parallel-reader-empty"});i.createEl("h3",{text:e.basename}),i.createEl("p",{text:this.plugin.t("emptyNoCache")}),i.createEl("code",{text:this.plugin.t("commandGenerate")})}render(){let e=this.containerEl.children[1];e.empty();let i=e.createDiv({cls:"parallel-reader-header"}).createDiv({cls:"parallel-reader-header-row"});i.createEl("div",{text:this.sourceFile?.basename||"",cls:"parallel-reader-title"});let a=i.createDiv({cls:"parallel-reader-actions"});if(this.sourceFile&&(this.plugin.isGeneratingFile(this.sourceFile)?M(a,"square",this.plugin.t("actionCancel"),()=>{this.plugin.cancelGenerationForFile(this.sourceFile)}):M(a,"refresh-cw",this.plugin.t("actionRegenerate"),()=>this.plugin.runForFile(this.sourceFile,!0)),M(a,"copy",this.plugin.t("actionCopyAll"),()=>this.plugin.copyCurrentViewMarkdown()),M(a,"download",this.plugin.t("actionExport"),()=>this.exportToVault())),this.stale){let o=e.createDiv({cls:"parallel-reader-stale-banner"});o.createSpan({text:this.plugin.t("staleBanner")}),N(o,"refresh-cw",this.plugin.t("actionRegenerate"),()=>this.plugin.runForFile(this.sourceFile,!0),"parallel-reader-stale-button")}if(this.loadingMessage){let o=e.createDiv({cls:"parallel-reader-state parallel-reader-loading"});o.createDiv({cls:"parallel-reader-spinner"}),o.createEl("div",{text:this.loadingMessage,cls:"parallel-reader-state-title"}),o.createEl("div",{text:this.plugin.t("loadingSubtitle"),cls:"parallel-reader-state-subtitle"});return}if(this.errorMessage){let o=e.createDiv({cls:"parallel-reader-state parallel-reader-error"});o.createEl("div",{text:this.plugin.t("errorTitle"),cls:"parallel-reader-state-title"}),o.createEl("div",{text:this.errorMessage,cls:"parallel-reader-state-subtitle"}),N(o,"refresh-cw",this.plugin.t("actionRegenerate"),()=>this.plugin.runForFile(this.sourceFile,!0),"parallel-reader-text-button");return}let s=e.createDiv({cls:"parallel-reader-cards"});this.cards=[];let c=this.sourceFile?.path||"";this.sections.forEach((o,d)=>{let l=s.createDiv({cls:"parallel-reader-card"});l.dataset.idx=String(d),o.startLine<0&&l.addClass("parallel-reader-card-unanchored");let u=l.createEl("div",{cls:"parallel-reader-card-title"});if(u.createSpan({text:o.title}),o.startLine<0&&u.createEl("span",{text:" \u26A0",cls:"parallel-reader-warn",title:this.plugin.t("anchorMismatch")}),o.gist){let p=l.createEl("div",{cls:"parallel-reader-gist"});A.MarkdownRenderer.render(this.app,o.gist,p,c,this).catch(()=>{p.setText(o.gist)})}let y=o.bullets||[];if(y.length>0){let p=l.createEl("div",{cls:"parallel-reader-bullets-md"}),g=y.map(b=>`- ${b}`).join(` `);A.MarkdownRenderer.render(this.app,g,p,c,this).catch(()=>{p.setText(g)})}else o.gist||l.createEl("div",{cls:"parallel-reader-empty-li",text:this.plugin.t("emptyCard")});l.addEventListener("click",p=>{let g=window.getSelection();if(g&&g.toString().length>0)return;let b=p.target;b&&b.tagName==="A"||o.startLine>=0&&this.plugin.scrollEditorToLine(o.startLine,this.sourceFile)}),l.addEventListener("contextmenu",p=>{p.preventDefault();let g=new A.Menu;g.addItem(b=>b.setTitle(this.plugin.t("menuCopyMarkdown")).setIcon("copy").onClick(()=>O(nt(o),this.plugin.t("copiedMarkdown")))),g.addItem(b=>b.setTitle(this.plugin.t("menuCopyPlain")).setIcon("clipboard-copy").onClick(()=>O(Nt(o),this.plugin.t("copiedPlain")))),o.anchor&&g.addItem(b=>b.setTitle(this.plugin.t("menuCopyAnchor")).setIcon("quote-glyph").onClick(()=>O(o.anchor,this.plugin.t("copiedAnchor")))),g.addSeparator(),o.startLine>=0&&g.addItem(b=>b.setTitle(this.plugin.t("menuJumpSource")).setIcon("arrow-right").onClick(()=>this.plugin.scrollEditorToLine(o.startLine,this.sourceFile))),g.addSeparator(),g.addItem(b=>b.setTitle(this.plugin.t("menuEditCard")).setIcon("pencil").onClick(()=>this.openEditCardModal(d))),g.addItem(b=>b.setTitle(this.plugin.t("menuDeleteCard")).setIcon("trash").onClick(()=>this.deleteCard(d))),g.showAtMouseEvent(p)}),this.cards.push(l)}),this.activeIdx>=0&&this.cards[this.activeIdx]&&this.cards[this.activeIdx].addClass("is-active")}setActiveSection(e){e!==this.activeIdx&&(this.activeIdx>=0&&this.cards[this.activeIdx]&&this.cards[this.activeIdx].removeClass("is-active"),this.activeIdx=e,e>=0&&this.cards[e]&&(this.cards[e].addClass("is-active"),this.cards[e].scrollIntoView({block:"nearest",behavior:"smooth"})))}moveActiveSection(e){let n=Pe(this.activeIdx,this.sections.length,e);return this.setActiveSection(n),this.focusSummaryPane(),n}jumpToActiveSection(){let e=Se(this.sections,this.activeIdx);return e<0||!this.sourceFile?-1:(this.plugin.scrollEditorToLine(e,this.sourceFile),e)}handleKeydown(e){if(e.altKey&&e.key==="ArrowUp"){e.preventDefault(),this.moveActiveSection(-1);return}if(e.altKey&&e.key==="ArrowDown"){e.preventDefault(),this.moveActiveSection(1);return}!e.altKey&&!e.metaKey&&!e.ctrlKey&&!e.shiftKey&&e.key==="Enter"&&this.jumpToActiveSection()>=0&&e.preventDefault()}async deleteCard(e){if(!this.sourceFile)return!1;let n=ge(this.sections,e);if(n.length===this.sections.length)return!1;let i=this.sections.length;return this.sections=n,this.activeIdx=fe(e,i,this.activeIdx),await this.plugin.cacheReplaceCards(this.sourceFile.path,n),this.render(),new A.Notice(this.plugin.t("cardDeleted")),!0}openEditCardModal(e){return!this.sourceFile||!this.sections[e]?!1:(new ke(this.app,this.plugin,this.sections[e],async n=>{await this.updateCard(e,n)}).open(),!0)}async updateCard(e,n){if(!this.sourceFile)return!1;let i=ye(this.sections,e,n);return i.length!==this.sections.length?!1:(this.sections=i,await this.plugin.cacheReplaceCards(this.sourceFile.path,i),this.render(),new A.Notice(this.plugin.t("cardSaved")),!0)}async exportToVault(){if(!this.sourceFile)return;let e=st(this.plugin.settings.exportFolder),n=`${this.sourceFile.basename} - ${this.plugin.t("displayName")}.md`,i=`${e}/${n}`,a=["---",`source: [[${this.sourceFile.basename}]]`,`generated: ${new Date().toISOString().slice(0,10)}`,"tool: parallel-reader","---","",ie(`${this.sourceFile.basename} \xB7 ${this.plugin.t("displayName")}`,this.sections),""].join(` -`),s=this.plugin.app;await It(s,e);let c=s.vault.getAbstractFileByPath(i);c instanceof A.TFile?await s.vault.modify(c,a):await s.vault.create(i,a),new A.Notice(this.plugin.t("exported",{path:i}))}};var ct=class extends h.Plugin{constructor(){super(...arguments);this.activeBatch=null;this._scrollDispose=null;this._settingsSaveTimer=null}get cache(){return this.cacheManager.cache}t(e,n){return C(this.settings||f,e,n)}async onload(){await this.loadSettings(),this.jobs=new W,this.addRibbonIcon("book-open",this.t("ribbonOpen"),async()=>{let e=this.getActiveView();await this.ensureView()&&e?.file&&await this.syncViewToFile(e.file)}),this.registerView(B,e=>new Fe(e,this)),this.addCommand({id:"run",name:this.t("cmdRun"),callback:()=>this.runForActiveFile(!1)}),this.addCommand({id:"regen",name:this.t("cmdRegen"),callback:()=>this.runForActiveFile(!0)}),this.addCommand({id:"open-view",name:this.t("cmdOpenView"),callback:async()=>{let e=this.getActiveView();await this.ensureView()&&e?.file&&this.syncViewToFile(e.file)}}),this.addCommand({id:"export-current",name:this.t("cmdExport"),callback:()=>this.exportCurrentView()}),this.addCommand({id:"copy-current-markdown",name:this.t("cmdCopyMarkdown"),callback:()=>this.copyCurrentViewMarkdown()}),this.addCommand({id:"cancel-current",name:this.t("cmdCancel"),callback:()=>this.cancelActiveGeneration()}),this.addCommand({id:"clear-current",name:this.t("cmdClearCurrent"),callback:async()=>{let e=this.getActiveView();if(!e?.file)return new h.Notice(this.t("noCurrentNote"));await this.cacheManager.delete(e.file.path),new h.Notice(this.t("cacheClearedFile",{name:e.file.basename}))}}),this.addCommand({id:"clear-all",name:this.t("cmdClearAll"),callback:async()=>{let e=Object.keys(this.cacheManager.cache).length;await this.cacheManager.clear(),new h.Notice(this.t("cacheClearedAll",{count:e}))}}),this.addCommand({id:"card-prev",name:this.t("cmdCardPrev"),callback:()=>this.moveActiveCard(-1)}),this.addCommand({id:"card-next",name:this.t("cmdCardNext"),callback:()=>this.moveActiveCard(1)}),this.addCommand({id:"card-jump",name:this.t("cmdCardJump"),callback:()=>this.jumpActiveCard()}),this.addCommand({id:"batch-generate",name:this.t("cmdBatchGenerate"),callback:()=>this.runBatchForFolder()}),this.addSettingTab(new Te(this.app,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",()=>this.bindScrollSync())),this.registerEvent(this.app.workspace.on("file-open",e=>{e&&this.syncViewToFile(e)})),this.registerEvent(this.app.workspace.on("file-menu",(e,n)=>this.addFileMenuItems(e,n))),this.registerEvent(this.app.vault.on("rename",(e,n)=>{e instanceof h.TFile&&this.handleFileRename(e,n)})),this.registerEvent(this.app.vault.on("delete",e=>{e instanceof h.TFile&&this.handleFileDelete(e)})),this.bindScrollSync()}onunload(){this.flushSettingsSave(),this.flushCacheSave()}async loadSettings(){let n=(await this.loadData()||{}).settings||{};this.settings=le(Object.assign({},f,n)),this.cacheManager=new z(this.app.vault.adapter,this.app.vault.configDir,this.manifest?.id||"parallel-reader",()=>this.settings),await this.cacheManager.load()}async saveSettings(){this._settingsSaveTimer&&(clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=null),await this.saveData({settings:this.settings})}saveSettingsDebounced(e=400){this._settingsSaveTimer&&clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=setTimeout(()=>{this._settingsSaveTimer=null,this.saveSettings().catch(n=>console.error("[parallel-reader] failed to save settings",n))},e)}async flushSettingsSave(){this._settingsSaveTimer&&(clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=null,await this.saveSettings())}cacheTouch(e){return this.cacheManager.touch(e)}scheduleCacheSave(e=5e3){this.cacheManager.scheduleSave(e)}async flushCacheSave(){await this.cacheManager.flush()}async cacheReplaceCards(e,n){return this.cacheManager.replaceCards(e,n)}async cacheClear(){return this.cacheManager.clear()}async pruneCacheIfNeeded(){return this.cacheManager.pruneIfNeeded()}async ensureView(){let{workspace:e}=this.app,n=e.getLeavesOfType(B)[0];if(!n){let i=e.getRightLeaf(!1);if(!i)return new h.Notice(this.t("viewOpenFailed")),null;n=i,await n.setViewState({type:B,active:!0})}return await e.revealLeaf(n),n.view}getActiveView(){return this.app.workspace.getActiveViewOfType(h.MarkdownView)}getParallelView(){return this.app.workspace.getLeavesOfType(B)[0]?.view}moveActiveCard(e){let n=this.getParallelView();return n?.sections.length?n.moveActiveSection(e):(new h.Notice(this.t("noActiveCard")),-1)}jumpActiveCard(){let e=this.getParallelView();return!e||e.jumpToActiveSection()<0?(new h.Notice(this.t("noActiveCard")),!1):!0}isGeneratingFile(e){return!!e&&!!e.path&&this.jobs.isRunning(e.path)}cancelGenerationForFile(e){if(!e?.path)return new h.Notice(this.t("noCancelableJob")),!1;let n=this.jobs.get(e.path),i=rt(this.settings,n),a=this.jobs.cancel(e.path);return a&&this.activeBatch?.currentPath===e.path&&pe(this.activeBatch),new h.Notice(a?this.t(i):this.t("noCancelableJob")),a}requestBatchCancellation(){return pe(this.activeBatch)}viewIsShowingFile(e,n){return!!e&&!!n&&e.sourceFile?.path===n.path}activeFileStillMatches(e){let n=this.getActiveView();return!n?.file||n.file.path===e.path}cancelActiveGeneration(){if(this.requestBatchCancellation()){let i=this.activeBatch?.currentPath;i&&this.jobs.cancel(i),new h.Notice(this.t("batchCancelRequested"));return}let e=this.getActiveView();if(e?.file&&this.cancelGenerationForFile(e.file))return;let n=this.getParallelView();n?.sourceFile?this.cancelGenerationForFile(n.sourceFile):new h.Notice(this.t("noCancelableJob"))}confirmRegenerateEditedCards(){return new Promise(e=>{let n=this.t("confirmRegenerateEditedCards"),i=new h.Modal(this.app);i.titleEl.setText(this.t("displayName")),i.contentEl.createEl("p",{text:n});let a=i.contentEl.createDiv({cls:"modal-button-container"});a.createEl("button",{text:"Cancel"}).addEventListener("click",()=>{i.close(),e(!1)}),a.createEl("button",{text:"OK",cls:"mod-cta"}).addEventListener("click",()=>{i.close(),e(!0)}),i.onClose=()=>e(!1),i.open()})}addFileMenuItems(e,n){!(n instanceof h.TFile)||!n.path.endsWith(".md")||(e.addSeparator(),e.addItem(i=>i.setTitle(this.t("fileMenuGenerate")).setIcon("book-open").onClick(()=>this.runForFile(n,!1))),e.addItem(i=>i.setTitle(this.t("fileMenuRegen")).setIcon("refresh-cw").onClick(()=>this.runForFile(n,!0))),this.cacheManager.get(n.path)&&e.addItem(i=>i.setTitle(this.t("fileMenuClear")).setIcon("trash").onClick(async()=>{await this.cacheManager.delete(n.path),new h.Notice(this.t("cacheClearedFile",{name:n.basename}))})))}async handleFileRename(e,n){if(!(e instanceof h.TFile)||!n)return;let i=n.endsWith(".md"),a=e.path.endsWith(".md");if(!i&&!a)return;if(i&&!a){await this.cacheManager.delete(n);let c=this.getParallelView();c&&c.sourceFile?.path===n&&c.renderEmpty();return}if(!i)return;await this.cacheManager.move(n,e.path);let s=this.getParallelView();s?.sourceFile&&(s.sourceFile.path===n||s.sourceFile.path===e.path)&&(s.sourceFile=e,await this.syncViewToFile(e))}async handleFileDelete(e){if(!(e instanceof h.TFile))return;await this.cacheManager.delete(e.path);let n=this.getParallelView();n?.sourceFile?.path===e.path&&n.renderEmpty()}async exportCurrentView(){let e=this.getActiveView(),n=await this.ensureView();if(n){if((!n.sourceFile||!n.sections.length)&&e?.file&&await this.syncViewToFile(e.file),!n.sourceFile||!n.sections.length){new h.Notice(this.t("noExportContent"));return}await n.exportToVault()}}async copyCurrentViewMarkdown(){let e=this.getActiveView(),n=await this.ensureView();if(n){if((!n.sourceFile||!n.sections.length)&&e?.file&&await this.syncViewToFile(e.file),!n.sourceFile||!n.sections.length){new h.Notice(this.t("noCopyContent"));return}await O(ie(`${n.sourceFile.basename} \xB7 ${this.t("displayName")}`,n.sections),this.t("copiedAllMarkdown"))}}async runForActiveFile(e){let n=this.getActiveView();if(!n?.file){new h.Notice(this.t("openNoteFirst"));return}return this.runForFile(n.file,e)}async runForFile(e,n){if(!e){new h.Notice(this.t("openNoteFirst"));return}if(this.jobs.isRunning(e.path)){new h.Notice(this.t("alreadyGenerating"));return}if(qe(this.cacheManager.get(e.path),n)&&!await this.confirmRegenerateEditedCards()){new h.Notice(this.t("regenerateCancelled"));return}let i=null;return this.jobs.start(e.path,async a=>{a.setPhase("reading");let s=await this.app.vault.read(e);if(a.throwIfCancelled(),!s.trim()){new h.Notice(this.t("emptyNote"));return}if(i=await this.ensureView(),!i)return;if(a.throwIfCancelled(),a.setPhase("cache-check"),!n){let p=this.cacheManager.get(e.path);if(p&&j(p,s,this.settings)){this.cacheTouch(e.path),this.activeFileStillMatches(e)&&i.loadFor(e,this.resolveCardAnchors(s,p.cards),!1);return}}i.renderLoading(e,this.t("loadingGenerating"));let c=Number(this.settings.maxDocChars)||f.maxDocChars;s.length>c&&new h.Notice(this.t("longNoteTruncated",{count:c})),new h.Notice(this.t("generatingNotice")),a.setPhase("generating");let o=i,d=o?p=>{!p.done&&this.viewIsShowingFile(o,e)&&o.renderStreamingPreview(e,p.accumulated)}:void 0,l=await tt(s,this.settings,a,d);if(a.throwIfCancelled(),l.length===0){new h.Notice(this.t("noCardsReturned"));return}let u=l.map(p=>({title:p.title,anchor:p.anchor,gist:p.gist,bullets:p.bullets}));a.setPhase("saving"),await this.cacheManager.put(e.path,s,u,this.settings),a.throwIfCancelled(),this.viewIsShowingFile(i,e)&&i.loadFor(e,l,!1);let y=l.filter(p=>p.startLine<0).length;new h.Notice(this.t("generationDone",{count:l.length,suffix:y?this.t("unanchoredSuffix",{count:y}):""}))}).catch(async a=>{if(a instanceof G){new h.Notice(a.message);return}if(a instanceof k){i&&this.viewIsShowingFile(i,e)&&i.renderError(e,this.t("cancelledError")),new h.Notice(this.t("cancelled"));return}let s=We(a);console.error(a),i&&this.viewIsShowingFile(i,e)&&i.renderError(e,a.message||String(a)),new h.Notice(this.t("generationFailed",{kind:s==="unknown"?"":` (${s})`,error:a.message||a}))})}async runBatchForFolder(){if(this.activeBatch){new h.Notice(this.t("batchAlreadyRunning"));return}let e=this.t("batchSelectFolder"),n=this.t("batchFolderPrompt"),i=await new Promise(l=>{let u=new h.Modal(this.app);u.onOpen=()=>{u.contentEl.createEl("p",{text:e});let p=u.contentEl.createDiv({cls:"parallel-reader-modal-field"}).createEl("input",{type:"text"});p.placeholder=n,p.addEventListener("keydown",g=>{g.key==="Enter"&&(l(p.value.trim()),u.close())}),u.contentEl.createEl("button",{text:"OK"}).addEventListener("click",()=>{l(p.value.trim()),u.close()})},u.onClose=()=>l(null),u.open()});if(i===null)return;let a=_e(i,l=>{let u=this.app.vault.getAbstractFileByPath(l);return!!u&&!(u instanceof h.TFile)});if(!a.valid){let l=a.reason==="unsafe"?"batchInvalidFolderInput":"batchFolderNotFound";new h.Notice(this.t(l,{path:a.folderPath||i}));return}let s=Ve(this.app.vault.getMarkdownFiles(),a.folderPath);if(s.length===0){new h.Notice(this.t("batchNoMarkdown"));return}let c=$e();this.activeBatch=c;let o=je(s.length);try{for(let l=0;l({title:a.title,level:2,anchor:a.anchor,gist:a.gist,startLine:J(e,a.anchor),bullets:a.bullets||[]}));return i.sort((a,s)=>a.startLine<0&&s.startLine<0?0:a.startLine<0?1:s.startLine<0?-1:a.startLine-s.startLine),i}async syncViewToFile(e){if(!e?.path?.endsWith(".md"))return;let n=this.app.workspace.getLeavesOfType(B);if(n.length===0)return;let i=n[0].view;if(!i||!this.activeFileStillMatches(e))return;let a=this.cacheManager.get(e.path);if(!a){i.loadFor(e,[],!1),i.renderEmptyWithHint(e);return}let s=await this.app.vault.read(e);if(!this.activeFileStillMatches(e))return;let c=!j(a,s,this.settings);this.cacheTouch(e.path),i.loadFor(e,this.resolveCardAnchors(s,a.cards),c)}bindScrollSync(){this._scrollDispose&&(this._scrollDispose(),this._scrollDispose=null);let e=this.getActiveView();if(!e)return;let n=e.editor,i=n&&n.cm,a=i?.scrollDOM?i.scrollDOM:e.contentEl.querySelector(".cm-scroller");if(!a)return;let s=at(()=>this.handleEditorScroll(e));a.addEventListener("scroll",s,{passive:!0}),this._scrollDispose=()=>{s.cancel(),a.removeEventListener("scroll",s)}}handleEditorScroll(e){let n=this.getParallelView();if(!n||!e.file||n.sourceFile?.path!==e.file.path)return;let i=e.editor,a=i&&i.cm;if(!a?.scrollDOM)return;let s=a.scrollDOM.getBoundingClientRect(),c=it(s),o=0;try{let l=a.posAtCoords({x:s.left+20,y:c});l!=null&&(o=a.state.doc.lineAt(l).number-1)}catch{return}let d=-1;for(let l=0;l{let e=this.getActiveView();await this.ensureView()&&e?.file&&await this.syncViewToFile(e.file)}),this.registerView(B,e=>new Fe(e,this)),this.addCommand({id:"run",name:this.t("cmdRun"),callback:()=>this.runForActiveFile(!1)}),this.addCommand({id:"regen",name:this.t("cmdRegen"),callback:()=>this.runForActiveFile(!0)}),this.addCommand({id:"open-view",name:this.t("cmdOpenView"),callback:async()=>{let e=this.getActiveView();await this.ensureView()&&e?.file&&this.syncViewToFile(e.file)}}),this.addCommand({id:"export-current",name:this.t("cmdExport"),callback:()=>this.exportCurrentView()}),this.addCommand({id:"copy-current-markdown",name:this.t("cmdCopyMarkdown"),callback:()=>this.copyCurrentViewMarkdown()}),this.addCommand({id:"cancel-current",name:this.t("cmdCancel"),callback:()=>this.cancelActiveGeneration()}),this.addCommand({id:"clear-current",name:this.t("cmdClearCurrent"),callback:async()=>{let e=this.getActiveView();if(!e?.file)return new h.Notice(this.t("noCurrentNote"));await this.cacheManager.delete(e.file.path),new h.Notice(this.t("cacheClearedFile",{name:e.file.basename}))}}),this.addCommand({id:"clear-all",name:this.t("cmdClearAll"),callback:async()=>{let e=Object.keys(this.cacheManager.cache).length;await this.cacheManager.clear(),new h.Notice(this.t("cacheClearedAll",{count:e}))}}),this.addCommand({id:"card-prev",name:this.t("cmdCardPrev"),callback:()=>this.moveActiveCard(-1)}),this.addCommand({id:"card-next",name:this.t("cmdCardNext"),callback:()=>this.moveActiveCard(1)}),this.addCommand({id:"card-jump",name:this.t("cmdCardJump"),callback:()=>this.jumpActiveCard()}),this.addCommand({id:"batch-generate",name:this.t("cmdBatchGenerate"),callback:()=>this.runBatchForFolder()}),this.addSettingTab(new Te(this.app,this)),this.registerEvent(this.app.workspace.on("active-leaf-change",()=>this.bindScrollSync())),this.registerEvent(this.app.workspace.on("file-open",e=>{e&&this.syncViewToFile(e)})),this.registerEvent(this.app.workspace.on("file-menu",(e,n)=>this.addFileMenuItems(e,n))),this.registerEvent(this.app.vault.on("rename",(e,n)=>{e instanceof h.TFile&&this.handleFileRename(e,n)})),this.registerEvent(this.app.vault.on("delete",e=>{e instanceof h.TFile&&this.handleFileDelete(e)})),this.bindScrollSync()}onunload(){this.flushSettingsSave(),this.flushCacheSave()}async loadSettings(){let n=(await this.loadData()||{}).settings||{};this.settings=le(Object.assign({},f,n)),this.cacheManager=new z(this.app.vault.adapter,this.app.vault.configDir,this.manifest?.id||"parallel-reader",()=>this.settings),await this.cacheManager.load()}async saveSettings(){this._settingsSaveTimer&&(clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=null),await this.saveData({settings:this.settings})}saveSettingsDebounced(e=400){this._settingsSaveTimer&&clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=setTimeout(()=>{this._settingsSaveTimer=null,this.saveSettings().catch(n=>console.error("[parallel-reader] failed to save settings",n))},e)}async flushSettingsSave(){this._settingsSaveTimer&&(clearTimeout(this._settingsSaveTimer),this._settingsSaveTimer=null,await this.saveSettings())}cacheTouch(e){return this.cacheManager.touch(e)}scheduleCacheSave(e=5e3){this.cacheManager.scheduleSave(e)}async flushCacheSave(){await this.cacheManager.flush()}async cacheReplaceCards(e,n){return this.cacheManager.replaceCards(e,n)}async cacheClear(){return this.cacheManager.clear()}async pruneCacheIfNeeded(){return this.cacheManager.pruneIfNeeded()}async ensureView(){let{workspace:e}=this.app,n=e.getLeavesOfType(B)[0];if(!n){let i=e.getRightLeaf(!1);if(!i)return new h.Notice(this.t("viewOpenFailed")),null;n=i,await n.setViewState({type:B,active:!0})}return await e.revealLeaf(n),n.view}getActiveView(){return this.app.workspace.getActiveViewOfType(h.MarkdownView)}getParallelView(){return this.app.workspace.getLeavesOfType(B)[0]?.view}moveActiveCard(e){let n=this.getParallelView();return n?.sections.length?n.moveActiveSection(e):(new h.Notice(this.t("noActiveCard")),-1)}jumpActiveCard(){let e=this.getParallelView();return!e||e.jumpToActiveSection()<0?(new h.Notice(this.t("noActiveCard")),!1):!0}isGeneratingFile(e){return!!e&&!!e.path&&this.jobs.isRunning(e.path)}cancelGenerationForFile(e){if(!e?.path)return new h.Notice(this.t("noCancelableJob")),!1;let n=this.jobs.get(e.path),i=rt(this.settings,n),a=this.jobs.cancel(e.path);return a&&this.activeBatch?.currentPath===e.path&&pe(this.activeBatch),new h.Notice(a?this.t(i):this.t("noCancelableJob")),a}requestBatchCancellation(){return pe(this.activeBatch)}viewIsShowingFile(e,n){return!!e&&!!n&&e.sourceFile?.path===n.path}activeFileStillMatches(e){let n=this.getActiveView();return!n?.file||n.file.path===e.path}cancelActiveGeneration(){if(this.requestBatchCancellation()){let i=this.activeBatch?.currentPath;i&&this.jobs.cancel(i),new h.Notice(this.t("batchCancelRequested"));return}let e=this.getActiveView();if(e?.file&&this.cancelGenerationForFile(e.file))return;let n=this.getParallelView();n?.sourceFile?this.cancelGenerationForFile(n.sourceFile):new h.Notice(this.t("noCancelableJob"))}confirmRegenerateEditedCards(){return new Promise(e=>{let n=this.t("confirmRegenerateEditedCards"),i=new h.Modal(this.app);i.titleEl.setText(this.t("displayName")),i.contentEl.createEl("p",{text:n});let a=i.contentEl.createDiv({cls:"modal-button-container"});a.createEl("button",{text:"Cancel"}).addEventListener("click",()=>{i.close(),e(!1)}),a.createEl("button",{text:"OK",cls:"mod-cta"}).addEventListener("click",()=>{i.close(),e(!0)}),i.onClose=()=>e(!1),i.open()})}addFileMenuItems(e,n){!(n instanceof h.TFile)||!n.path.endsWith(".md")||(e.addSeparator(),e.addItem(i=>i.setTitle(this.t("fileMenuGenerate")).setIcon("book-open").onClick(()=>this.runForFile(n,!1))),e.addItem(i=>i.setTitle(this.t("fileMenuRegen")).setIcon("refresh-cw").onClick(()=>this.runForFile(n,!0))),this.cacheManager.get(n.path)&&e.addItem(i=>i.setTitle(this.t("fileMenuClear")).setIcon("trash").onClick(async()=>{await this.cacheManager.delete(n.path),new h.Notice(this.t("cacheClearedFile",{name:n.basename}))})))}async handleFileRename(e,n){if(!(e instanceof h.TFile)||!n)return;let i=n.endsWith(".md"),a=e.path.endsWith(".md");if(!i&&!a)return;if(i&&!a){await this.cacheManager.delete(n);let c=this.getParallelView();c&&c.sourceFile?.path===n&&c.renderEmpty();return}if(!i)return;await this.cacheManager.move(n,e.path);let s=this.getParallelView();s?.sourceFile&&(s.sourceFile.path===n||s.sourceFile.path===e.path)&&(s.sourceFile=e,await this.syncViewToFile(e))}async handleFileDelete(e){if(!(e instanceof h.TFile))return;await this.cacheManager.delete(e.path);let n=this.getParallelView();n?.sourceFile?.path===e.path&&n.renderEmpty()}async exportCurrentView(){let e=this.getActiveView(),n=await this.ensureView();if(n){if((!n.sourceFile||!n.sections.length)&&e?.file&&await this.syncViewToFile(e.file),!n.sourceFile||!n.sections.length){new h.Notice(this.t("noExportContent"));return}await n.exportToVault()}}async copyCurrentViewMarkdown(){let e=this.getActiveView(),n=await this.ensureView();if(n){if((!n.sourceFile||!n.sections.length)&&e?.file&&await this.syncViewToFile(e.file),!n.sourceFile||!n.sections.length){new h.Notice(this.t("noCopyContent"));return}await O(ie(`${n.sourceFile.basename} \xB7 ${this.t("displayName")}`,n.sections),this.t("copiedAllMarkdown"))}}async runForActiveFile(e){let n=this.getActiveView();if(!n?.file){new h.Notice(this.t("openNoteFirst"));return}return this.runForFile(n.file,e)}async runForFile(e,n){if(!e){new h.Notice(this.t("openNoteFirst"));return}if(this.jobs.isRunning(e.path)){new h.Notice(this.t("alreadyGenerating"));return}if(qe(this.cacheManager.get(e.path),n)&&!await this.confirmRegenerateEditedCards()){new h.Notice(this.t("regenerateCancelled"));return}let i=null;return this.jobs.start(e.path,async a=>{a.setPhase("reading");let s=await this.app.vault.read(e);if(a.throwIfCancelled(),!s.trim()){new h.Notice(this.t("emptyNote"));return}if(i=await this.ensureView(),!i)return;if(a.throwIfCancelled(),a.setPhase("cache-check"),!n){let p=this.cacheManager.get(e.path);if(p&&j(p,s,this.settings)){this.cacheTouch(e.path),this.activeFileStillMatches(e)&&i.loadFor(e,this.resolveCardAnchors(s,p.cards),!1);return}}i.renderLoading(e,this.t("loadingGenerating"));let c=Number(this.settings.maxDocChars)||f.maxDocChars;s.length>c&&new h.Notice(this.t("longNoteTruncated",{count:c})),new h.Notice(this.t("generatingNotice")),a.setPhase("generating");let o=i,d=o?p=>{!p.done&&this.viewIsShowingFile(o,e)&&o.renderStreamingPreview(e,p.accumulated)}:void 0,l=await tt(s,this.settings,a,d);if(a.throwIfCancelled(),l.length===0){new h.Notice(this.t("noCardsReturned"));return}let u=l.map(p=>({title:p.title,anchor:p.anchor,gist:p.gist,bullets:p.bullets}));a.setPhase("saving"),await this.cacheManager.put(e.path,s,u,this.settings),a.throwIfCancelled(),this.viewIsShowingFile(i,e)&&i.loadFor(e,l,!1);let y=l.filter(p=>p.startLine<0).length;new h.Notice(this.t("generationDone",{count:l.length,suffix:y?this.t("unanchoredSuffix",{count:y}):""}))}).catch(a=>{if(a instanceof G){new h.Notice(a.message);return}if(a instanceof k){i&&this.viewIsShowingFile(i,e)&&i.renderError(e,this.t("cancelledError")),new h.Notice(this.t("cancelled"));return}let s=We(a);console.error(a),i&&this.viewIsShowingFile(i,e)&&i.renderError(e,a.message||String(a)),new h.Notice(this.t("generationFailed",{kind:s==="unknown"?"":` (${s})`,error:a.message||a}))})}async runBatchForFolder(){if(this.activeBatch){new h.Notice(this.t("batchAlreadyRunning"));return}let e=this.t("batchSelectFolder"),n=this.t("batchFolderPrompt"),i=await new Promise(l=>{let u=new h.Modal(this.app);u.onOpen=()=>{u.contentEl.createEl("p",{text:e});let p=u.contentEl.createDiv({cls:"parallel-reader-modal-field"}).createEl("input",{type:"text"});p.placeholder=n,p.addEventListener("keydown",g=>{g.key==="Enter"&&(l(p.value.trim()),u.close())}),u.contentEl.createEl("button",{text:"OK"}).addEventListener("click",()=>{l(p.value.trim()),u.close()})},u.onClose=()=>l(null),u.open()});if(i===null)return;let a=_e(i,l=>{let u=this.app.vault.getAbstractFileByPath(l);return!!u&&!(u instanceof h.TFile)});if(!a.valid){let l=a.reason==="unsafe"?"batchInvalidFolderInput":"batchFolderNotFound";new h.Notice(this.t(l,{path:a.folderPath||i}));return}let s=Ve(this.app.vault.getMarkdownFiles(),a.folderPath);if(s.length===0){new h.Notice(this.t("batchNoMarkdown"));return}let c=$e();this.activeBatch=c;let o=je(s.length);try{for(let l=0;l({title:a.title,level:2,anchor:a.anchor,gist:a.gist,startLine:J(e,a.anchor),bullets:a.bullets||[]}));return i.sort((a,s)=>a.startLine<0&&s.startLine<0?0:a.startLine<0?1:s.startLine<0?-1:a.startLine-s.startLine),i}async syncViewToFile(e){if(!e?.path?.endsWith(".md"))return;let n=this.app.workspace.getLeavesOfType(B);if(n.length===0)return;let i=n[0].view;if(!i||!this.activeFileStillMatches(e))return;let a=this.cacheManager.get(e.path);if(!a){i.loadFor(e,[],!1),i.renderEmptyWithHint(e);return}let s=await this.app.vault.read(e);if(!this.activeFileStillMatches(e))return;let c=!j(a,s,this.settings);this.cacheTouch(e.path),i.loadFor(e,this.resolveCardAnchors(s,a.cards),c)}bindScrollSync(){this._scrollDispose&&(this._scrollDispose(),this._scrollDispose=null);let e=this.getActiveView();if(!e)return;let n=e.editor,i=n&&n.cm,a=i?.scrollDOM?i.scrollDOM:e.contentEl.querySelector(".cm-scroller");if(!a)return;let s=at(()=>this.handleEditorScroll(e));a.addEventListener("scroll",s,{passive:!0}),this._scrollDispose=()=>{s.cancel(),a.removeEventListener("scroll",s)}}handleEditorScroll(e){let n=this.getParallelView();if(!n||!e.file||n.sourceFile?.path!==e.file.path)return;let i=e.editor,a=i&&i.cm;if(!a?.scrollDOM)return;let s=a.scrollDOM.getBoundingClientRect(),c=it(s),o=0;try{let l=a.posAtCoords({x:s.left+20,y:c});l!=null&&(o=a.state.doc.lineAt(l).number-1)}catch{return}let d=-1;for(let l=0;l { + .catch((e) => { if (e instanceof GenerationJobAlreadyRunningError) { new Notice(e.message); return;