mirror of
https://github.com/lllin000/PaperForge.git
synced 2026-07-22 06:50:53 +00:00
55 lines
200 KiB
JavaScript
55 lines
200 KiB
JavaScript
"use strict";var qt=Object.create;var Ve=Object.defineProperty;var Zt=Object.getOwnPropertyDescriptor;var Jt=Object.getOwnPropertyNames;var Gt=Object.getPrototypeOf,Yt=Object.prototype.hasOwnProperty;var Xt=(p,d)=>()=>(d||p((d={exports:{}}).exports,d),d.exports),Qt=(p,d)=>{for(var e in d)Ve(p,e,{get:d[e],enumerable:!0})},bt=(p,d,e,t)=>{if(d&&typeof d=="object"||typeof d=="function")for(let r of Jt(d))!Yt.call(p,r)&&r!==e&&Ve(p,r,{get:()=>d[r],enumerable:!(t=Zt(d,r))||t.enumerable});return p};var H=(p,d,e)=>(e=p!=null?qt(Gt(p)):{},bt(d||!p||!p.__esModule?Ve(e,"default",{value:p,enumerable:!0}):e,p)),er=p=>bt(Ve({},"__esModule",{value:!0}),p);var it=Xt((yr,ir)=>{ir.exports={versions:[{version:"1.5.15",date:"2026-06-01",title:"\u5168\u6587\u5B58\u50A8\u91CD\u6784 + OCR \u9605\u8BFB\u987A\u5E8F\u4FEE\u590D + Redo \u4E00\u952E\u91CD\u505A",breaking_or_migration:["\u5168\u6587\u6587\u4EF6\u73B0\u5728\u7EDF\u4E00\u5B58\u653E\u4E8E System/PaperForge/ocr/ \u4E0B\uFF0C\u4E0D\u518D\u5728\u5DE5\u4F5C\u533A\u4FDD\u7559\u526F\u672C","Redo OCR \u73B0\u5728\u4F1A\u7ACB\u5373\u6267\u884C\uFF08\u4E00\u952E\u5B8C\u6210\uFF09\uFF0C\u4E0D\u518D\u9700\u8981\u624B\u52A8\u518D\u8DD1\u4E00\u6B21"],new_features:["Redo OCR \u4E00\u952E\u95ED\u73AF\uFF1A\u52FE\u9009 \u2192 \u70B9\u6309\u94AE \u2192 \u81EA\u52A8\u5B8C\u6210\u5168\u90E8\u6D41\u7A0B","\u8BBE\u7F6E\u9875\u65B0\u589E\u300C\u66F4\u65B0\u4E0E\u624B\u518C\u300D\u6807\u7B7E\u9875\uFF0C\u53EF\u968F\u65F6\u67E5\u770B\u7248\u672C\u66F4\u65B0\u8BB0\u5F55\u548C\u4F7F\u7528\u624B\u518C","\u63D2\u4EF6\u66F4\u65B0\u540E\u81EA\u52A8\u5F39\u51FA\u66F4\u65B0\u8BF4\u660E"],fixes:["\u4FEE\u590D\u5168\u6587\u9605\u8BFB\u987A\u5E8F\u6DF7\u4E71\uFF0C\u4F18\u5316\u6574\u4F53\u6392\u7248\u4F53\u9A8C","\u4FEE\u590D\u7AE0\u8282\u6807\u9898\u548C\u6B63\u6587\u6BB5\u843D\u9519\u4F4D\u65AD\u5F00\u7684\u95EE\u9898","\u4FEE\u590D\u56FE\u8868\u548C\u5BF9\u5E94\u56FE\u6CE8\u88AB\u5206\u5F00\u7684\u95EE\u9898","\u4FEE\u590D\u9996\u9875\u6458\u8981\u533A\u5757\u6392\u5E8F\u5F02\u5E38","\u4FEE\u590D\u5E76\u6392\u56FE\u7247\u672A\u80FD\u81EA\u52A8\u5408\u5E76\u7684\u95EE\u9898","Dashboard \u73B0\u5728\u80FD\u6B63\u786E\u8BC6\u522B\u65B0\u7684\u5168\u6587\u6587\u4EF6\u4F4D\u7F6E"],recommended_actions:["\u65E7\u7248 OCR \u5168\u6587\u53EF\u80FD\u5B58\u5728\u9605\u8BFB\u987A\u5E8F\u95EE\u9898\uFF0C\u5EFA\u8BAE\u5BF9\u91CD\u8981\u8BBA\u6587\u6267\u884C\u4E00\u6B21 Redo OCR","\u6253\u5F00\u5168\u6587\u8BF7\u76F4\u63A5\u4F7F\u7528 Dashboard \u7684\u300C\u6253\u5F00\u5168\u6587\u300D\u6309\u94AE"]}]}});var fr={};Qt(fr,{default:()=>Xe});module.exports=er(fr);var Y=require("obsidian"),U=H(require("fs")),Ae=H(require("path")),ge=require("child_process");var ke="paperforge-status",Be="paperforge",Et='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path><line x1="8" y1="7" x2="16" y2="7"></line><line x1="8" y1="11" x2="14" y2="11"></line></svg>',ie=[{id:"paperforge-sync",title:"Sync Library",desc:"Pull new references from Zotero and generate literature notes",icon:"\u21BB",cmd:"sync",okMsg:"Sync complete"},{id:"paperforge-ocr",title:"Run OCR",desc:"Extract full text and figures from PDFs via PaddleOCR",icon:"\u229E",cmd:"ocr",okMsg:"OCR started"},{id:"paperforge-doctor",title:"Run Doctor",desc:"Verify PaperForge setup \u2014 check configs, Zotero, paths, and index health",icon:"\u2695",cmd:"doctor",okMsg:"Doctor complete"},{id:"paperforge-repair",title:"Repair Issues",desc:"Fix three-way state divergence, path errors, and rebuild index",icon:"\u21BA",cmd:"repair",args:["--fix","--fix-paths"],okMsg:"Repair complete"},{id:"paperforge-ocr-redo",title:"Redo OCR",desc:"Re-run OCR for papers marked ocr_redo: true",icon:"\u21BA",cmd:"ocr",args:["redo"],okMsg:"OCR redo started"}],Oe={vault_path:"",setup_complete:!1,auto_update:!0,auto_update_on_startup:!0,agent_platform:"opencode",language:"",paddleocr_api_key:"",zotero_data_dir:"",python_path:"",features:{memory_layer:!0,vector_db:!1},selected_skill_platform:"opencode",vector_db_api_key:"",vector_db_api_base:"",vector_db_api_model:"text-embedding-3-small",frozen_skills:{},system_dir:"",resources_dir:"",literature_dir:"",base_dir:"",capabilityState:{},last_seen_version:""};function xt(p,d){if(!d||!d.note_path)return d;let e=p.vault.getAbstractFileByPath(d.note_path);if(!e)return d;let t=p.metadataCache.getFileCache(e),r=t&&t.frontmatter;if(!r)return d;let n={...d};for(let a of["do_ocr","analyze","ocr_status","ocr_redo","deep_reading_status"])Object.prototype.hasOwnProperty.call(r,a)&&(n[a]=r[a]);return n}function Qe(p,d){return p&&{...p,...d}}var et=1,Se=["installation","library","ocr","memory","maintenance","help"],tr=["unknown","unavailable","missing_input","needs_action","limited","ready"],rr=["unknown","ok","warning","error"],nr=["idle","running"];function sr(p){if(!p||typeof p!="object"||Array.isArray(p))return!1;let d=p;return!(typeof d.verb!="string"||typeof d.label!="string"||typeof d.destructive!="boolean"||d.destructive_scope!==null&&typeof d.destructive_scope!="string"||d.destructive_effect!==null&&typeof d.destructive_effect!="string"||typeof d.confirmation_required!="boolean"||d.confirmation_prompt!==null&&typeof d.confirmation_prompt!="string"||typeof d.command!="string"||typeof d.scope!="string"||typeof d.scope_count!="number")}function Le(p){return{verb:"probe",label:"Check",destructive:!1,destructive_scope:null,destructive_effect:null,confirmation_required:!1,confirmation_prompt:null,command:`probe ${p}`,scope:p,scope_count:1}}function tt(p,d){if(!p||typeof p!="object")return!1;let e=p;if(e.schema_version!==1||typeof e.module!="string"||!e.module||!Se.includes(e.module)||d!==void 0&&e.module!==d||typeof e.capability_state!="string"||!tr.includes(e.capability_state)||typeof e.severity!="string"||!rr.includes(e.severity)||typeof e.activity_state!="string"||!nr.includes(e.activity_state)||e.activity_label!==null&&typeof e.activity_label!="string")return!1;if(e.activity_progress!==null){if(typeof e.activity_progress!="object")return!1;let n=e.activity_progress;if(typeof n.current!="number"||typeof n.total!="number")return!1}if(!Array.isArray(e.notices)||!e.reason||typeof e.reason!="object")return!1;let t=e.reason;if(typeof t.code!="string"||typeof t.text!="string"||!e.action||typeof e.action!="object")return!1;let r=e.action;return!(r.primary!==null&&!sr(r.primary)||typeof e.updated_at!="string"||!e.updated_at||typeof e.ttl_seconds!="number")}function He(p){return{schema_version:et,module:p,capability_state:"unknown",activity_state:"idle",activity_label:null,activity_progress:null,severity:"unknown",reason:{code:`${p}.no_probe`,text:`${p} has not been probed yet.`},action:{primary:Le(p)},notices:[],updated_at:new Date(0).toISOString(),ttl_seconds:0}}function rt(p){return{schema_version:et,module:p,capability_state:"unknown",activity_state:"idle",activity_label:null,activity_progress:null,severity:"unknown",reason:{code:`${p}.stale`,text:`Cached probe data for ${p} is stale.`},action:{primary:Le(p)},notices:[],updated_at:new Date(0).toISOString(),ttl_seconds:0}}function Pe(p){return{schema_version:et,module:p,capability_state:"unknown",activity_state:"idle",activity_label:null,activity_progress:null,severity:"unknown",reason:{code:`${p}.invalid_response`,text:`Probe response for ${p} was invalid.`},action:{primary:Le(p)},notices:[],updated_at:new Date(0).toISOString(),ttl_seconds:0}}function nt(p){if(p.activity_state==="running")return!1;if(p.ttl_seconds<=0)return!0;let d=new Date(p.updated_at).getTime();return isNaN(d)?!0:Date.now()-d>p.ttl_seconds*1e3}function kt(p){return p.capability_state==="ready"&&p.action.primary===null}function wt(p){var r,n,a;let d=(r=p.action)==null?void 0:r.primary,e=(n=d==null?void 0:d.verb)!=null?n:"probe",t=(a=d==null?void 0:d.label)!=null?a:e;return e==="setup"||e==="set_config"||e==="update"?{kind:"setup",verb:e,label:t}:e==="probe"?{kind:"probe",verb:e,label:t}:{kind:"action",verb:e,label:t}}function St(p,d){let e={};for(let t of d){let r=p[t];if(!r||typeof r!="object"){e[t]=He(t);continue}if(!tt(r,t)){e[t]=Pe(t);continue}if(nt(r)){e[t]=rt(t);continue}e[t]=r}return e}var st={en:{action_running:"Running ",api_key_missing:"Missing",api_key_set:"Entered",btn_install:"Open Setup Wizard",btn_install_desc:"Check whether the environment is ready, then open the step-by-step setup wizard",btn_reconfig:"Reconfigure",btn_reconfig_desc:"Open the setup wizard again to change directories, platform, or API keys",btn_validate:"Validate",check_bbt_fail:"Not detected",check_bbt_ok:"Installed",check_python_fail:"Not found",check_python_ok:"Ready",check_zotero_fail:"Not detected",check_zotero_ok:"Found",complete_export_path:"Save Better BibTeX JSON exports into:",complete_next:"Recommended next steps",complete_step1:"Open Dashboard",complete_step1_desc:'Press Ctrl+P and run "PaperForge: Open Main Panel", or click the PaperForge icon in the left sidebar.',complete_step2:"Sync Literature",complete_step2_desc:"In the main panel, click Sync Library to bring papers from Zotero into Obsidian and generate notes.",complete_step3:"Run OCR",complete_step3_desc:"In the Obsidian Base view, mark do_ocr:true on papers, then run OCR in the main panel.",complete_step4:"Configure Better BibTeX Auto-export",complete_step4_desc:'In Zotero, right-click the library or collection you want to sync -> Export -> Better BibTeX JSON -> enable "Keep updated".',complete_summary:"Saved Configuration",complete_title:"Setup Complete",copied:"Copied!",copy_pf_deep_cmd:"Copy /pf-deep Command",dashboard_drift_warning:"PaperForge CLI (v{0}) differs from plugin (v{1}). Open Settings \u2192 Runtime Health to sync.",deep_reading_not_found:"Deep reading file not found",desc:"Obsidian + Zotero literature pipeline. Sync papers, generate notes, run OCR, and read deeply in one place.",dir_base:"Base Dir",dir_index:"Index Dir",dir_notes:"Notes Dir",dir_resources:"Resource Dir",dir_system:"System Dir",dir_vault:"Vault Path",error_copied:"Copied!",error_copy_diagnostic:"Copy diagnostic",feat_agent_platform:"Agent Platform",feat_agent_platform_desc:"Select which agent platform to manage skills for.",feat_api_base_url:"API Base URL",feat_api_base_url_desc:"Custom OpenAI-compatible API endpoint. Leave empty for default.",feat_api_model:"API Model",feat_api_model_desc:"Embedding model name for this endpoint.",feat_build_btn:"Build",feat_build_complete:"Vector build complete.",feat_build_failed:"Build failed. See terminal output.",feat_building:"Building...",feat_cache_remove_failed:"Failed: {0}",feat_cache_removed:"Model cache removed.",feat_checking:"Checking...",feat_checking_btn:"Checking...",feat_deps_checking:"Checking dependencies...",feat_deps_missing:"Dependencies not installed. Required: chromadb, openai.",feat_enter_key:"Enter a valid OpenAI API key.",feat_install_btn:"Install",feat_install_deps:"Install Dependencies",feat_install_deps_desc:"pip install chromadb openai (~35MB).",feat_install_done:"Dependencies installed. Building vectors...",feat_install_failed:"Install failed: ",feat_installing:"Installing...",feat_installing_pkgs:"Installing {pkgs}...",feat_key_rejected:"API key rejected.",feat_memory_desc:"The Memory Layer is the core data engine of PaperForge, powered by SQLite. It integrates literature metadata (papers, assets, aliases, reading events), provides FTS5 metadata search across titles, abstracts, authors, domains, and collections, and powers agent-context and paper-status. Always active \u2014 no toggle needed.",feat_memory_rebuild_btn:"Rebuild",feat_memory_rebuild_done:"Memory DB rebuilt.",feat_memory_rebuild_failed:"Rebuild failed.",feat_memory_rebuilding:"Rebuilding...",feat_model_changed_warn:"Model changed ({0} -> {1}). Existing vectors are incompatible \u2014 rebuild required.",feat_network_error:"Network error: ",feat_no_python:"No Python found. Check Installation tab.",feat_not_cached:"Not cached",feat_openai_key:"OpenAI API Key",feat_openai_key_desc:"Used for API embedding calls. Model is defined below.",feat_output_copied:"Output copied to clipboard.",feat_rebuild_btn:"Rebuild",feat_rebuild_vectors:"Rebuild Vectors",feat_rebuild_vectors_changed:"Model changed \u2014 rebuild to update all vectors.",feat_rebuild_vectors_desc:"Rebuild all OCR fulltext vectors. Required after model or mode change.",feat_removing:"Removing...",feat_retry_btn:"Retry",feat_skills_desc:"Manage and enable/disable agent skills installed in your vault. Each row corresponds to a SKILL.md file \u2014 toggle off to prevent the agent from auto-invoking that skill.",feat_skills_system:"System Skills ship with PaperForge and are updated alongside PaperForge.",feat_skills_user:"User Skills are custom skills you install from community or create yourself.",feat_uninstall_btn:"Uninstall",feat_valid_key:"API key valid.",feat_vector_config_label:"Vector Settings",feat_vector_corrupted:"Vector index corrupted \u2014 needs force rebuild.",feat_vector_desc:"Vector Database enables semantic search across OCR-extracted fulltext via API embedding. Documents are split into chunks, embedded via OpenAI-compatible API, and stored in ChromaDB.",feat_vector_enable:"Enable Vector Retrieval",feat_vector_enable_desc:"Semantic search across OCR fulltext. Requires: pip install openai chromadb (~35MB).",feat_vector_rebuild_force_btn:"Force Rebuild",feat_verify:"Verify",feat_verify_btn:"Verify",field_paddleocr:"PaddleOCR API Key",field_python_custom:"Custom Path",field_python_interp:"Python Interpreter",field_zotero_data:"Zotero Data Dir",field_zotero_placeholder:"Required. Path to Zotero data directory for PDF attachment resolution.",guide_ocr:"Run OCR",guide_ocr_desc:"In the main panel, click Run OCR to extract full text and figures from PDFs for later reading and analysis.",guide_open:"Open Main Panel",guide_open_desc:'Press Ctrl+P and run "PaperForge: Open Main Panel", or click the PaperForge icon in the left sidebar.',guide_sync:"Sync Literature",guide_sync_desc:"After Better BibTeX JSON export is configured, click Sync Library to import papers from Zotero into Obsidian and generate notes automatically.",header_title:"PaperForge",install_bootstrapping:"PaperForge Python package not found. Installing automatically...",install_btn:"Start Install",install_btn_retry:"Retry",install_btn_running:"Installing...",install_complete:"Installation complete!",install_failed:"Installation failed: ",install_validating:"Validating setup...",jump_to_deep_reading:"Open Deep Reading",label_agent:"Agent Platform",nav_close:"Close",nav_next:"Next",nav_prev:"Back",not_set:"Not entered",notice_check_fail:"Missing: ",notice_python_missing:"Python was not detected. Install Python 3.10+ and add it to PATH.",ocr_privacy_title:"OCR Privacy Notice",ocr_privacy_warning:"OCR will upload PDFs to the PaddleOCR API. Do not upload sensitive or confidential documents.",ocr_queue_add:"Add to OCR Queue",ocr_queue_added:"Added to OCR queue",ocr_queue_remove:"Remove from OCR Queue",ocr_queue_removed:"Removed from OCR queue",ocr_understand:"I understand, continue",optional_later:"(can be set later in Settings)",orphan_delete_failed:"Prune failed",orphan_delete_selected:"Delete {count} selected",orphan_deleted:"Deleted {count} orphan workspace(s)",orphan_desc:"These papers are no longer in your Zotero library.",orphan_deselect_all:"Deselect all",orphan_explain:"Removed from Zotero. Workspace files remain on disk.",orphan_keep_all:"Keep all",orphan_none_selected:"No papers selected for deletion",orphan_select_all:"Select all",orphan_title:"Found {count} orphan paper(s)",panel_actions:"Quick Actions",prep_bbt:"Better BibTeX",prep_bbt_desc:"In Zotero: Tools -> Add-ons -> install Better BibTeX.",prep_export:"Better BibTeX Auto-export",prep_export_desc:'In Zotero, right-click the collection you want to sync -> Export Collection -> BetterBibTeX JSON -> enable "Keep updated" -> save the JSON file into the exports folder shown below. Obsidian Base views will use the JSON filename as the Base name:',prep_export_path_label:"Save the exported JSON file into this folder:",prep_key:"PaddleOCR Key",prep_key_desc:"Get your API key from https://aistudio.baidu.com/paddleocr",prep_python:"Python 3.10+",prep_python_desc:"Python must be available from the command line. If you are not sure, click below to auto-detect.",prep_zotero:"Zotero Desktop",prep_zotero_desc:"Install Zotero from https://www.zotero.org",run_in_agent:"Run in {0}",runtime_health:"Runtime Health",runtime_health_checking:"Checking...",runtime_health_desc:"Check whether the installed paperforge Python package matches the plugin version and whether the deployed skill contract is current.",runtime_health_match:"Match",runtime_health_mismatch:"Mismatch",runtime_health_package_ver:"Python package v{0}",runtime_health_plugin_ver:"Plugin v{0}",runtime_health_sync:"Sync Runtime",runtime_health_sync_done:"Runtime synced to v{0}",runtime_health_sync_fail:"Sync failed: {0}",runtime_health_syncing:"Syncing...",section_config:"Current Configuration",section_guide:"How To Use",section_prep:"Preparation",section_prep_desc:"Before first use, finish these 4 preparation items. Better BibTeX auto-export is configured after setup:",setup_done:"PaperForge environment is ready",setup_pending:"Not installed yet. Finish the preparation items below, then open the wizard.",tab_features:"Features",tab_setup:"Installation",tab_maintenance:"Maintenance",validate_base:"Base directory is required",validate_fail:"Please complete the required fields below",validate_index:"Index directory is required",validate_key:"PaddleOCR API key (optional, needed for OCR)",validate_notes:"Notes directory is required",validate_resources:"Resources directory is required",validate_system:"System directory is required",validate_vault:"Vault path is required",validate_zotero:"Zotero data directory (optional, needed for PDF linking)",wizard_agent_hint:"Choose the AI agent platform you use most often. PaperForge will place the matching command and skill files in the correct location.",wizard_dir_hint:"PaperForge stores user-facing literature data under the resources directory. These folders will live there:",wizard_dir_sub_hint:"Resolved folder preview based on the names below:",wizard_intro:"This wizard walks you through the full setup. In most cases, the default values are fine to keep.",wizard_keys_hint:"Enter your PaddleOCR API key below. If you want PaperForge to auto-locate Zotero PDFs, you can also fill in the Zotero data directory.",wizard_preview:"After installation, system files stay at the vault root while literature data stays under the resources directory.",wizard_safety:"Safety: if the selected folders already contain files, setup preserves existing files and only creates missing PaperForge folders and files.",wizard_step1:"Overview",wizard_step2:"Directory Setup",wizard_step3:"Platform & Keys",wizard_step4:"Install",wizard_step5:"Done",wizard_skip_ocr_desc:"OCR will not be available until you configure a valid PaddleOCR API key. You can continue setup now and configure it later in Settings.",wizard_skip_ocr_continue:"Continue without OCR key",wizard_skip_ocr_back:"Back to configure",wizard_api_hint_skip:"OCR key is optional \u2014 you may skip it and configure later.",wizard_sys_hint:"These folders live at the vault root, outside the resources directory:",wizard_title:"PaperForge Setup Wizard",ocr_maint_no_action:"No Action Needed",ocr_maint_rebuild:"Rebuild Recommended",ocr_maint_failed:"OCR Failed",ocr_maint_limited:"Result Limited",ocr_maint_needs_attention:"Needs Attention",ocr_maint_limitations:"Result Limitations",ocr_maint_hero_ok:"OCR looks usable overall.",ocr_maint_hero_warn:"OCR needs attention: {rebuild} rebuild recommended, {failed} failed.",ocr_maint_hero_note:"This page only promotes issues where maintenance is likely to help. Some papers may have limitations that maintenance will not improve.",ocr_maint_limitations_intro:"These papers look less certain, but PaperForge does not currently have a high-confidence maintenance action to recommend.",ocr_maint_all_papers:"All Papers",ocr_maint_rebuild_btn:"Rebuild results",ocr_maint_redo_btn:"Rerun OCR",ocr_maint_redo_confirm:"Rerun OCR for {n} paper(s)? Existing derived OCR artifacts will be replaced.",maintenance_group_retry:"Needs Retry",maintenance_group_rebuild:"Can Rebuild",maintenance_group_legacy:"Upgrade Available (Optional)",maintenance_btn_retry:"Retry",maintenance_btn_rebuild:"Rebuild",maintenance_btn_upgrade:"Upgrade",maintenance_refresh_spinning:"Updating\u2026",maintenance_all_good:"\u2705 All good \u2014 no action needed",maintenance_n_pending:"{n} need attention",maintenance_filter_all:"All",maintenance_filter_recommended:"Recommended",maintenance_batch_rebuild:"\u25B6 Rebuild selected",maintenance_batch_redo:"\u25B6 Full OCR redo selected",maintenance_stop:"Stop",maintenance_batch_complete:"Batch operation complete \u2014 {n} papers processed.",maintenance_progress_label:"{current}/{total} papers",version_panel_title:"Version History",version_panel_back:"Back",version_filter_placeholder:"Filter papers...",version_papers_count:"{n} papers",version_current:"current",version_restore_btn:"Restore",version_compare_btn:"Compare",version_restore_selected:"Restore selected",version_clear_old:"Clear old versions (free {size})",version_no_backups:"No version history available",version_restore_confirm:"Restore {label} for {paper}?",version_restore_done:"Restored {label}",version_compare_title:"{vA} vs {vB}",version_compare_paragraphs:"{n} paragraphs changed",version_error_read:"Cannot read version data",retrieval_search_placeholder:"Search papers... (@ for deep search)",retrieval_search_placeholder_deep:"Search paper content...",retrieval_search_idle_hint:"Type a keyword or @ to search paper content",retrieval_searching_metadata:"Searching metadata...",retrieval_searching_deep:"Deep searching...",retrieval_search_cancel:"Cancel",retrieval_results_count:"{n} result(s)",retrieval_empty:"No matching papers found.",retrieval_empty_tips:"Try broader terms or use @ deep search.",retrieval_vectors_not_built:"Vector index not built",retrieval_vectors_not_built_desc:"Build vectors to enable @ deep search with semantic matching.",retrieval_open_vector_settings:"Open Vector Settings",retrieval_backend_unavailable:"Search backend unavailable",retrieval_backend_unavailable_desc:"The Python CLI search backend is not responding correctly.",retrieval_run_doctor:"Run Doctor",retrieval_retry:"Retry",retrieval_timeout_title:"Search timed out",retrieval_timeout_desc:"The search took too long. Try a more specific query.",retrieval_model_changed:"Model changed",retrieval_model_changed_desc:"The embedding model has changed since vectors were built. Rebuild to use deep search.",retrieval_rebuild_vectors:"Rebuild Vectors",retrieval_build_idle:"Vector database ready",retrieval_build_ready:"{n} vector(s) built",retrieval_build_stopping:"Stopping...",retrieval_build_stopped:"Build stopped ({n}/{t} papers)",retrieval_build_failed:"Build failed",retrieval_build_stale:"Vectors are stale \u2014 rebuild recommended",retrieval_build_deps_missing:"Dependencies missing. Install chromadb and openai.",retrieval_build_runtime_mismatch:"Python runtime version mismatch.",retrieval_stop:"Stop",retrieval_no_python:"Python not found",retrieval_internal_error:"An internal error occurred",retrieval_force_rebuild:"Force Rebuild",retrieval_rebuild_warning:"Rebuild will replace {n} existing chunk(s). Continue?",cc_summary_ok:"All systems ready",cc_summary_core_ok:"Core environment ready; {n} modules pending detection",cc_summary_attention:"Some modules need attention",cc_summary_ok_body:"PaperForge environment is fully operational. Installation and documentation are verified.",cc_summary_core_ok_body:"Installation and Help modules are active. Library, OCR, Memory, and Maintenance will show live status once their backends are connected.",cc_summary_attention_body:"One or more core modules require your attention to function properly.",cc_badge_ok:"Ready",cc_badge_pending:"Pending",cc_badge_setup:"Setup needed",cc_badge_attention:"Needs attention",cc_diagnostic_toggle:"Details",cc_n_ready:"{n} ready",cc_n_pending:"{n} pending",cc_title:"System Status",cc_desc:"Real-time status of PaperForge core modules. Modules with a pending action need your attention.",cc_zone_attention:"Needs Attention",cc_zone_modules:"All Modules",cc_module_installation:"Installation",cc_module_help:"Help & Docs",cc_module_library:"Library Index",cc_module_ocr:"OCR Engine",cc_module_memory:"Memory Layer",cc_module_maintenance:"Maintenance",cc_state_ready:"Ready",cc_state_limited:"Limited",cc_state_unavailable:"Unavailable",cc_state_unknown:"Unknown",cc_severity_ok:"OK",cc_severity_unknown:"Unknown",cc_severity_warning:"Warning",cc_severity_error:"Error",cc_state_missing_input:"Missing Input",cc_state_needs_action:"Needs Action",cc_action_setup:"Open Setup Wizard",cc_action_probe:"Check",cc_action_set_config:"Set Config",cc_action_update:"Update",cc_reason_installation_ready:"PaperForge environment is set up correctly.",cc_reason_config_missing:"Configuration file is missing. Run setup to create one.",cc_reason_config_corrupt:"Configuration file is corrupt. Run setup to repair.",cc_reason_python_version_unsupported:"Python version is not supported. Install Python 3.11+.",cc_reason_help_ready:"Help documentation is available.",cc_reason_docs_missing:"Help documentation is not yet installed.",cc_reason_placeholder:"Detection pending \u2014 will show live status once connected.",cc_diag_module:"Module",cc_diag_state:"State",cc_diag_severity:"Severity",cc_diag_activity:"Activity",cc_diag_reason:"Reason",cc_diag_ttl:"TTL",cc_diag_updated:"Updated",cc_reason_no_probe:"{module} has not been probed yet.",cc_reason_stale:"Cached probe data for {module} is stale.",cc_reason_invalid_response:"Probe response for {module} was invalid.",cc_reason_probing:"Checking {module} status...",cc_notice_placeholder:"{module} module probing is not yet available; it will be added in a future update.",cc_notice_refreshed:"Module status refreshed.",cc_notice_refresh_failed:"Failed to refresh module status.",cc_activity_idle:"Idle",cc_activity_running:"Running"},zh:{action_running:"\u6B63\u5728\u6267\u884C ",api_key_missing:"\u672A\u914D\u7F6E \u2717",api_key_set:"\u5DF2\u914D\u7F6E \u2713",btn_install:"\u6253\u5F00\u5B89\u88C5\u5411\u5BFC",btn_install_desc:"\u81EA\u52A8\u68C0\u6D4B Python + \u524D\u7F6E\u73AF\u5883\uFF0C\u901A\u8FC7\u540E\u6253\u5F00\u5206\u6B65\u5B89\u88C5\u5411\u5BFC",btn_reconfig:"\u91CD\u65B0\u914D\u7F6E",btn_reconfig_desc:"\u91CD\u65B0\u8FD0\u884C\u5B89\u88C5\u5411\u5BFC\uFF0C\u4FEE\u6539\u76EE\u5F55\u6216\u5BC6\u94A5\u914D\u7F6E",btn_validate:"\u9A8C\u8BC1",check_bbt_fail:"\u672A\u68C0\u6D4B\u5230",check_bbt_ok:"\u5DF2\u5B89\u88C5",check_python_fail:"\u672A\u5B89\u88C5",check_python_ok:"\u5DF2\u5C31\u7EEA",check_zotero_fail:"\u672A\u68C0\u6D4B\u5230",check_zotero_ok:"\u5DF2\u5B89\u88C5",complete_next:"\u4E0B\u4E00\u6B65\u64CD\u4F5C",complete_step1:"\u6253\u5F00 PaperForge Dashboard",complete_step1_desc:"Ctrl+P \u2192 \u8F93\u5165 PaperForge: Open Dashboard\uFF0C\u6216\u70B9\u5DE6\u4FA7\u4E66\u672C\u56FE\u6807",complete_step2:"\u540C\u6B65\u6587\u732E",complete_step2_desc:"Dashboard \u4E2D\u70B9 Sync Library\uFF0C\u4ECE Zotero \u62C9\u53D6\u6587\u732E\u751F\u6210\u7B14\u8BB0",complete_step3:"\u8FD0\u884C OCR",complete_step3_desc:"Dashboard \u4E2D\u70B9 Run OCR\uFF0C\u63D0\u53D6 PDF \u5168\u6587\u4E0E\u56FE\u8868",complete_step4:"\u914D\u7F6E BBT \u81EA\u52A8\u5BFC\u51FA",complete_summary:"\u5F53\u524D\u5B8C\u6574\u914D\u7F6E",complete_title:"\u2713 PaperForge \u5B89\u88C5\u5B8C\u6210",copied:"\u5DF2\u590D\u5236\uFF01",copy_pf_deep_cmd:"\u590D\u5236 /pf-deep \u547D\u4EE4",dashboard_drift_warning:'\u63D2\u4EF6\u7248\u672C\u4E0E Python \u8FD0\u884C\u65F6\u7248\u672C\u4E0D\u5339\u914D\u3002\u8BF7\u5728\u8BBE\u7F6E\u4E2D\u70B9\u51FB"\u540C\u6B65\u8FD0\u884C\u65F6"\u3002',deep_reading_not_found:"\u7CBE\u8BFB\u6587\u4EF6\u672A\u627E\u5230",desc:"Obsidian + Zotero \u6587\u732E\u7BA1\u7406\u6D41\u6C34\u7EBF\u3002\u81EA\u52A8\u540C\u6B65\u6587\u732E\u3001\u751F\u6210\u7B14\u8BB0\u3001OCR \u63D0\u53D6\u5168\u6587\uFF0C\u4E00\u7AD9\u5F0F\u6587\u732E\u7CBE\u8BFB\u5DE5\u4F5C\u6D41\u3002",dir_base:"Base \u76EE\u5F55",dir_index:"\u7D22\u5F15\u76EE\u5F55",dir_notes:"\u6B63\u6587\u76EE\u5F55",dir_resources:"\u8D44\u6E90\u76EE\u5F55",dir_system:"\u7CFB\u7EDF\u76EE\u5F55",dir_vault:"Vault \u8DEF\u5F84",error_copied:"\u5DF2\u590D\u5236\uFF01",error_copy_diagnostic:"\u590D\u5236\u8BCA\u65AD\u4FE1\u606F",feat_agent_platform:"Agent \u5E73\u53F0",feat_agent_platform_desc:"\u9009\u62E9\u8981\u7BA1\u7406\u7684 Agent \u5E73\u53F0\u3002",feat_api_base_url:"API \u5730\u5740",feat_api_base_url_desc:"\u81EA\u5B9A\u4E49 OpenAI \u517C\u5BB9 API \u7AEF\u70B9\u3002\u7559\u7A7A\u4F7F\u7528\u9ED8\u8BA4\u5730\u5740\u3002",feat_api_model:"API \u6A21\u578B",feat_api_model_desc:"\u8BE5\u7AEF\u70B9\u4F7F\u7528\u7684\u5D4C\u5165\u6A21\u578B\u540D\u79F0\u3002",feat_build_btn:"\u6784\u5EFA",feat_build_complete:"\u5411\u91CF\u6784\u5EFA\u5B8C\u6210\u3002",feat_build_failed:"\u6784\u5EFA\u5931\u8D25\u3002\u8BF7\u67E5\u770B\u7EC8\u7AEF\u8F93\u51FA\u3002",feat_building:"\u6784\u5EFA\u4E2D\u2026",feat_cache_remove_failed:"\u5931\u8D25\uFF1A{0}",feat_cache_removed:"\u6A21\u578B\u7F13\u5B58\u5DF2\u6E05\u9664\u3002",feat_checking:"\u68C0\u6D4B\u4E2D\u2026",feat_checking_btn:"\u68C0\u6D4B\u4E2D\u2026",feat_deps_checking:"\u6B63\u5728\u68C0\u6D4B\u4F9D\u8D56\u2026",feat_deps_missing:"\u4F9D\u8D56\u672A\u5B89\u88C5\u3002\u9700\u8981\uFF1Achromadb, openai\u3002",feat_enter_key:"\u8BF7\u8F93\u5165\u6709\u6548\u7684 OpenAI API Key\u3002",feat_install_btn:"\u5B89\u88C5",feat_install_deps:"\u5B89\u88C5\u4F9D\u8D56",feat_install_done:"\u4F9D\u8D56\u5DF2\u5B89\u88C5\u3002\u6B63\u5728\u6784\u5EFA\u5411\u91CF\u2026",feat_install_failed:"\u5B89\u88C5\u5931\u8D25\uFF1A",feat_installing:"\u5B89\u88C5\u4E2D\u2026",feat_installing_pkgs:"\u6B63\u5728\u5B89\u88C5 {pkgs}...",feat_key_rejected:"API Key \u88AB\u62D2\u7EDD\u3002",feat_memory_desc:"\u8BB0\u5FC6\u5C42\u662F PaperForge \u7684\u6838\u5FC3\u6570\u636E\u5F15\u64CE\uFF0C\u57FA\u4E8E SQLite \u6784\u5EFA\u3002\u5B83\u6574\u5408\u4E86\u6587\u732E\u5143\u6570\u636E\uFF08\u8BBA\u6587\u3001\u8D44\u6E90\u6587\u4EF6\u3001\u522B\u540D\u3001\u9605\u8BFB\u4E8B\u4EF6\uFF09\uFF0C\u652F\u6301 FTS5 \u5143\u6570\u636E\u68C0\u7D22\uFF08\u6807\u9898\u3001\u6458\u8981\u3001\u4F5C\u8005\u3001domain\u3001collection\uFF09\uFF0C\u5E76\u4E3A agent-context \u548C paper-status \u547D\u4EE4\u63D0\u4F9B\u6570\u636E\u652F\u6491\u3002\u59CB\u7EC8\u8FD0\u884C\uFF0C\u65E0\u9700\u624B\u52A8\u5F00\u542F\u3002",feat_memory_rebuild_btn:"\u91CD\u5EFA\u6570\u636E\u5E93",feat_memory_rebuild_done:"\u8BB0\u5FC6\u6570\u636E\u5E93\u91CD\u5EFA\u5B8C\u6210\u3002",feat_memory_rebuild_failed:"\u91CD\u5EFA\u5931\u8D25\u3002",feat_memory_rebuilding:"\u91CD\u5EFA\u4E2D\u2026",feat_model:"\u6A21\u578B",feat_model_changed_warn:"\u6A21\u578B\u5DF2\u66F4\u6362\uFF08{0} -> {1}\uFF09\u3002\u5DF2\u6709\u5411\u91CF\u4E0D\u517C\u5BB9\u2014\u2014\u9700\u8981\u91CD\u5EFA\u3002",feat_network_error:"\u7F51\u7EDC\u9519\u8BEF\uFF1A",feat_no_python:"\u672A\u627E\u5230 Python\u3002\u8BF7\u67E5\u770B\u5B89\u88C5\u6807\u7B7E\u9875\u3002",feat_not_cached:"\u672A\u7F13\u5B58",feat_openai_key:"OpenAI API Key",feat_openai_key_desc:"\u7528\u4E8E API \u5D4C\u5165\u8C03\u7528\uFF0C\u6A21\u578B\u5728\u4E0B\u65B9\u5B9A\u4E49\u3002",feat_output_copied:"\u8F93\u51FA\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F\u3002",feat_rebuild_btn:"\u91CD\u5EFA",feat_rebuild_vectors:"\u91CD\u5EFA\u5411\u91CF",feat_rebuild_vectors_changed:"\u6A21\u578B\u5DF2\u66F4\u6362 \u2014 \u9700\u8981\u91CD\u5EFA\u5411\u91CF\u3002",feat_rebuild_vectors_desc:"\u91CD\u5EFA\u6240\u6709 OCR \u5168\u6587\u5411\u91CF\u3002\u66F4\u6362\u6A21\u578B\u6216\u6A21\u5F0F\u540E\u9700\u8981\u91CD\u5EFA\u3002",feat_removing:"\u5220\u9664\u4E2D\u2026",feat_retry_btn:"\u91CD\u8BD5",feat_skills_desc:"\u7BA1\u7406 Vault \u4E2D\u5DF2\u5B89\u88C5\u7684 Agent \u6280\u80FD\u3002\u6BCF\u884C\u5BF9\u5E94\u4E00\u4E2A SKILL.md \u6587\u4EF6\uFF0C\u5173\u95ED\u5F00\u5173\u53EF\u963B\u6B62 Agent \u81EA\u52A8\u8C03\u7528\u8BE5\u6280\u80FD\u3002",feat_skills_system:"\u7CFB\u7EDF\u6280\u80FD\u968F PaperForge \u4E00\u540C\u53D1\u5E03\uFF0C\u4F1A\u8DDF\u968F PaperForge \u7248\u672C\u66F4\u65B0\u3002",feat_skills_user:"\u7528\u6237\u6280\u80FD\u662F\u4F60\u81EA\u884C\u5B89\u88C5\u6216\u521B\u5EFA\u7684\u81EA\u5B9A\u4E49\u6280\u80FD\u3002",feat_uninstall_btn:"\u5378\u8F7D",feat_valid_key:"API Key \u6709\u6548\u3002",feat_vector_config_label:"\u5411\u91CF\u5E93\u914D\u7F6E",feat_vector_corrupted:"\u5411\u91CF\u7D22\u5F15\u5DF2\u635F\u574F \u2014 \u9700\u8981\u5F3A\u5236\u91CD\u5EFA\u3002",feat_vector_desc:"\u5411\u91CF\u6570\u636E\u5E93\u901A\u8FC7\u5D4C\u5165\u6A21\u578B\u5B9E\u73B0 OCR \u5168\u6587\u7684\u8BED\u4E49\u641C\u7D22\u3002\u6587\u6863\u88AB\u5207\u5206\u4E3A\u6587\u672C\u5757\uFF08chunk\uFF09\uFF0C\u7F16\u7801\u4E3A\u5411\u91CF\u5B58\u5165 ChromaDB\u3002\u652F\u6301\u672C\u5730\u6A21\u578B\uFF08\u514D\u8D39\uFF0CCPU \u8FD0\u884C\uFF09\u6216 OpenAI API\uFF08\u4ED8\u8D39\uFF0C\u66F4\u5FEB\u901F\uFF09\u3002",feat_vector_enable:"\u542F\u7528\u5411\u91CF\u68C0\u7D22",feat_vector_enable_desc:"\u5BF9 OCR \u5168\u6587\u8FDB\u884C\u8BED\u4E49\u641C\u7D22\u3002\u9700\u5B89\u88C5: pip install chromadb sentence-transformers openai (~500MB)\u3002",feat_vector_rebuild_force_btn:"\u5F3A\u5236\u91CD\u5EFA",feat_verify:"\u9A8C\u8BC1",feat_verify_btn:"\u9A8C\u8BC1",field_paddleocr:"PaddleOCR API \u5BC6\u94A5",field_python_custom:"\u81EA\u5B9A\u4E49 Python \u8DEF\u5F84",field_python_interp:"\u5F53\u524D Python \u89E3\u91CA\u5668",field_zotero_data:"Zotero \u6570\u636E\u76EE\u5F55",field_zotero_placeholder:"\u53EF\u9009\uFF0C\u7528\u4E8E\u81EA\u52A8\u68C0\u6D4B PDF",guide_ocr:"\u8FD0\u884C OCR",guide_ocr_desc:"Dashboard \u4E2D\u70B9 Run OCR\uFF0C\u63D0\u53D6 PDF \u5168\u6587\u4E0E\u56FE\u8868",guide_open:"\u6253\u5F00 Dashboard",guide_open_desc:"Ctrl+P \u2192 \u8F93\u5165 PaperForge: Open Dashboard\uFF0C\u6216\u70B9\u5DE6\u4FA7\u4E66\u672C\u56FE\u6807",guide_sync:"\u540C\u6B65\u6587\u732E",guide_sync_desc:"Dashboard \u4E2D\u70B9 Sync Library\uFF0C\u4ECE Zotero \u62C9\u53D6\u6587\u732E\u751F\u6210\u7B14\u8BB0",header_title:"PaperForge",install_bootstrapping:"\u672A\u68C0\u6D4B\u5230 PaperForge Python \u5305\uFF0C\u6B63\u5728\u81EA\u52A8\u5B89\u88C5\u2026",install_btn:"\u5F00\u59CB\u5B89\u88C5",install_btn_retry:"\u91CD\u8BD5",install_btn_running:"\u6B63\u5728\u5B89\u88C5...",install_complete:"\u2713 \u5B89\u88C5\u5B8C\u6210\uFF01",install_failed:"\u2717 \u5B89\u88C5\u5931\u8D25\uFF1A",install_validating:"\u6B63\u5728\u6821\u9A8C\u5B89\u88C5\u73AF\u5883\u2026",jump_to_deep_reading:"\u8DF3\u8F6C\u5230\u7CBE\u8BFB",label_agent:"Agent \u5E73\u53F0",nav_close:"\u5173\u95ED",nav_next:"\u4E0B\u4E00\u6B65 \u2192",nav_prev:"\u2190 \u4E0A\u4E00\u6B65",no_pending_ocr:"\u6240\u6709 OCR \u4EFB\u52A1\u5DF2\u5B8C\u6210",not_set:"\u672A\u8BBE\u7F6E",notice_check_fail:"\u672A\u901A\u8FC7: ",notice_python_missing:"Python \u672A\u68C0\u6D4B\u5230\uFF0C\u8BF7\u5148\u5B89\u88C5 Python 3.10+ \u5E76\u52A0\u5165 PATH",ocr_privacy_title:"OCR \u9690\u79C1\u63D0\u793A",ocr_privacy_warning:"OCR \u4F1A\u5C06 PDF \u4E0A\u4F20\u5230 PaddleOCR API \u8FDB\u884C\u5904\u7406\u3002\u8BF7\u4E0D\u8981\u4E0A\u4F20\u5305\u542B\u654F\u611F\u4FE1\u606F\u6216\u65E0\u6CD5\u5916\u4F20\u7684\u6587\u732E\u3002",ocr_queue_add:"\u52A0\u5165 OCR \u961F\u5217",ocr_queue_added:"\u5DF2\u52A0\u5165 OCR \u961F\u5217",ocr_queue_remove:"\u79FB\u51FA OCR \u961F\u5217",ocr_queue_removed:"\u5DF2\u79FB\u51FA OCR \u961F\u5217",ocr_understand:"\u6211\u4E86\u89E3\uFF0C\u7EE7\u7EED",optional_later:"\uFF08\u7A0D\u540E\u53EF\u5728\u8BBE\u7F6E\u4E2D\u8865\u5145\uFF09",orphan_delete_failed:"\u6E05\u7406\u5931\u8D25",orphan_delete_selected:"\u5220\u9664 {count} \u7BC7",orphan_deleted:"\u5DF2\u5220\u9664 {count} \u7BC7\u6B8B\u7559\u6587\u732E",orphan_desc:"\u8FD9\u4E9B\u6587\u732E\u5DF2\u4ECE Zotero \u4E2D\u79FB\u9664\u3002",orphan_deselect_all:"\u53D6\u6D88\u5168\u9009",orphan_explain:"\u5DF2\u4ECE Zotero \u4E2D\u79FB\u9664\u3002\u5DE5\u4F5C\u533A\u6587\u4EF6\u4ECD\u4FDD\u7559\u5728\u78C1\u76D8\u4E0A\u3002",orphan_keep_all:"\u4FDD\u7559\u5168\u90E8",orphan_none_selected:"\u672A\u9009\u62E9\u4EFB\u4F55\u6587\u732E",orphan_select_all:"\u5168\u9009",orphan_title:"\u53D1\u73B0 {count} \u7BC7\u6B8B\u7559\u6587\u732E",panel_actions:"\u5FEB\u6377\u64CD\u4F5C",prep_bbt:"Better BibTeX",prep_bbt_desc:"Zotero \u2192 \u5DE5\u5177 \u2192 \u63D2\u4EF6 \u2192 \u5B89\u88C5 Better BibTeX",prep_export:"BBT \u81EA\u52A8\u5BFC\u51FA",prep_export_desc:"\u53F3\u952E\u6587\u732E\u5B50\u5206\u7C7B \u2192 \u5BFC\u51FA\u5206\u7C7B \u2192 BetterBibTeX JSON \u2192 \u52FE\u9009\u4FDD\u6301\u66F4\u65B0 \u2192 \u5BFC\u51FA\u5230\uFF08JSON \u6587\u4EF6\u540D\u5373\u4E3A Base \u540D\uFF09\uFF1A",prep_key:"PaddleOCR Key",prep_key_desc:"\u5728 https://aistudio.baidu.com/paddleocr \u83B7\u53D6 API Key",prep_python:"Python 3.10+",prep_python_desc:"\u786E\u4FDD Python \u53EF\u547D\u4EE4\u884C\u8C03\u7528\u3002\u70B9\u51FB\u4E0B\u65B9\u6309\u94AE\u81EA\u52A8\u68C0\u6D4B\u3002",prep_zotero:"Zotero \u684C\u9762\u7248",prep_zotero_desc:"\u5B89\u88C5 Zotero (https://www.zotero.org)",run_in_agent:"\u5728 {0} \u4E2D\u8FD0\u884C",runtime_health:"\u8FD0\u884C\u65F6\u72B6\u6001",runtime_health_checking:"\u6B63\u5728\u68C0\u6D4B\u2026",runtime_health_desc:"\u68C0\u67E5\u63D2\u4EF6\u4E0E Python \u8FD0\u884C\u65F6\u7248\u672C\u7684\u5339\u914D\u60C5\u51B5\uFF0C\u5E76\u786E\u8BA4\u5DF2\u90E8\u7F72\u7684 skill contract \u662F\u5426\u4E3A\u5F53\u524D\u7248\u672C\u3002",runtime_health_match:"\u5339\u914D",runtime_health_mismatch:"\u4E0D\u5339\u914D",runtime_health_package_ver:"Python \u5305 v{0}",runtime_health_plugin_ver:"\u63D2\u4EF6 v{0}",runtime_health_sync:"\u540C\u6B65\u8FD0\u884C\u65F6",runtime_health_sync_done:"\u8FD0\u884C\u65F6\u5DF2\u540C\u6B65\u81F3 v{0}",runtime_health_sync_fail:"\u8FD0\u884C\u65F6\u540C\u6B65\u5931\u8D25\uFF1A{0}",runtime_health_syncing:"\u6B63\u5728\u540C\u6B65\u2026",section_config:"\u5F53\u524D\u914D\u7F6E",section_guide:"\u64CD\u4F5C\u65B9\u5F0F",section_prep:"\u5B89\u88C5\u51C6\u5907",section_prep_desc:"\u9996\u6B21\u4F7F\u7528\u524D\uFF0C\u8BF7\u4F9D\u6B21\u5B8C\u6210\u4EE5\u4E0B\u51C6\u5907\uFF1A",setup_done:"\u2713 PaperForge \u73AF\u5883\u5DF2\u914D\u7F6E\u5B8C\u6210",setup_pending:"\u5C1A\u672A\u5B89\u88C5\uFF0C\u5B8C\u6210\u5B89\u88C5\u51C6\u5907\u540E\u70B9\u51FB\u5B89\u88C5\u5411\u5BFC",tab_features:"\u529F\u80FD",tab_setup:"\u5B89\u88C5",tab_maintenance:"\u7EF4\u62A4",validate_base:"Base \u76EE\u5F55\u672A\u586B\u5199",validate_fail:"\u914D\u7F6E\u9A8C\u8BC1\u5931\u8D25",validate_index:"\u7D22\u5F15\u76EE\u5F55\u672A\u586B\u5199",validate_key:"PaddleOCR API \u5BC6\u94A5\u672A\u586B\u5199",validate_notes:"\u6B63\u6587\u76EE\u5F55\u672A\u586B\u5199",validate_resources:"\u8D44\u6E90\u76EE\u5F55\u672A\u586B\u5199",validate_system:"\u7CFB\u7EDF\u76EE\u5F55\u672A\u586B\u5199",validate_vault:"Vault \u8DEF\u5F84\u672A\u586B\u5199",validate_zotero:"Zotero \u6570\u636E\u76EE\u5F55\u4E3A\u5FC5\u586B\u9879",wizard_agent_hint:"\u9009\u62E9\u4F60\u4F7F\u7528\u7684 AI Agent \u5E73\u53F0\uFF0C\u5B89\u88C5\u65F6\u5C06\u6309\u5BF9\u5E94\u683C\u5F0F\u90E8\u7F72\u6280\u80FD\u6587\u4EF6\uFF1A",wizard_dir_hint:"\u8D44\u6E90\u76EE\u5F55\u662F\u6587\u732E\u6570\u636E\u7684\u7EDF\u4E00\u6839\u76EE\u5F55\uFF0C\u4EE5\u4E0B\u5B50\u76EE\u5F55\u5C06\u521B\u5EFA\u5728\u5176\u5185\u90E8\uFF1A",wizard_dir_sub_hint:"\u8D44\u6E90\u76EE\u5F55\u5185\u7684\u4E24\u4E2A\u5B50\u76EE\u5F55\uFF1A",wizard_intro:"\u672C\u5411\u5BFC\u5C06\u5F15\u5BFC\u60A8\u5B8C\u6210 PaperForge \u73AF\u5883\u7684\u5B8C\u6574\u914D\u7F6E\u3002\u5B89\u88C5\u8FC7\u7A0B\u4F1A\u81EA\u52A8\u521B\u5EFA\u6240\u6709\u76EE\u5F55\u7ED3\u6784\uFF0C\u65E0\u9700\u624B\u52A8\u64CD\u4F5C\u3002",wizard_keys_hint:"\u4EE5\u4E0B\u4E3A API \u5BC6\u94A5\u4E0E Zotero \u914D\u7F6E\uFF1A",wizard_preview:"\u7CFB\u7EDF\u6587\u4EF6\u548C Agent \u914D\u7F6E\u4F4D\u4E8E Vault \u6839\u76EE\u5F55\u4E0B\u3002\u6587\u732E\u6570\u636E\uFF08\u6B63\u6587\u3001\u7D22\u5F15\uFF09\u7EDF\u4E00\u5B58\u653E\u5728\u8D44\u6E90\u76EE\u5F55\u5185\u3002\u5B89\u88C5\u540E\u4ECD\u53EF\u5728\u8BBE\u7F6E\u4E2D\u4FEE\u6539\u3002",wizard_safety:"\u5B89\u5168\u8BF4\u660E\uFF1A\u5982\u679C\u4F60\u9009\u62E9\u7684\u76EE\u5F55\u91CC\u5DF2\u7ECF\u6709\u6587\u4EF6\uFF0C\u5B89\u88C5\u5411\u5BFC\u4F1A\u4FDD\u7559\u5DF2\u6709\u5185\u5BB9\uFF0C\u53EA\u8865\u5145\u7F3A\u5931\u7684 PaperForge \u6587\u4EF6\u548C\u76EE\u5F55\u3002",wizard_step1:"\u6982\u89C8",wizard_step2:"\u76EE\u5F55",wizard_step3:"Agent",wizard_step4:"\u5B89\u88C5",wizard_step5:"\u5B8C\u6210",wizard_skip_ocr_desc:"OCR \u529F\u80FD\u5728\u914D\u7F6E\u6709\u6548\u7684 PaddleOCR API \u5BC6\u94A5\u4E4B\u524D\u4E0D\u53EF\u7528\u3002\u60A8\u53EF\u4EE5\u7EE7\u7EED\u5B8C\u6210\u8BBE\u7F6E\uFF0C\u7A0D\u540E\u5728\u8BBE\u7F6E\u4E2D\u914D\u7F6E\u3002",wizard_skip_ocr_continue:"\u7EE7\u7EED\uFF0C\u7A0D\u540E\u914D\u7F6E\u5BC6\u94A5",wizard_skip_ocr_back:"\u8FD4\u56DE\u914D\u7F6E",wizard_api_hint_skip:"OCR \u5BC6\u94A5\u4E3A\u9009\u586B\u9879 \u2014 \u53EF\u8DF3\u8FC7\uFF0C\u7A0D\u540E\u5728\u8BBE\u7F6E\u4E2D\u914D\u7F6E\u3002",wizard_sys_hint:"\u72EC\u7ACB\u4E8E\u8D44\u6E90\u76EE\u5F55\u7684\u7CFB\u7EDF\u6587\u4EF6\uFF1A",wizard_title:"PaperForge \u5B89\u88C5\u5411\u5BFC",ocr_maint_no_action:"\u65E0\u9700\u5904\u7406",ocr_maint_rebuild:"\u5EFA\u8BAE\u91CD\u5EFA",ocr_maint_failed:"OCR \u5931\u8D25",ocr_maint_limited:"\u7ED3\u679C\u4E00\u822C",ocr_maint_needs_attention:"\u9700\u8981\u5904\u7406",ocr_maint_limitations:"\u7ED3\u679C\u8BF4\u660E",ocr_maint_hero_ok:"OCR \u6574\u4F53\u6B63\u5E38\u3002",ocr_maint_hero_warn:"OCR \u9700\u8981\u5173\u6CE8\uFF1A{rebuild} \u7BC7\u5EFA\u8BAE\u91CD\u5EFA\uFF0C{failed} \u7BC7\u5904\u7406\u5931\u8D25\u3002",ocr_maint_hero_note:"\u672C\u9875\u53EA\u63D0\u793A\u7EF4\u62A4\u540E\u5927\u6982\u7387\u4F1A\u6539\u5584\u7684\u95EE\u9898\u3002\u90E8\u5206\u8BBA\u6587\u6548\u679C\u4E00\u822C\uFF0C\u7EF4\u62A4\u672A\u5FC5\u80FD\u6539\u5584\u3002",ocr_maint_limitations_intro:"\u8FD9\u7C7B\u8BBA\u6587\u901A\u5E38\u8868\u793A\u7248\u5F0F\u590D\u6742\u6216\u4FE1\u53F7\u504F\u5F31\uFF0CPaperForge \u76EE\u524D\u6CA1\u6709\u9AD8\u7F6E\u4FE1\u5EA6\u7684\u7EF4\u62A4\u5EFA\u8BAE\u3002",ocr_maint_all_papers:"\u5168\u90E8\u8BBA\u6587",ocr_maint_rebuild_btn:"\u91CD\u5EFA\u7ED3\u679C",ocr_maint_redo_btn:"\u91CD\u65B0 OCR",ocr_maint_redo_confirm:"\u786E\u8BA4\u91CD\u65B0 OCR {n} \u7BC7\u8BBA\u6587\uFF1F\u73B0\u6709\u7684\u6D3E\u751F OCR \u7ED3\u679C\u5C06\u88AB\u66FF\u6362\u3002",maintenance_group_retry:"\u9700\u8981\u91CD\u8BD5",maintenance_group_rebuild:"\u53EF\u91CD\u5EFA\u7ED3\u679C",maintenance_group_legacy:"\u53EF\u5347\u7EA7\u65E7\u7ED3\u679C\uFF08\u53EF\u9009\uFF09",maintenance_btn_retry:"\u91CD\u8BD5",maintenance_btn_rebuild:"\u91CD\u5EFA",maintenance_btn_upgrade:"\u5347\u7EA7",maintenance_refresh_spinning:"\u6B63\u5728\u66F4\u65B0\u2026",maintenance_all_good:"\u2705 \u5168\u90E8\u6B63\u5E38",maintenance_n_pending:"{n} \u7BC7\u9700\u8981\u5904\u7406",maintenance_filter_all:"\u5168\u90E8",maintenance_filter_recommended:"\u5EFA\u8BAE\u5904\u7406",maintenance_batch_rebuild:"\u25B6 \u91CD\u5EFA\u5DF2\u9009",maintenance_batch_redo:"\u25B6 \u5168\u90E8\u91CD\u8DD1 OCR",maintenance_stop:"\u505C\u6B62",maintenance_batch_complete:"\u6279\u91CF\u64CD\u4F5C\u5B8C\u6210 \u2014 \u5904\u7406\u4E86 {n} \u7BC7\u8BBA\u6587\u3002",maintenance_progress_label:"{current}/{total} \u7BC7",version_panel_title:"\u7248\u672C\u5386\u53F2",version_panel_back:"\u8FD4\u56DE",version_filter_placeholder:"\u641C\u7D22\u8BBA\u6587...",version_papers_count:"{n} \u7BC7\u8BBA\u6587",version_current:"\u5F53\u524D",version_restore_btn:"\u6062\u590D",version_compare_btn:"\u5BF9\u6BD4",version_restore_selected:"\u6062\u590D\u9009\u4E2D\u7248\u672C",version_clear_old:"\u6E05\u9664\u65E7\u7248\u672C (\u91CA\u653E {size})",version_no_backups:"\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5386\u53F2\u7248\u672C",version_restore_confirm:"\u786E\u8BA4\u5C06 {paper} \u6062\u590D\u5230 {label}\uFF1F",version_restore_done:"\u5DF2\u6062\u590D\u5230 {label}",version_compare_title:"{vA} vs {vB}",version_compare_paragraphs:"{n} \u6BB5\u6709\u53D8\u5316",version_error_read:"\u65E0\u6CD5\u8BFB\u53D6\u7248\u672C\u6570\u636E",retrieval_search_placeholder:"\u641C\u7D22\u8BBA\u6587...\uFF08@ \u542F\u52A8\u6DF1\u5EA6\u641C\u7D22\uFF09",retrieval_search_placeholder_deep:"\u641C\u7D22\u8BBA\u6587\u5185\u5BB9...",retrieval_search_idle_hint:"\u8F93\u5165\u5173\u952E\u8BCD\u641C\u7D22\u8BBA\u6587\uFF0C\u6216\u4EE5 @ \u5F00\u5934\u641C\u7D22\u8BBA\u6587\u5185\u5BB9",retrieval_searching_metadata:"\u641C\u7D22\u5143\u6570\u636E\u4E2D...",retrieval_searching_deep:"\u6DF1\u5EA6\u641C\u7D22\u4E2D...",retrieval_search_cancel:"\u53D6\u6D88",retrieval_results_count:"{n} \u4E2A\u7ED3\u679C",retrieval_empty:"\u672A\u627E\u5230\u5339\u914D\u7684\u8BBA\u6587\u3002",retrieval_empty_tips:"\u5C1D\u8BD5\u66F4\u5BBD\u6CDB\u7684\u5173\u952E\u8BCD\uFF0C\u6216\u4F7F\u7528 @ \u6DF1\u5EA6\u641C\u7D22\u8BBA\u6587\u5185\u5BB9\u3002",retrieval_vectors_not_built:"\u5411\u91CF\u7D22\u5F15\u672A\u6784\u5EFA",retrieval_vectors_not_built_desc:"\u6784\u5EFA\u5411\u91CF\u7D22\u5F15\u4EE5\u542F\u7528 @ \u6DF1\u5EA6\u8BED\u4E49\u641C\u7D22\u3002",retrieval_open_vector_settings:"\u6253\u5F00\u5411\u91CF\u8BBE\u7F6E",retrieval_backend_unavailable:"\u641C\u7D22\u540E\u7AEF\u4E0D\u53EF\u7528",retrieval_backend_unavailable_desc:"Python CLI \u641C\u7D22\u540E\u7AEF\u672A\u6B63\u5E38\u54CD\u5E94\u3002",retrieval_run_doctor:"\u8FD0\u884C\u8BCA\u65AD",retrieval_retry:"\u91CD\u8BD5",retrieval_timeout_title:"\u641C\u7D22\u8D85\u65F6",retrieval_timeout_desc:"\u641C\u7D22\u8017\u65F6\u8FC7\u957F\uFF0C\u8BF7\u5C1D\u8BD5\u66F4\u7CBE\u786E\u7684\u67E5\u8BE2\u3002",retrieval_model_changed:"\u6A21\u578B\u5DF2\u66F4\u6362",retrieval_model_changed_desc:"\u5D4C\u5165\u6A21\u578B\u5DF2\u66F4\u6362\uFF0C\u9700\u91CD\u5EFA\u5411\u91CF\u540E\u624D\u80FD\u4F7F\u7528\u6DF1\u5EA6\u641C\u7D22\u3002",retrieval_rebuild_vectors:"\u91CD\u5EFA\u5411\u91CF",retrieval_build_idle:"\u5411\u91CF\u6570\u636E\u5E93\u5C31\u7EEA",retrieval_build_ready:"\u5DF2\u6784\u5EFA {n} \u4E2A\u5411\u91CF",retrieval_build_stopping:"\u6B63\u5728\u505C\u6B62...",cc_summary_attention:"\u90E8\u5206\u6A21\u5757\u9700\u8981\u5173\u6CE8",cc_summary_ok_body:"PaperForge \u73AF\u5883\u5DF2\u5B8C\u5168\u5C31\u7EEA\u3002\u5B89\u88C5\u548C\u5E2E\u52A9\u6587\u6863\u5747\u6B63\u5E38\u53EF\u7528\u3002",cc_summary_core_ok_body:"\u5B89\u88C5\u548C\u5E2E\u52A9\u6A21\u5757\u5DF2\u53EF\u7528\u3002\u6587\u732E\u7D22\u5F15\u3001OCR\u3001\u8BB0\u5FC6\u5C42\u548C\u7EF4\u62A4\u6A21\u5757\u5C06\u5728\u540E\u7AEF\u63A5\u5165\u540E\u663E\u793A\u5B9E\u65F6\u72B6\u6001\u3002",cc_summary_attention_body:"\u4E00\u4E2A\u6216\u591A\u4E2A\u6838\u5FC3\u6A21\u5757\u9700\u8981\u60A8\u7684\u5173\u6CE8\u624D\u80FD\u6B63\u5E38\u8FD0\u884C\u3002",retrieval_build_stopped:"\u6784\u5EFA\u5DF2\u505C\u6B62\uFF08{n}/{t} \u7BC7\uFF09",retrieval_build_failed:"\u6784\u5EFA\u5931\u8D25",retrieval_build_stale:"\u5411\u91CF\u5DF2\u8FC7\u671F \u2014 \u5EFA\u8BAE\u91CD\u5EFA",retrieval_build_deps_missing:"\u4F9D\u8D56\u7F3A\u5931\u3002\u8BF7\u5B89\u88C5 chromadb \u548C openai\u3002",retrieval_build_runtime_mismatch:"Python \u8FD0\u884C\u65F6\u7248\u672C\u4E0D\u5339\u914D\u3002",retrieval_stop:"\u505C\u6B62",retrieval_no_python:"\u672A\u627E\u5230 Python",retrieval_internal_error:"\u53D1\u751F\u5185\u90E8\u9519\u8BEF",retrieval_force_rebuild:"\u5F3A\u5236\u91CD\u5EFA",retrieval_rebuild_warning:"\u91CD\u5EFA\u5C06\u66FF\u6362 {n} \u4E2A\u73B0\u6709\u6587\u672C\u5757\uFF0C\u662F\u5426\u7EE7\u7EED\uFF1F",cc_summary_ok:"\u5168\u90E8\u6B63\u5E38",cc_summary_core_ok:"\u6838\u5FC3\u73AF\u5883\u6B63\u5E38\uFF1B{n} \u4E2A\u6A21\u5757\u72B6\u6001\u68C0\u6D4B\u5F85\u63A5\u5165",cc_badge_ok:"\u5DF2\u5C31\u7EEA",cc_badge_pending:"\u5F85\u63A5\u5165",cc_badge_setup:"\u9700\u8981\u5B89\u88C5",cc_badge_attention:"\u9700\u8981\u6CE8\u610F",cc_diagnostic_toggle:"\u8BE6\u60C5",cc_n_ready:"{n} \u5DF2\u5C31\u7EEA",cc_n_pending:"{n} \u5F85\u63A5\u5165",cc_title:"\u7CFB\u7EDF\u72B6\u6001",cc_desc:"PaperForge \u6838\u5FC3\u6A21\u5757\u7684\u5B9E\u65F6\u72B6\u6001\u3002\u6709\u5F85\u5904\u7406\u64CD\u4F5C\u7684\u6A21\u5757\u9700\u8981\u60A8\u7684\u5173\u6CE8\u3002",cc_zone_attention:"\u9700\u8981\u5173\u6CE8",cc_zone_modules:"\u6240\u6709\u6A21\u5757",cc_module_installation:"\u5B89\u88C5",cc_module_help:"\u5E2E\u52A9\u4E0E\u6587\u6863",cc_module_library:"\u6587\u732E\u7D22\u5F15",cc_module_ocr:"OCR \u5F15\u64CE",cc_module_memory:"\u8BB0\u5FC6\u5C42",cc_module_maintenance:"\u7EF4\u62A4",cc_state_ready:"\u5C31\u7EEA",cc_state_limited:"\u53D7\u9650",cc_state_unavailable:"\u4E0D\u53EF\u7528",cc_state_unknown:"\u672A\u77E5",cc_severity_ok:"\u6B63\u5E38",cc_severity_unknown:"\u672A\u77E5",cc_severity_warning:"\u8B66\u544A",cc_severity_error:"\u9519\u8BEF",cc_state_missing_input:"\u7F3A\u5C11\u8F93\u5165",cc_state_needs_action:"\u9700\u8981\u64CD\u4F5C",cc_action_setup:"\u6253\u5F00\u5B89\u88C5\u5411\u5BFC",cc_action_probe:"\u68C0\u6D4B",cc_action_set_config:"\u914D\u7F6E\u8BBE\u7F6E",cc_action_update:"\u66F4\u65B0",cc_reason_installation_ready:"PaperForge \u73AF\u5883\u5DF2\u6B63\u786E\u914D\u7F6E\u3002",cc_reason_config_missing:"\u914D\u7F6E\u6587\u4EF6\u7F3A\u5931\uFF0C\u8BF7\u8FD0\u884C\u5B89\u88C5\u5411\u5BFC\u3002",cc_reason_config_corrupt:"\u914D\u7F6E\u6587\u4EF6\u635F\u574F\uFF0C\u8BF7\u8FD0\u884C\u5B89\u88C5\u5411\u5BFC\u4FEE\u590D\u3002",cc_reason_python_version_unsupported:"Python \u7248\u672C\u4E0D\u53D7\u652F\u6301\uFF0C\u8BF7\u5B89\u88C5 Python 3.11+\u3002",cc_reason_help_ready:"\u5E2E\u52A9\u6587\u6863\u5DF2\u53EF\u7528\u3002",cc_reason_docs_missing:"\u5E2E\u52A9\u6587\u6863\u5C1A\u672A\u5B89\u88C5\u3002",cc_reason_placeholder:"\u72B6\u6001\u68C0\u6D4B\u5F85\u63A5\u5165\uFF0C\u63A5\u5165\u540E\u5C06\u663E\u793A\u5B9E\u65F6\u72B6\u6001\u3002",cc_diag_module:"\u6A21\u5757",cc_diag_state:"\u72B6\u6001",cc_diag_severity:"\u4E25\u91CD\u7A0B\u5EA6",cc_diag_activity:"\u6D3B\u52A8",cc_diag_reason:"\u539F\u56E0",cc_diag_ttl:"TTL",cc_diag_updated:"\u66F4\u65B0\u65F6\u95F4",cc_reason_no_probe:"{module} \u5C1A\u672A\u68C0\u6D4B\u3002",cc_reason_stale:"{module} \u7684\u68C0\u6D4B\u6570\u636E\u5DF2\u8FC7\u671F\u3002",cc_reason_invalid_response:"{module} \u7684\u68C0\u6D4B\u54CD\u5E94\u65E0\u6548\u3002",cc_reason_probing:"\u6B63\u5728\u68C0\u6D4B {module} \u72B6\u6001...",cc_notice_placeholder:"{module} \u6A21\u5757\u68C0\u6D4B\u529F\u80FD\u5C1A\u672A\u53EF\u7528\uFF0C\u5C06\u5728\u540E\u7EED\u7248\u672C\u4E2D\u6DFB\u52A0\u3002",cc_notice_refreshed:"\u6A21\u5757\u72B6\u6001\u5DF2\u5237\u65B0\u3002",cc_notice_refresh_failed:"\u6A21\u5757\u72B6\u6001\u5237\u65B0\u5931\u8D25\u3002",cc_activity_idle:"\u7A7A\u95F2",cc_activity_running:"\u8FD0\u884C\u4E2D"}},at=null;function ar(p){try{let d=p.vault;if(typeof d.getConfig=="function"){let e=d.getConfig("language");if(e&&String(e).startsWith("zh"))return"zh"}}catch(d){}try{if(typeof localStorage!="undefined"){let d=localStorage.getItem("language");if(d&&String(d).startsWith("zh"))return"zh"}}catch(d){}return"en"}function Pt(p){at=ar(p)==="zh"?st.zh:st.en}function o(p){return at&&at[p]||st.en[p]||p}var F=require("obsidian"),W=H(require("fs")),te=H(require("path")),zt=H(require("os")),G=require("child_process");var Vt=H(it());var _e=H(require("fs")),ue=H(require("path")),Rt=H(require("os")),me=require("child_process"),ot=null,Ct=!1;function z(p,d,e,t){let r=e||_e,n=t||me.execFileSync;if(d&&d.python_path&&d.python_path.trim()){let i=d.python_path.trim();if(r.existsSync(i))return{path:i,source:"manual",extraArgs:[]}}let a=[ue.join(p,".paperforge-test-venv","Scripts","python.exe"),ue.join(p,".venv","Scripts","python.exe"),ue.join(p,"venv","Scripts","python.exe")];for(let i of a)try{if(r.existsSync(i))return{path:i,source:"auto-detected",extraArgs:[]}}catch(c){}let s=[{path:"py",extraArgs:["-3"]},{path:"python",extraArgs:[]},{path:"python3",extraArgs:[]}];for(let i of s)try{let c=n(i.path,[...i.extraArgs,"--version"],{encoding:"utf-8",timeout:5e3,windowsHide:!0});if(c&&c.toLowerCase().includes("python"))return{path:i.path,source:"auto-detected",extraArgs:i.extraArgs}}catch(c){}return{path:"python",source:"auto-detected",extraArgs:[]}}function Ft(p,d,e,t,r){t===void 0&&(t=1e4);let n=r||me.execFile;return new Promise(a=>{n(p,["-c","import paperforge; print(paperforge.__version__)"],{cwd:e,timeout:t},(s,i)=>{if(s){a({status:"not-installed",pyVersion:null,pluginVersion:d,error:s.message});return}let c=i&&i.trim()||null;a(c===d?{status:"match",pyVersion:c,pluginVersion:d,error:null}:{status:"mismatch",pyVersion:c,pluginVersion:d,error:null})})})}function lt(p){let d=String(p),t={ENOENT:{type:"python_missing",message:"Python executable not found",recoverable:!0},"python-missing":{type:"python_missing",message:"Python executable not found",recoverable:!0},MODULE_NOT_FOUND:{type:"import_failed",message:"PaperForge package not installed",recoverable:!0},"import-failed":{type:"import_failed",message:"PaperForge package not installed",recoverable:!0},"version-mismatch":{type:"version_mismatch",message:"Plugin and package versions differ",recoverable:!0,action:"sync-runtime"},"pip-failed":{type:"pip_install_failure",message:"pip install command failed",recoverable:!0},ETIMEDOUT:{type:"timeout",message:"Subprocess timed out",recoverable:!0,action:"retry"},timeout:{type:"timeout",message:"Subprocess timed out",recoverable:!0,action:"retry"},NO_PYTHON:{type:"no_python",message:"Python executable not found",recoverable:!0,action:"open-setup"},VECTOR_NOT_BUILT:{type:"vectors_not_built",message:"Vector index has not been built yet",recoverable:!0,action:"open-vector-settings"},VECTOR_CORRUPTED:{type:"vectors_corrupted",message:"Vector index is corrupted",recoverable:!0,action:"force-rebuild"},MODEL_CHANGED:{type:"model_changed",message:"Embedding model has changed since vectors were built",recoverable:!0,action:"rebuild-vectors"},BACKEND_UNAVAILABLE:{type:"backend_unavailable",message:"Python CLI search backend is not responding",recoverable:!0,action:"run-doctor"},TIMEOUT:{type:"timeout",message:"Search timed out",recoverable:!0,action:"retry"},INTERNAL_ERROR:{type:"internal_error",message:"An internal error occurred",recoverable:!1}}[d];return t?{...t}:{type:"unknown",message:String(p),recoverable:!1}}function Tt(p,d,e){e===void 0&&(e=[]);let t=`paperforge==${d}`,r=`git+https://github.com/LLLin000/PaperForge.git@${d}`,n=[...e,"-m","pip","install","--upgrade",t],a=[...e,"-m","pip","install","--upgrade",r];return{cmd:p,url:r,args:a,pypiArgs:n,gitArgs:a,timeout:12e4}}function At(p,d,e,t,r,n){let a=r||me.spawn;return new Promise(s=>{let i=Date.now(),c={cwd:e,timeout:t,windowsHide:!0};n&&(c.env=n);let l=a(p,d,c),_=[],f=[];l.stdout.on("data",u=>{_.push(u.toString("utf-8"))}),l.stderr.on("data",u=>{f.push(u.toString("utf-8"))}),l.on("close",u=>{s({stdout:_.join(""),stderr:f.join(""),exitCode:u,elapsed:Date.now()-i})}),l.on("error",u=>{s({stdout:_.join(""),stderr:f.join("")+`
|
|
`+u.message,exitCode:-1,elapsed:Date.now()-i})})})}function ct(){if(Ct)return ot;Ct=!0;try{let p;if(process.platform==="win32"){let d=process.env.ComSpec||"C:\\Windows\\System32\\cmd.exe";p=(0,me.execFileSync)(d,["/c","where","git"],{timeout:5e3,windowsHide:!0,encoding:"utf-8"})}else p=(0,me.execFileSync)("which",["git"],{timeout:5e3,encoding:"utf-8"});if(p){let d=p.split(`
|
|
`)[0].trim();d&&(ot=ue.dirname(d))}}catch(p){}return ot}function we(){let p={...process.env},d=process.platform,e=Rt.homedir(),t=[],r=ct();r&&t.push(r),d==="darwin"?t.push("/opt/homebrew/bin","/usr/local/bin","/usr/bin",`${e}/.local/bin`):d==="linux"&&t.push("/usr/local/bin","/usr/bin",`${e}/.local/bin`);let n=p.PATH||"";return p.PATH=[...t,n].filter(Boolean).join(ue.delimiter),p}function Dt(p){return String(p).toLowerCase().replace(/[^a-z0-9]/g,"").includes("betterbibtex")}function pt(p){if(!p)return!1;try{if(!_e.existsSync(p))return!1;for(let d of _e.readdirSync(p))if(Dt(d))return!0}catch(d){}return!1}function Ke(p){if(!p)return!1;try{if(!_e.existsSync(p))return!1;for(let d of _e.readdirSync(p)){let e=ue.join(p,d,"extensions");try{if(!_e.existsSync(e))continue;for(let t of _e.readdirSync(e))if(Dt(t))return!0}catch(t){}}}catch(d){}return!1}var Ee=H(require("fs")),K=H(require("path")),dt=require("child_process"),fe=null;function or(p,d){let e=d||Ee,t=K.join(p,"paperforge.json"),r={system_dir:"System",resources_dir:"Resources",literature_dir:"Literature",base_dir:"Bases"};try{if(!e.existsSync(t))return{...r,_warning:"paperforge.json not found; using defaults"};let n=e.readFileSync(t,"utf-8"),a=JSON.parse(n),s=a.vault_config||{};return{system_dir:s.system_dir||a.system_dir||r.system_dir,resources_dir:s.resources_dir||a.resources_dir||r.resources_dir,literature_dir:s.literature_dir||a.literature_dir||r.literature_dir,base_dir:s.base_dir||a.base_dir||r.base_dir,_warning:null}}catch(n){return console.warn("PaperForge: Failed to read paperforge.json, using defaults",n),{...r,_warning:"paperforge.json invalid; using defaults"}}}function le(p,d){let e=or(p,d),t=K.join(p,e.system_dir,"PaperForge");return{vault:p,systemDir:t,indexesDir:K.join(t,"indexes"),logsDir:K.join(t,"logs"),dbPath:K.join(t,"indexes","paperforge.db"),memoryStatePath:K.join(t,"indexes","memory-runtime-state.json"),vectorStatePath:K.join(t,"indexes","vector-runtime-state.json"),healthStatePath:K.join(t,"indexes","runtime-health.json"),buildStatePath:K.join(t,"indexes","vector-build-state.json"),orphanStatePath:K.join(t,"indexes","sync-orphan-state.json"),exportsDir:K.join(t,"exports"),ocrDir:K.join(t,"ocr"),pluginDataPath:K.join(p,".obsidian","plugins","paperforge","data.json"),pfJsonPath:K.join(p,"paperforge.json"),configWarning:e._warning}}function ut(p){try{return Ee.existsSync(p)?JSON.parse(Ee.readFileSync(p,"utf-8")):null}catch(d){return null}}function lr(p){let d=le(p);return ut(d.memoryStatePath)}var Ce=null;function We(p){let d=le(p),e=Date.now();if(Ce&&Ce.vaultPath===p&&e-Ce.ts<2e3)return Ce.result;let t="",r=[K.join(p,".paperforge-test-venv","Scripts","python.exe"),K.join(p,".venv","Scripts","python.exe"),K.join(p,"venv","Scripts","python.exe")];for(let a=0;a<r.length;a++)if(Ee.existsSync(r[a])){t=r[a];break}if(t)try{let a=(0,dt.execFileSync)(t,["-m","paperforge","--vault",p,"embed","status","--json"],{encoding:"utf-8",timeout:1e4,windowsHide:!0}),s=JSON.parse(a);if(s.ok&&s.data){let i=s.data;return Ce={vaultPath:p,result:i,ts:e},i}}catch(a){}let n=ut(d.vectorStatePath);return Ce={vaultPath:p,result:n,ts:e},n}function Me(p){let d=le(p);return ut(d.healthStatePath)}function Bt(p){var e;let d=Me(p);return!!(d&&((e=d.summary)==null?void 0:e.status)==="ok")}function Ue(p){let d=lr(p);return!d||d.paper_count_db===0?"DB not found. Run paperforge memory build.":"Papers: "+d.paper_count_db+" | "+(d.fresh?"fresh":"stale")}function Re(p){var t,r,n;let d=We(p);return d?d.healthy===!1?"Vector index unreadable - rebuild required":"Chunks: "+(((t=d.chunk_count)!=null?t:0)+((r=d.body_chunk_count)!=null?r:0)+((n=d.object_chunk_count)!=null?n:0))+" | "+d.model+" | "+d.mode:"Status unavailable"}function he(p,d){if(fe)return fe;if(d&&d.python_path&&d.python_path.trim()){let r=d.python_path.trim();if(Ee.existsSync(r))return fe={path:r,source:"manual",extraArgs:[]},fe}let e=[K.join(p,".paperforge-test-venv","Scripts","python.exe"),K.join(p,".venv","Scripts","python.exe"),K.join(p,"venv","Scripts","python.exe")];for(let r=0;r<e.length;r++)if(Ee.existsSync(e[r]))return fe={path:e[r],source:"auto-detected",extraArgs:[]},fe;let t=[{path:"py",extraArgs:["-3"]},{path:"python",extraArgs:[]},{path:"python3",extraArgs:[]}];for(let r=0;r<t.length;r++)try{let n=t[r],a=(0,dt.execFileSync)(n.path,n.extraArgs.concat(["--version"]),{encoding:"utf-8",timeout:5e3,windowsHide:!0});if(a&&a.toLowerCase().indexOf("python")!==-1)return fe={path:n.path,source:"auto-detected",extraArgs:n.extraArgs},fe}catch(n){}return fe={path:"python",source:"auto-detected",extraArgs:[]},fe}function _t(p,d,e){return!p||typeof p!="object"||!Object.prototype.hasOwnProperty.call(p,d)?!!e:!!p[d]}function Ot(p,d,e){let t=!_t(p,d,e);return p&&typeof p=="object"&&(p[d]=t),t}var ae=require("obsidian"),pe=H(require("fs")),Mt=H(require("path")),It=H(require("https")),Ie=require("child_process");function Lt(p,d){return!d||!d.trim()?{blocked:!0,reason:"zotero"}:p?{blocked:!1}:{blocked:!0,reason:"ocr"}}var ft=class extends ae.Modal{constructor(e,t,r,n){super(e);this._rowEls=[];this.orphans=t.map((a,s)=>({...a,_selected:!0,_idx:s})),this.vaultPath=r,this.py=n}_updateUI(){let e=this.orphans.filter(t=>t._selected);this._countEl.setText(o("orphan_delete_selected").replace("{count}",String(e.length))),this._selectAllBtn.setText(e.length===this.orphans.length?o("orphan_deselect_all"):o("orphan_select_all"));for(let t of this.orphans){let r=this._rowEls[t._idx];r&&r.toggleClass("paperforge-orphan-dimmed",!t._selected)}}onOpen(){let{contentEl:e}=this;e.addClass("paperforge-modal"),e.createEl("h2",{text:o("orphan_title").replace("{count}",String(this.orphans.length))}),e.createEl("p",{cls:"paperforge-modal-desc",text:o("orphan_desc")}),this._rowEls=[];let t=e.createEl("div",{cls:"paperforge-orphan-list"});for(let n of this.orphans){let a=t.createEl("div",{cls:"paperforge-orphan-row"+(n._selected?"":" paperforge-orphan-dimmed")});this._rowEls.push(a);let s=a.createEl("div",{cls:"paperforge-orphan-info"}),i=s.createEl("div",{cls:"paperforge-orphan-header"});i.createEl("span",{cls:"paperforge-orphan-key",text:n.citation_key||n.key});let c=i.createEl("span",{cls:"paperforge-orphan-tags"});c.createEl("span",{cls:"paperforge-tag "+(n.has_pdf?"tag-pdf":"tag-nopdf"),text:n.has_pdf?"PDF":"no PDF"}),n.collection_path&&c.createEl("span",{cls:"paperforge-tag tag-collection",text:n.collection_path}),n.title&&s.createEl("div",{cls:"paperforge-orphan-title",text:n.title});let l=[];n.authors&&l.push(n.authors),n.year&&l.push(n.year),l.length>0&&s.createEl("div",{cls:"paperforge-orphan-meta",text:l.join(" \xB7 ")}),s.createEl("div",{cls:"paperforge-orphan-explain",text:o("orphan_explain")}),a.addEventListener("click",()=>{n._selected=!n._selected,this._updateUI()})}let r=e.createEl("div",{cls:"paperforge-modal-actions"});this._selectAllBtn=r.createEl("button",{cls:"paperforge-step-btn",text:"Deselect all"}),this._selectAllBtn.addEventListener("click",()=>{let n=this.orphans.every(a=>a._selected);for(let a of this.orphans)a._selected=!n;this._updateUI()}),this._countEl=r.createEl("button",{cls:"paperforge-step-btn mod-cta",text:"Delete "+this.orphans.length+" selected"}),r.createEl("button",{cls:"paperforge-step-btn",text:"Keep all"}).addEventListener("click",()=>this.close()),this._countEl.addEventListener("click",()=>{let n=this.orphans.filter(s=>s._selected);if(n.length===0){new ae.Notice(o("orphan_none_selected"));return}if(this._countEl.setText("Deleting..."),this._countEl.setAttr("disabled",""),this._selectAllBtn.setAttr("disabled",""),!this.py||!this.py.path){new ae.Notice("PaperForge: Python not found"),this.close();return}let a=n.map(s=>s.key);(0,Ie.execFile)(this.py.path,[...this.py.extraArgs,"-m","paperforge","--vault",this.vaultPath,"prune","--force","--json",...a],{cwd:this.vaultPath,timeout:6e4},(s,i)=>{if(s){new ae.Notice("PaperForge: prune failed"),this.close();return}try{let c=JSON.parse(i),l=c.data&&c.data.deleted||[];new ae.Notice("Deleted "+l.length+" orphan workspace(s)")}catch(c){new ae.Notice("PaperForge: prune done")}this.close()})})}onClose(){this.contentEl.empty()}};function Ze(p,d,e){console.log("[PF] checkOrphanState called");try{let r=le(e).orphanStatePath;if(!pe.existsSync(r)){console.log("[PF] orphan file NOT FOUND");return}console.log("[PF] orphan file FOUND");let n=pe.readFileSync(r,"utf-8"),s=JSON.parse(n).orphans||[];if(console.log("[PF] orphans count:",s.length),s.length===0)return;let i=he(e,d.settings);console.log("[PF] py.path:",i?i.path:"null"),new ft(p,s,e,i).open(),pe.unlinkSync(r),console.log("[PF] orphan file cleaned")}catch(t){console.log("[PF] checkOrphanState exception:",t.message||t)}}var qe=class extends ae.Modal{constructor(e,t,r){super(e);this._pendingSave=null;this._showSkipConfirm=!1;this.plugin=t,this._step=1,this._onComplete=r}onOpen(){this._render()}onClose(){this.contentEl.empty()}_render(){let{contentEl:e}=this;e.empty(),e.addClass("paperforge-modal"),this._renderStepIndicator(),this._renderStepContent(),this._renderNavigation()}_renderStepIndicator(){let e=[o("wizard_step1"),o("wizard_step2"),o("wizard_step3"),o("wizard_step4"),o("wizard_step5")],t=this.contentEl.createEl("div",{cls:"paperforge-step-bar"});e.forEach((r,n)=>{let a=n+1,s=t.createEl("div",{cls:`paperforge-step-dot ${a===this._step?"active":""} ${a<this._step?"done":""}`});s.createEl("span",{cls:"paperforge-step-num",text:`${a}`}),s.createEl("span",{cls:"paperforge-step-label",text:r})})}_renderStepContent(){let e=this.contentEl.createEl("div",{cls:"paperforge-step-content"});switch(this._step){case 1:this._stepOverview(e);break;case 2:this._stepDirectories(e);break;case 3:this._stepKeys(e);break;case 4:this._stepInstall(e);break;case 5:this._stepComplete(e);break}}_renderNavigation(){let e=this.contentEl.createEl("div",{cls:"paperforge-step-nav"});this._step>1&&e.createEl("button",{cls:"paperforge-step-btn",text:o("nav_prev")}).addEventListener("click",()=>{this._step--,this._showSkipConfirm=!1,this._render()}),this._step<5?e.createEl("button",{cls:"paperforge-step-btn mod-cta",text:o("nav_next")}).addEventListener("click",()=>{if(this._step===3){let r=this._validateStep3();if(r.blocked){if(r.reason==="zotero")return;if(r.reason==="ocr"){this._showSkipConfirm=!0,this._render();return}}}this._step++,this._showSkipConfirm=!1,this._render()}):e.createEl("button",{cls:"paperforge-step-btn",text:o("nav_close")}).addEventListener("click",()=>this.close())}_validateStep3(){let e=this.plugin.settings,t=Lt(this._apiKeyValidated,e.zotero_data_dir);if(t.reason==="ocr")return t;let r=(e.zotero_data_dir||"").trim();if(!r)return new ae.Notice("Zotero \u6570\u636E\u76EE\u5F55\u4E3A\u5FC5\u586B\u9879\uFF0C\u8BF7\u586B\u5199\u8DEF\u5F84"),{blocked:!0,reason:"zotero"};if(!pe.existsSync(r))return new ae.Notice("Zotero \u6570\u636E\u76EE\u5F55\u8DEF\u5F84\u4E0D\u5B58\u5728"),{blocked:!0,reason:"zotero"};if(!pe.statSync(r).isDirectory())return new ae.Notice("Zotero \u6570\u636E\u76EE\u5F55\u8DEF\u5F84\u4E0D\u662F\u4E00\u4E2A\u76EE\u5F55"),{blocked:!0,reason:"zotero"};let n=Mt.join(r,"storage");return!pe.existsSync(n)||!pe.statSync(n).isDirectory()?(new ae.Notice("Zotero \u6570\u636E\u76EE\u5F55\u4E2D\u672A\u627E\u5230 storage/ \u5B50\u76EE\u5F55"),{blocked:!0,reason:"zotero"}):{blocked:!1}}_stepOverview(e){e.createEl("h2",{text:o("wizard_title")}),e.createEl("p",{text:o("wizard_intro")});let t=this.plugin.settings,r=this.app.vault.adapter.basePath,n=e.createEl("div",{cls:"paperforge-dir-tree"}),a=n.createEl("div",{cls:"paperforge-dir-node root"});a.textContent=`\u{1F4C1} Vault (${r})`;let s=n.createEl("div",{cls:"paperforge-dir-children"}),i=s.createEl("div",{cls:"paperforge-dir-node folder"});i.textContent=`\u{1F4C1} ${t.resources_dir||"Resources"}/ \u2014 \u6587\u732E\u5361\u7247\u76EE\u5F55\uFF08Base \u6570\u636E\u6765\u6E90\uFF09`,i.createEl("div",{cls:"paperforge-dir-children"}).createEl("div",{cls:"paperforge-dir-node file",text:`\u{1F4C1} ${t.literature_dir||"Literature"}/ \u2014 \u6587\u732E\u5361\u7247`}),s.createEl("div",{cls:"paperforge-dir-node folder",text:`\u{1F4C1} ${t.base_dir||"Bases"}/ \u2014 \u6570\u636E\u7BA1\u7406\u9762\u677F`}),s.createEl("div",{cls:"paperforge-dir-node folder",text:`\u{1F4C1} ${t.system_dir||"System"}/ \u2014 Zotero \u8F6F\u94FE\u63A5 + PaperForge \u7CFB\u7EDF\u6587\u4EF6\u5939`}),e.createEl("p",{text:o("wizard_preview"),cls:"paperforge-modal-hint"}),e.createEl("p",{text:o("wizard_safety"),cls:"paperforge-modal-hint"});let l=e.createEl("div",{cls:"paperforge-summary"}),_=[{label:o("dir_resources"),val:`${r}/${t.resources_dir||"Resources"}`},{label:o("dir_notes"),val:`${r}/${t.resources_dir||"Resources"}/${t.literature_dir||"Literature"}`},{label:o("dir_base"),val:`${r}/${t.base_dir||"Bases"}`},{label:o("dir_system"),val:`${r}/${t.system_dir||"System"}`}];for(let f of _){let u=l.createEl("div",{cls:"paperforge-summary-row"});u.createEl("span",{cls:"paperforge-summary-label",text:f.label}),u.createEl("span",{cls:"paperforge-summary-value",text:f.val})}}_stepDirectories(e){e.createEl("h2",{text:o("wizard_step2")}),e.createEl("p",{text:o("wizard_intro")});let t=this.plugin.settings,r=this.app.vault.adapter.basePath;this._modalField(e,o("dir_vault"),r,!0),e.createEl("p",{text:o("wizard_dir_hint"),cls:"paperforge-modal-hint"}),this._modalInput(e,"\u8D44\u6E90\u76EE\u5F55\uFF08\u521B\u5EFA\u6587\u732E\u5361\u7247\u76EE\u5F55\u7684\u5730\u65B9\uFF09","resources_dir",t.resources_dir,"Resources"),e.createEl("p",{text:o("wizard_dir_sub_hint"),cls:"paperforge-modal-hint"}),this._modalInput(e,"\u6587\u732E\u5361\u7247\u76EE\u5F55\uFF08\u5B58\u653E\u6587\u732E\u5361\u7247\u7684\u5730\u65B9\uFF0CBase \u6570\u636E\u6765\u6E90\uFF09","literature_dir",t.literature_dir,"Literature"),e.createEl("p",{text:o("wizard_sys_hint"),cls:"paperforge-modal-hint"}),this._modalInput(e,"\u7CFB\u7EDF\u76EE\u5F55\uFF08\u5B58\u653E Zotero \u8F6F\u94FE\u63A5\u548C PaperForge \u7CFB\u7EDF\u6587\u4EF6\uFF09","system_dir",t.system_dir,"System"),this._modalInput(e,"Base \u76EE\u5F55\uFF08\u5B58\u653E\u6570\u636E\u7BA1\u7406\u9762\u677F\u7684\u5730\u65B9\uFF09","base_dir",t.base_dir,"Bases"),e.createEl("p",{text:o("wizard_safety"),cls:"paperforge-modal-hint"});let n=e.createEl("div",{cls:"paperforge-summary"}),a=[{label:o("dir_resources"),val:`${r}/${t.resources_dir||""}`},{label:o("dir_notes"),val:`${r}/${t.resources_dir||""}/${t.literature_dir||""}`},{label:o("dir_system"),val:`${r}/${t.system_dir||""}`},{label:o("dir_base"),val:`${r}/${t.base_dir||""}`}];for(let s of a){let i=n.createEl("div",{cls:"paperforge-summary-row"});i.createEl("span",{cls:"paperforge-summary-label",text:s.label}),i.createEl("span",{cls:"paperforge-summary-value",text:s.val})}}_stepKeys(e){if(e.createEl("h2",{text:o("wizard_step3")}),this._showSkipConfirm){this._renderSkipConfirm(e);return}let t=this.plugin.settings;e.createEl("p",{text:o("wizard_agent_hint"),cls:"paperforge-modal-hint"});let r=[{key:"opencode",name:"OpenCode"},{key:"claude",name:"Claude Code"},{key:"cursor",name:"Cursor"},{key:"github_copilot",name:"GitHub Copilot"},{key:"windsurf",name:"Windsurf"},{key:"codex",name:"Codex"},{key:"gemini",name:"Gemini CLI"},{key:"cline",name:"Cline"}],n=e.createEl("div",{cls:"paperforge-modal-field"});n.createEl("label",{cls:"paperforge-modal-label",text:o("label_agent")});let a=n.createEl("select",{cls:"paperforge-modal-select"});for(let f of r){let u=a.createEl("option",{text:f.name,attr:{value:f.key}});f.key===(t.agent_platform||"opencode")&&(u.selected=!0)}a.addEventListener("change",()=>{t.agent_platform=a.value,this._pendingSave&&clearTimeout(this._pendingSave),this._pendingSave=setTimeout(()=>{this.plugin.saveSettings(),this._pendingSave=null},500)}),e.createEl("p",{text:o("wizard_keys_hint"),cls:"paperforge-modal-hint"});let s=e.createEl("div",{cls:"paperforge-modal-field"});s.createEl("label",{cls:"paperforge-modal-label",text:o("field_paddleocr")});let i=s.createEl("input",{cls:"paperforge-modal-input",attr:{type:"password",placeholder:"API Key"}});i.value=t.paddleocr_api_key||"",this._apiKeyValidated=!1,this._apiKeyStatus=s.createEl("span",{cls:"paperforge-apikey-status",text:""});let c=s.createEl("button",{cls:"paperforge-step-btn",text:"\u9A8C\u8BC1"});c.addEventListener("click",()=>this._validateApiKey(i.value,c)),i.addEventListener("input",()=>{t.paddleocr_api_key=i.value,this._apiKeyValidated=!1,this._apiKeyStatus.textContent="",this._apiKeyStatus.className="paperforge-apikey-status"}),this._pendingSave&&clearTimeout(this._pendingSave),this._pendingSave=setTimeout(()=>{this.plugin.saveSettings(),this._pendingSave=null},500),e.createEl("p",{text:o("wizard_api_hint_skip"),cls:"paperforge-modal-hint"});let l=e.createEl("div",{cls:"paperforge-modal-field"});l.createEl("label",{cls:"paperforge-modal-label",text:o("field_zotero_data")});let _=l.createEl("input",{cls:"paperforge-modal-input",attr:{type:"text",placeholder:o("field_zotero_placeholder")}});_.value=t.zotero_data_dir||"",_.addEventListener("input",()=>{t.zotero_data_dir=_.value,this._pendingSave&&clearTimeout(this._pendingSave),this._pendingSave=setTimeout(()=>{this.plugin.saveSettings(),this._pendingSave=null},500)})}_validateApiKey(e,t){if(!e||e.length<10){this._apiKeyStatus.textContent="\u5BC6\u94A5\u683C\u5F0F\u4E0D\u6B63\u786E\u3002\u53EF\u70B9\u4E0B\u4E00\u6B65\u8DF3\u8FC7\uFF0C\u7B49\u4F1A\u513F\u518D\u914D\u7F6E\u3002",this._apiKeyStatus.className="paperforge-apikey-status error";return}t.disabled=!0,t.textContent="\u9A8C\u8BC1\u4E2D\u2026",this._apiKeyStatus.textContent="\u6B63\u5728\u9A8C\u8BC1\u2026",this._apiKeyStatus.className="paperforge-apikey-status";let r=JSON.stringify({model:"PaddleOCR-VL-1.5"}),n={hostname:"paddleocr.aistudio-app.com",path:"/api/v2/ocr/jobs",method:"POST",headers:{Authorization:"bearer "+e,"Content-Type":"application/json","Content-Length":Buffer.byteLength(r)},timeout:1e4},a=It.request(n,s=>{t.disabled=!1,t.textContent="\u9A8C\u8BC1";let i="";s.on("data",c=>i+=c),s.on("end",()=>{try{let c=JSON.parse(i);s.statusCode===400&&c.code===10001?(this._apiKeyStatus.textContent="\u2713 \u5BC6\u94A5\u6709\u6548",this._apiKeyStatus.className="paperforge-apikey-status ok",this._apiKeyValidated=!0):s.statusCode===401?(this._apiKeyStatus.textContent="\u9A8C\u8BC1\u5931\u8D25\uFF1A\u5BC6\u94A5\u65E0\u6548\u3002\u53EF\u70B9\u4E0B\u4E00\u6B65\u8DF3\u8FC7\uFF0C\u7B49\u4F1A\u513F\u518D\u914D\u7F6E\u3002",this._apiKeyStatus.className="paperforge-apikey-status error",this._apiKeyValidated=!1):(this._apiKeyStatus.textContent="\u9A8C\u8BC1\u5931\u8D25\uFF1AAPI \u8FD4\u56DE "+s.statusCode+"\u3002\u53EF\u70B9\u4E0B\u4E00\u6B65\u8DF3\u8FC7\uFF0C\u7B49\u4F1A\u513F\u518D\u914D\u7F6E\u3002",this._apiKeyStatus.className="paperforge-apikey-status error",this._apiKeyValidated=!1)}catch(c){this._apiKeyStatus.textContent="\u9A8C\u8BC1\u5931\u8D25\uFF1A\u65E0\u6CD5\u89E3\u6790\u54CD\u5E94\u3002\u53EF\u70B9\u4E0B\u4E00\u6B65\u8DF3\u8FC7\uFF0C\u7B49\u4F1A\u513F\u518D\u914D\u7F6E\u3002",this._apiKeyStatus.className="paperforge-apikey-status error",this._apiKeyValidated=!1}})});a.on("error",s=>{t.disabled=!1,t.textContent="\u9A8C\u8BC1",this._apiKeyStatus.textContent="\u9A8C\u8BC1\u5931\u8D25\uFF1A\u65E0\u6CD5\u8FDE\u63A5 ("+s.message+")\u3002\u53EF\u70B9\u4E0B\u4E00\u6B65\u8DF3\u8FC7\uFF0C\u7B49\u4F1A\u513F\u518D\u914D\u7F6E\u3002",this._apiKeyStatus.className="paperforge-apikey-status error",this._apiKeyValidated=!1}),a.write(r),a.end()}_renderSkipConfirm(e){e.createEl("p",{text:o("wizard_skip_ocr_desc"),cls:"paperforge-modal-desc"});let t=e.createEl("div",{cls:"paperforge-modal-actions"});t.createEl("button",{cls:"paperforge-step-btn mod-cta",text:o("wizard_skip_ocr_continue")}).addEventListener("click",()=>{this._showSkipConfirm=!1,this._step++,this._render()}),t.createEl("button",{cls:"paperforge-step-btn",text:o("wizard_skip_ocr_back")}).addEventListener("click",()=>{this._showSkipConfirm=!1,this._render()})}_modalField(e,t,r,n){let a=e.createEl("div",{cls:"paperforge-modal-field"});a.createEl("label",{cls:"paperforge-modal-label",text:t});let s=a.createEl("input",{cls:"paperforge-modal-input",attr:{type:"text"}});s.value=r,s.disabled=!!n}_modalInput(e,t,r,n,a){let s=e.createEl("div",{cls:"paperforge-modal-field"});s.createEl("label",{cls:"paperforge-modal-label",text:t});let i=s.createEl("input",{cls:"paperforge-modal-input",attr:{type:"text",placeholder:a||""}});i.value=n;let c=this.plugin.settings;i.addEventListener("input",()=>{c[r]=i.value,this._pendingSave&&clearTimeout(this._pendingSave),this._pendingSave=setTimeout(()=>{this.plugin.saveSettings(),this._pendingSave=null},500)})}_modalSecret(e,t,r,n,a){let s=e.createEl("div",{cls:"paperforge-modal-field"});s.createEl("label",{cls:"paperforge-modal-label",text:t});let i=s.createEl("input",{cls:"paperforge-modal-input",attr:{type:"password",placeholder:a||""}});i.value=n;let c=this.plugin.settings;i.addEventListener("input",()=>{c[r]=i.value,this._pendingSave&&clearTimeout(this._pendingSave),this._pendingSave=setTimeout(()=>{this.plugin.saveSettings(),this._pendingSave=null},500)})}_stepInstall(e){e.createEl("h2",{text:o("wizard_step4")}),this._installLog=e.createEl("div",{cls:"paperforge-install-log"});let t=e.createEl("button",{cls:"paperforge-step-btn mod-cta",text:o("install_btn")});t.addEventListener("click",()=>this._runInstall(t))}async _runInstall(e){var s,i,c,l,_,f;e.disabled=!0,e.textContent=o("install_btn_running"),this._installLog.setText(o("install_validating")+`
|
|
`),this._log(o("install_validating"));let t=this.plugin.settings,r=this._validate();if(r.length>0){this._log(o("validate_fail")+":"),r.forEach(u=>this._log(" \u2717 "+u)),e.disabled=!1,e.textContent=o("install_btn_retry");return}let n=(u,g={})=>new Promise((m,b)=>{let{path:h,extraArgs:v=[]}=z(t.vault_path.trim(),this.plugin.settings,void 0,void 0),x=(0,Ie.spawn)(h,[...v,...u],{cwd:t.vault_path.trim(),env:we(),timeout:12e4,...g}),k="",y="";x.stdout.on("data",E=>{let w=E.toString("utf-8");k+=w,g.logStdout&&this._processSetupOutput(w)}),x.stderr.on("data",E=>{let w=E.toString("utf-8");y+=w,this._log("[stderr] "+w.trim())}),x.on("close",E=>{E===0?m({stdout:k,stderr:y}):b(new Error(y.trim()||k.trim()||`exit code ${E}`))}),x.on("error",E=>b(E))}),a=["-m","paperforge","--vault",t.vault_path.trim(),"setup","--headless","--system-dir",t.system_dir.trim(),"--resources-dir",t.resources_dir.trim(),"--literature-dir",t.literature_dir.trim(),"--base-dir",t.base_dir.trim(),"--agent",t.agent_platform||"opencode"];t.zotero_data_dir&&t.zotero_data_dir.trim()&&a.push("--zotero-data",t.zotero_data_dir.trim()),t.paddleocr_api_key&&t.paddleocr_api_key.trim()&&a.push("--paddleocr-key",t.paddleocr_api_key.trim());try{let u=!0;try{await n(["-c","import paperforge"])}catch(g){u=!1}if(!u){this._log(o("install_bootstrapping"));let g=this.plugin.manifest.version;this._log(`[install] Trying PyPI: pip install paperforge==${g}`);let m=["-m","pip","install","--upgrade"];process.platform!=="win32"&&m.push("--user"),m.push(`paperforge==${g}`);try{await n(m,{logStdout:!0})}catch(b){this._log(`[install] PyPI failed, falling back to git: git+https://...@v${g}`),console.warn("[PaperForge] PyPI install failed, falling back to git:",(s=b.message)==null?void 0:s.slice(0,200));let h=["-m","pip","install","--upgrade"];process.platform!=="win32"&&h.push("--user"),h.push(`git+https://github.com/LLLin000/PaperForge.git@v${g}`),await n(h,{logStdout:!0})}}await n(a,{logStdout:!0,env:we()}),this._log(o("install_complete")),t.setup_complete=!0,await this.plugin.saveSettings(),this._onComplete&&this._onComplete(),setTimeout(()=>{this._step=5,this._render()},800)}catch(u){console.error("PaperForge setup failed:",u.message);let g=this._formatSetupError(u.message);this._log(o("install_failed")+g);let m=(i=this._installLog.parentElement)==null?void 0:i.createEl("button",{cls:"paperforge-copy-diag-btn",text:o("error_copy_diagnostic")||"Copy diagnostic"});if(m){let b=u.message,h=((l=(c=this.plugin)==null?void 0:c.settings)==null?void 0:l.python_path)||"auto",v=((f=(_=this.plugin)==null?void 0:_.manifest)==null?void 0:f.version)||"?",x=process.platform+" "+process.arch,k,y;try{k=ct()||"(not found)"}catch(T){k="(error)"}try{y=z(t.vault_path.trim(),this.plugin.settings,void 0,void 0)}catch(T){y=null}let E=(process.env.PATH||"").length,w=(process.env.PATH||"").toLowerCase().includes("git"),D=["[PaperForge Diagnostic]","Category: "+g,"Plugin version: "+v,"Python: "+h,"Resolved Python: "+((y==null?void 0:y.path)||"?"),"OS: "+x,"Vault path: "+(t.vault_path||"?"),"--- Git ---","Git dir (resolved): "+k,"PATH length: "+E+" chars","PATH contains git: "+w,"--- Raw error ---",b.slice(0,2e3)].join(`
|
|
`);m.addEventListener("click",()=>{navigator.clipboard.writeText(D).then(()=>{m.setText(o("error_copied")||"Copied!"),setTimeout(()=>{m.setText(o("error_copy_diagnostic")||"Copy diagnostic")},3e3)}).catch(()=>{new ae.Notice("[!!] Clipboard write failed",6e3)})})}e.disabled=!1,e.textContent=o("install_btn_retry")}}_log(e){this._installLog&&this._installLog.setText(this._installLog.textContent+e+`
|
|
`)}_validate(){let e=[],t=this.plugin.settings;return(!t.vault_path||!t.vault_path.trim())&&e.push(o("validate_vault")),(!t.resources_dir||!t.resources_dir.trim())&&e.push(o("validate_resources")),(!t.literature_dir||!t.literature_dir.trim())&&e.push(o("validate_notes")),(!t.base_dir||!t.base_dir.trim())&&e.push(o("validate_base")),(!t.paddleocr_api_key||!t.paddleocr_api_key.trim())&&this._log(" ! "+o("validate_key")+" "+o("optional_later")),(!t.zotero_data_dir||!t.zotero_data_dir.trim())&&this._log(" ! "+o("validate_zotero")+" "+o("optional_later")),e}_processSetupOutput(e){let t=e.split(`
|
|
`).filter(Boolean);for(let r of t)if(r.includes("[*]")||r.includes("[OK]")||r.includes("[FAIL]")){let n=r.replace(/^\[\*\].*\d+:?\s*/,"").replace(/^\[OK\]\s*/,"").replace(/^\[FAIL\]\s*/,"");this._log(" "+n)}}_formatSetupError(e){if(process.platform==="darwin"&&/No module named ['"]?paperforge/i.test(e))return"PaperForge not installed \u2014 install Python from Homebrew or python.org (Apple CLT /Library/Developer/CommandLineTools python often fails); then: python3 -m pip install --user git+https://github.com/LLLin000/PaperForge.git";let t=[{match:/pip.*not found|No module named.*pip|command not found.*pip/i,msg:"pip not found"},{match:/command not found|No such file|not recognized/i,msg:"Python not found"},{match:/resolve host|getaddrinfo.*nodename|connect ETIMEDOUT|connect ECONNREFUSED|fetch failed|Network error|ENOTFOUND|ECONNREFUSED|ECONNRESET/i,msg:"Network error"},{match:/certificate verify failed|SSL.*certificate|self.signed.cert|CERTIFICATE_VERIFY_FAILED/i,msg:"SSL certificate error"},{match:/No space left on device|disk full|ENOSPC/i,msg:"Disk full"},{match:/paperforge.*not found|cannot import|ModuleNotFoundError|No module named/i,msg:"PaperForge not installed"},{match:/permission denied|EACCES|EPERM/i,msg:"Permission denied"},{match:/ENOENT/i,msg:"Path not found"},{match:/timeout|timed out/i,msg:"Timeout"}];for(let n of t)if(n.match.test(e))return n.msg;return e.split(`
|
|
`).filter(Boolean).slice(0,3).join(" | ").slice(0,200)||"Unknown error"}_stepComplete(e){e.createEl("h2",{text:o("complete_title")});let t=e.createEl("div",{cls:"paperforge-summary"});t.createEl("div",{cls:"paperforge-summary-title",text:o("complete_summary")});let r=this.plugin.settings,n=this.app.vault.adapter.basePath,a=[{label:o("dir_vault"),val:n},{label:o("dir_resources"),val:`${n}/${r.resources_dir}`},{label:o("dir_notes"),val:`${n}/${r.resources_dir}/${r.literature_dir}`},{label:o("dir_base"),val:`${n}/${r.base_dir}`},{label:o("dir_system"),val:`${n}/${r.system_dir}`},{label:"API Key",val:r.paddleocr_api_key?o("api_key_set"):o("api_key_missing")},{label:o("field_zotero_data"),val:r.zotero_data_dir||o("not_set")}];for(let _ of a){let f=t.createEl("div",{cls:"paperforge-summary-row"});f.createEl("span",{cls:"paperforge-summary-label",text:_.label}),f.createEl("span",{cls:"paperforge-summary-value",text:_.val})}let s=t.createEl("div",{cls:"paperforge-summary-row"});s.createEl("span",{cls:"paperforge-summary-label",text:"PaperForge"});let i=s.createEl("span",{cls:"paperforge-summary-value",text:"\u2014"});{let _=n,{path:f,extraArgs:u=[]}=z(_,this.plugin.settings,void 0,void 0);(0,Ie.execFile)(f,[...u,"-c","import paperforge; print(paperforge.__version__)"],{cwd:_,timeout:1e4},(g,m)=>{!g&&m&&(i.textContent="v"+m.trim())})}for(let _ of a){let f=t.createEl("div",{cls:"paperforge-summary-row"});f.createEl("span",{cls:"paperforge-summary-label",text:_.label}),f.createEl("span",{cls:"paperforge-summary-value",text:_.val})}e.createEl("h3",{text:o("complete_next")});let c=e.createEl("div",{cls:"paperforge-nextsteps"}),l=[[o("complete_step4"),o("complete_step4_desc")],["",`${o("complete_export_path")} ${n}/${r.system_dir}/PaperForge/exports/`],[o("complete_step1"),o("complete_step1_desc")],[o("complete_step2"),o("complete_step2_desc")],[o("complete_step3"),o("complete_step3_desc")]];for(let[_,f]of l){let u=c.createEl("div",{cls:"paperforge-nextstep-item"});_&&u.createEl("strong",{text:_}),u.createEl("span",{text:f})}}};var Fe=H(require("fs")),Je=H(require("path")),$t=require("child_process");function ht(p){return p.display_action==="rebuild_result"?"rebuild":p.display_action==="retry_ocr"||p.display_action==="upgrade_legacy"?"redo":null}function gt(p){return p==="redo"}function cr(p,d,e){let t={manifest:p,papers:{},cached_at:new Date().toISOString()};if(e!=null&&e.papers)for(let r of Object.keys(p))e.papers[r]&&(t.papers[r]=e.papers[r]);for(let r of d)t.papers[r.key]=r;return t}function jt(p){return Je.join(p,"System","PaperForge","cache","ocr_maintenance.json")}function Ge(p){try{let d=jt(p),e=Fe.readFileSync(d,"utf-8");return JSON.parse(e)}catch(d){return null}}function pr(p,d){let e=jt(p),t=Je.dirname(e);Fe.mkdirSync(t,{recursive:!0}),Fe.writeFileSync(e,JSON.stringify(d,null,2),"utf-8")}function Nt(p,d,e){return new Promise((t,r)=>{(0,$t.execFile)(p,d,e,(n,a)=>{n?r(n):t(a)})})}async function mt(p,d,e,t){let r=await Nt(d,[...e,"-m","paperforge","ocr","list","--manifest"],{cwd:p,timeout:3e4}),n=JSON.parse(r);if(t){let _=Object.keys(t.manifest),f=Object.keys(n);if(_.length===f.length&&_.every(g=>t.manifest[g]===n[g])&&Object.values(t.papers).every(m=>typeof m.needs_derived_rebuild=="boolean"))return{data:Object.values(t.papers),changed:!1}}let a=Object.keys(n),s=await Nt(d,[...e,"-m","paperforge","ocr","list","--json","--keys",...a],{cwd:p,timeout:3e4}),i=JSON.parse(s),c=cr(n,i,t);return pr(p,c),{data:Object.values(c.papers),changed:!0}}var dr=["EMBED","OCR_REBUILD","OCR_REDO"];function yt(p,d){var a,s;let t=(d+p).split(`
|
|
`),r=(a=t.pop())!=null?a:"",n=[];for(let i of t)for(let c of dr){let l=c.length;if(i.startsWith(c+"_START:")){let _=parseInt(i.slice(l+7),10)||0;n.push({prefix:c,event:"START",total:_});break}if(i.startsWith(c+"_PROGRESS:")){let f=i.slice(l+10).split(":");n.push({prefix:c,event:"PROGRESS",current:parseInt(f[0],10)||0,total:parseInt(f[1],10)||0,key:(s=f[2])!=null?s:""});break}if(i===c+"_DONE"||i.startsWith(c+"_DONE:")){n.push({prefix:c,event:"DONE"});break}}return{events:n,buffer:r}}var Ne=class Ne extends F.PluginSettingTab{constructor(e,t){super(e,t);this._saveTimeout=null;this._pfConfig=null;this._lastSyncTime=null;this._memoryStatusText=null;this._vectorDepsOk=null;this._embedStatusText=null;this._skillsCollapsed={user:!0};this._featurePanelsCollapsed={};this._advCollapsed=!0;this._refreshPending=!1;this._pythonInterpDescEl=null;this._customPathDescEl=null;this._checkEl=null;this.activeTab="setup";this._buildState="idle";this._buildProgress={current:0,total:0,key:""};this._capabilityState=null;this._probing=new Set;this._attemptedProbes=new Set;this.plugin=t}_refreshPfConfig(){this._pfConfig=this.plugin.readPaperforgeJson()}display(){let{containerEl:e}=this;if(e.empty(),this._refreshPfConfig(),this._initCapabilityState(),this._applyStaleTolerance(),!document.getElementById("paperforge-tab-styles")){let a=document.createElement("style");a.id="paperforge-tab-styles",a.textContent=`
|
|
.paperforge-settings-tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--background-modifier-border); }
|
|
.paperforge-settings-tab { padding: 6px 16px; border: none; background: none; cursor: pointer; border-bottom: 2px solid transparent; font-size: 14px; color: var(--text-muted); }
|
|
.paperforge-settings-tab--active { color: var(--text-accent); border-bottom-color: var(--text-accent); }
|
|
.paperforge-tab-content { display: none; }
|
|
.paperforge-tab-content--active { display: block; }
|
|
.paperforge-skills-collapse-header { display: flex !important; align-items: center; cursor: pointer; padding: 6px 0 !important; margin: 0 !important; }
|
|
.paperforge-skills-collapse-header h4 { margin: 0 !important; }
|
|
.paperforge-skills-collapse-content { margin: 0 !important; padding: 0 !important; }
|
|
.paperforge-skills-group { margin-bottom: 10px; }
|
|
.paperforge-skills-group:last-child { margin-bottom: 0; }
|
|
.vertical-tab-content-container { overflow-y: scroll !important; }
|
|
.paperforge-release-card { border: 1px solid var(--background-modifier-border); border-radius: 6px; padding: 12px; margin-bottom: 12px; }
|
|
.paperforge-release-header { margin-bottom: 8px; }
|
|
.paperforge-release-date { color: var(--text-muted); font-size: 12px; }
|
|
.paperforge-release-section { margin-bottom: 6px; }
|
|
.paperforge-release-label { font-weight: 600; color: var(--text-accent); margin-bottom: 2px; font-size: 13px; }
|
|
.paperforge-release-item { font-size: 13px; margin-left: 8px; color: var(--text-muted); }
|
|
.paperforge-release-item-bold { font-size: 13px; margin-left: 8px; font-weight: 600; color: var(--text-normal); }
|
|
.paperforge-release-recommended { background: rgba(var(--color-orange-rgb, 255,166,0), 0.08); border-radius: 4px; padding: 6px 8px; }
|
|
.paperforge-manual-links { margin-top: 8px; }
|
|
.paperforge-manual-links a { color: var(--text-accent); }
|
|
.paperforge-modal-subtitle { color: var(--text-muted); font-size: 13px; margin-bottom: 12px; }
|
|
.paperforge-modal-item { font-size: 13px; margin-left: 8px; color: var(--text-muted); }
|
|
`,document.head.appendChild(a)}let t=e.createDiv({cls:"paperforge-settings-tabs"}),r=[{id:"setup",label:o("tab_setup")||"\u5B89\u88C5"},{id:"features",label:o("tab_features")||"\u529F\u80FD"},{id:"maintenance",label:o("tab_maintenance")||"\u7EF4\u62A4"},{id:"release-notes",label:"\u66F4\u65B0\u4E0E\u624B\u518C"}],n={};r.forEach(a=>{t.createEl("button",{cls:"paperforge-settings-tab"+(a.id===this.activeTab?" paperforge-settings-tab--active":""),text:a.label}).addEventListener("click",()=>{this.activeTab=a.id,this.display()})}),r.forEach(a=>{n[a.id]=e.createDiv({cls:"paperforge-tab-content"+(a.id===this.activeTab?" paperforge-tab-content--active":"")})}),this.activeTab==="setup"?this._renderSetupTab(n.setup):this.activeTab==="features"?this._renderFeaturesTab(n.features):this.activeTab==="maintenance"?this._renderMaintenanceTab(n.maintenance):this._renderReleaseNotesTab(n["release-notes"])}_renderSetupTab(e){var r;let t=this.app.vault.adapter.basePath;this.plugin.settings.vault_path||(this.plugin.settings.vault_path=t,this._debouncedSave()),e.createEl("h2",{text:o("header_title")||"PaperForge"}),e.createEl("p",{text:o("desc"),cls:"paperforge-settings-desc"}),this._renderControlCenter(e);for(let n of Se){let a=(r=this._capabilityState)==null?void 0:r[n];a&&a.capability_state==="unknown"&&a.updated_at===new Date(0).toISOString()&&!this._attemptedProbes.has(n)&&(this._attemptedProbes.add(n),(n==="installation"||n==="help")&&this._probeModule(n))}}_execMemoryStatus(e,t,r){(0,G.exec)(`"${e}" -m paperforge --vault "${t}" memory status --json`,{encoding:"utf-8",timeout:15e3},(n,a)=>{if(n){r("Status unavailable");return}try{let s=JSON.parse(a);if(s.ok){let i=s.data,c=i.fresh?"fresh":"stale";r(`Papers: ${i.paper_count_db} | ${c}${i.needs_rebuild?" - needs rebuild":""}`)}else r("DB not found. Run paperforge memory build.")}catch(s){r("Could not parse status.")}})}_execEmbedStatus(e,t,r){(0,G.exec)(`"${e}" -m paperforge --vault "${t}" embed status --json`,{encoding:"utf-8",timeout:15e3},(n,a)=>{if(n){r("Status unavailable");return}try{let s=JSON.parse(a);s.ok?r(`Chunks: ${s.data.chunk_count} | ${s.data.model} | ${s.data.mode}`):r("Could not parse status.")}catch(s){r("Could not parse status.")}})}_callPython(e,t){let r=this.app.vault.adapter.basePath,n=he(r,this.plugin.settings),a=[...n.extraArgs,"-m","paperforge","--vault",r,...e];if(t&&t.stream){let s=(0,G.spawn)(n.path,a,{cwd:r,env:t.env||process.env,windowsHide:!0});return t.onData&&s.stdout.on("data",t.onData),t.onStderr&&s.stderr.on("data",t.onStderr),t.onError&&s.on("error",t.onError),s.on("close",t.onClose),s}return(0,G.execFile)(n.path,a,{cwd:r,timeout:t&&t.timeout||6e4},(s,i,c)=>{t&&t.onClose&&t.onClose(s?1:0,i,c)}),null}_renderMemoryStatusText(e,t,r){e.innerHTML="",e.createEl("span",{text:t,cls:"paperforge-memory-text"}),r==="syncing"?e.createEl("span",{text:"Syncing...",cls:"paperforge-sync-status"}):r&&e.createEl("span",{text:r,cls:"paperforge-sync-status"});let n=e.createEl("button",{cls:"paperforge-rebuild-btn",text:o("feat_memory_rebuild_btn")});n.title="Rebuild memory database",n.onclick=()=>{let s=this.app.vault.adapter.basePath,i=he(s,this.plugin.settings);if(!i.path){new F.Notice(o("feat_no_python"));return}console.log("[PaperForge] Rebuilding memory:",i.path),n.setText(o("feat_memory_rebuilding")),n.setAttr("disabled",""),this._callPython(["memory","build"],{timeout:6e4,onClose:(c,l,_)=>{console.log("[PaperForge] memory build exit:",c?"FAIL:"+c:"OK",(l||"").slice(0,200),(_||"").slice(0,200)),n.setText(o("feat_memory_rebuild_btn")),n.removeAttribute("disabled"),c===0?new F.Notice(o("feat_memory_rebuild_done")):new F.Notice(o("feat_memory_rebuild_failed")+(_?" "+_.slice(0,80):"")),this._memoryStatusText=Ue(s),this._refreshSnapshots(s)}})};let a=e.createEl("button",{cls:"paperforge-refresh-btn",text:"\u21BB"});a.title="Sync now",a.onclick=()=>{this._memoryStatusText=null,this._runManualSync()}}_getBuildCommand(e){let t=this.app.vault.adapter.basePath,r=z(t,e,void 0,void 0);return r.path?`"${r.path}" -m paperforge --vault "${t}" sync`:null}_runManualSync(){let e=this.app.vault.adapter.basePath;if(!he(e,this.plugin.settings).path)return;let r=document.querySelector(".paperforge-memory-status");r&&this._renderMemoryStatusText(r,"Checking...","syncing"),this.plugin._autoSyncRunning=!0,this._callPython(["sync"],{timeout:12e4,onClose:n=>{this.plugin._autoSyncRunning=!1,this._memoryStatusText=null,n===0&&(this._lastSyncTime=new Date().toLocaleTimeString(),this.plugin._lastSyncTime=this._lastSyncTime),this.display(),this._refreshSnapshots(e),Ze(this.app,this.plugin,e)}})}_refreshSnapshots(e){let t=he(e,this.plugin.settings),r=[...t.extraArgs,"-m","paperforge","--vault",e,"runtime-health","--json"];this._refreshPending=!0,(0,G.execFile)(t.path,r,{cwd:e,timeout:3e4,windowsHide:!0},(n,a,s)=>{this._refreshPending=!1,this._memoryStatusText=Ue(e),this._embedStatusText=Re(e),this.display()})}_renderFeaturesTab(e){e.createEl("h3",{text:"Skills"});let t=e.createEl("div",{cls:"paperforge-desc-box"});t.setText(o("feat_skills_desc")),t.createEl("br"),t.createEl("span",{text:o("feat_skills_system")});let r={opencode:"OpenCode",claude:"Claude Code",codex:"Codex",cursor:"Cursor",windsurf:"Windsurf",github_copilot:"GitHub Copilot",gemini:"Gemini CLI"},n={opencode:".opencode/skills",claude:".claude/skills",codex:".codex/skills",cursor:".cursor/skills",windsurf:".windsurf/skills",github_copilot:".github/skills",gemini:".gemini/skills"},a=this.app.vault.adapter.basePath,s=this.plugin.settings.selected_skill_platform||"opencode";new F.Setting(e).setName(o("feat_agent_platform")).setDesc(o("feat_agent_platform_desc")).addDropdown(y=>{Object.entries(r).forEach(([E,w])=>y.addOption(E,w)),y.setValue(s).onChange(E=>{this.plugin.settings.selected_skill_platform=E,this.plugin.saveSettings(),this.display()})}).addExtraButton(y=>{y.setIcon("folder").setTooltip("Open skills folder").onClick(()=>{let E=n[s]||".opencode/skills",w=te.join(a,E);W.existsSync(w)?(0,G.exec)(`start "" "${w}"`):new F.Notice(`Skills folder not found: ${E}`)})});let i=te.join(a,n[s]),c=[],l=[];W.existsSync(i)&&W.readdirSync(i,{withFileTypes:!0}).forEach(y=>{if(!y.isDirectory())return;let E=te.join(i,y.name,"SKILL.md");if(!W.existsSync(E))return;let w=W.readFileSync(E,"utf-8"),D=w.match(/^name:\s*(.+)$/m),T=w.split(`
|
|
`),I=T.findIndex(N=>/^description:/.test(N)),B="";if(I>=0){let N=T[I].match(/^description:\s*(.+)$/);if(N&&N[1]&&N[1]!==">"&&N[1]!=="|-"&&N[1]!=="|")B=N[1].trim();else{for(let q=I+1;q<T.length&&(/^\s{2,}/.test(T[q])||T[q].trim()==="");q++)B+=T[q].trim()+" ";B=B.trim()}}let $=w.match(/^source:\s*(.+)$/m),V=w.match(/^disable-model-invocation:\s*(.+)$/m),A=w.match(/^version:\s*(.+)$/m),S={name:D?D[1].trim():y.name,desc:B,source:$?$[1].trim():"user",disabled:V&&V[1].trim()==="true",version:A?A[1].trim():"",path:E,content:w,dirName:y.name};S.source==="paperforge"?c.push(S):l.push(S)});let _=e.createEl("div",{cls:"paperforge-skills-box"}),f=(y,E,w)=>{if(E.length===0)return;let D=_.createEl("div",{cls:"paperforge-skills-group"}),T=D.createEl("div",{cls:"paperforge-skills-collapse-header"}),I=D.createEl("div",{cls:"paperforge-skills-collapse-content"}),B=T.createEl("span",{text:"\u25BC",cls:"paperforge-skills-arrow"});T.createEl("h4",{text:`${y} (${E.length})`,cls:"paperforge-skills-subheader"}),E.forEach(A=>{let S=A.name+(A.version?" v"+A.version:""),N=w?" [system]":" [user]",q=A.desc||"",j=new F.Setting(I).setName(S+N).setDesc(q);j.settingEl.style.opacity=A.disabled?"0.4":"1",j.addToggle(O=>{O.setValue(!A.disabled).onChange(se=>{let Q=!se,ee=A.content.match(/^disable-model-invocation:\s*(.+)$/m)?A.content.replace(/^disable-model-invocation:\s*.+$/m,`disable-model-invocation: ${Q}`):A.content.replace(/^(---\r?\n)/,`$1disable-model-invocation: ${Q}
|
|
`);W.writeFileSync(A.path,ee,"utf-8"),A.disabled=Q,A.content=ee,j.settingEl.style.opacity=A.disabled?"0.4":"1"})})});let $=w?"system":"user";(this._skillsCollapsed[$]||!1)&&(I.style.display="none",B.style.transform="rotate(-90deg)"),T.addEventListener("click",()=>{I.style.display!=="none"?(I.style.display="none",B.style.transform="rotate(-90deg)"):(I.style.display="",B.style.transform="rotate(0deg)"),this._skillsCollapsed[$]=I.style.display==="none"})};f("System Skills",c,!0),f("User Skills",l,!1),c.length===0&&l.length===0&&_.createEl("p",{text:`No skills found in ${n[s]}. Run setup to deploy skills.`,cls:"setting-item-description"}),this._advCollapsed===void 0&&(this._advCollapsed=!0);let u=e.createEl("div",{cls:"paperforge-collapsible-header"}),g=u.createEl("span",{text:"\u25B6",cls:"paperforge-collapsible-arrow"});g.style.transform=this._advCollapsed?"rotate(0deg)":"rotate(90deg)";let m=u.createEl("span",{cls:"paperforge-collapsible-title",text:"Advanced"}),b=u.createEl("span",{cls:"paperforge-collapsible-sub",text:"Memory + Vector DB + Embedding"}),h=e.createEl("div",{cls:"paperforge-collapsible-content"});h.style.display=this._advCollapsed?"none":"",u.addEventListener("click",()=>{this._advCollapsed=!this._advCollapsed,h.style.display=this._advCollapsed?"none":"",g.style.transform=this._advCollapsed?"rotate(0deg)":"rotate(90deg)"}),h.createEl("h4",{text:"Memory Layer"}),h.createEl("div",{cls:"paperforge-desc-box"}).setText(o("feat_memory_desc"));let x=h.createEl("div",{cls:"paperforge-memory-status"}),k=this.app.vault.adapter.basePath;this.plugin._lastSyncTime&&!this._lastSyncTime&&(this._lastSyncTime=this.plugin._lastSyncTime),this._memoryStatusText===null&&(this._memoryStatusText=Ue(k)),this._renderMemoryStatusText(x,this._memoryStatusText,this._lastSyncTime),this._renderVectorSection(h)}_renderVectorSection(e){var c;if(e.createEl("h4",{text:"Vector Database"}),this.plugin.settings.features||(this.plugin.settings.features={memory_layer:!0,vector_db:!1}),e.createEl("div",{cls:"paperforge-desc-box"}).setText(o("feat_vector_desc")),new F.Setting(e).setName(o("feat_vector_enable")).setDesc(o("feat_vector_enable_desc")).addToggle(l=>{l.setValue(!!this.plugin.settings.features.vector_db).onChange(_=>{this.plugin.settings.features.vector_db=_,this.plugin.saveSettings(),this._vectorDepsOk=null,this._embedStatusText=null,this.display()})}),!this.plugin.settings.features.vector_db)return;let r=this.app.vault.adapter.basePath,n=e.createEl("div",{cls:"paperforge-vec-header"}),a=n.createEl("span",{text:"\u25BC",cls:"paperforge-skills-arrow"});n.createEl("span",{cls:"paperforge-vec-header-label",text:o("feat_vector_config_label")});let s=e.createEl("div",{cls:"paperforge-vector-config"}),i=l=>{s.style.display=l?"none":"",a.style.transform=l?"rotate(-90deg)":"rotate(0deg)"};if(i(_t(this._featurePanelsCollapsed,"vectorConfig",!1)),n.addEventListener("click",()=>{let l=Ot(this._featurePanelsCollapsed,"vectorConfig",!1);i(l)}),this._vectorDepsOk===!0){this._renderVectorReady(s,r);return}if(this._vectorDepsOk===!1){this._renderVectorNoDeps(s);return}if(this._vectorDepsOk===null){let l=We(r);this._vectorDepsOk=l&&(c=l.deps_installed)!=null?c:!1,this._vectorDepsOk&&(this._embedStatusText=Re(r)),this.display()}}_renderApiConfig(e){new F.Setting(e).setName(o("feat_openai_key")).setDesc(o("feat_openai_key_desc")).addText(t=>{t.setPlaceholder("sk-...").setValue(this.plugin.settings.vector_db_api_key||"").onChange(r=>{this.plugin.settings.vector_db_api_key=r,this.plugin.saveSettings()})}),new F.Setting(e).setName(o("feat_api_base_url")).setDesc(o("feat_api_base_url_desc")).addText(t=>{t.setPlaceholder("https://api.openai.com/v1").setValue(this.plugin.settings.vector_db_api_base||"").onChange(r=>{this.plugin.settings.vector_db_api_base=r,this.plugin.saveSettings()})}),new F.Setting(e).setName(o("feat_api_model")).setDesc(o("feat_api_model_desc")).addText(t=>{t.setPlaceholder("text-embedding-3-small").setValue(this.plugin.settings.vector_db_api_model||"text-embedding-3-small").onChange(r=>{this.plugin.settings.vector_db_api_model=r,this.plugin.saveSettings()})})}_renderVectorNoDeps(e){e.createEl("div",{cls:"paperforge-desc-box"}).setText(o("feat_deps_missing")),new F.Setting(e).setName(o("feat_install_deps")).setDesc(o("feat_install_deps_desc")).addButton(r=>{r.setButtonText(o("feat_install_btn")).setCta().onClick(async()=>{let n=this.app.vault.adapter.basePath,a=he(n,this.plugin.settings);if(!a.path){new F.Notice(o("feat_no_python"));return}r.setButtonText(o("feat_installing")),r.setDisabled(!0);let s="chromadb openai",i=new F.Notice(o("feat_installing_pkgs").replace("{pkgs}",s),0);try{let c=Object.assign({},process.env,{PYTHONIOENCODING:"utf-8",PYTHONUTF8:"1"}),l=s.split(" ");await new Promise((_,f)=>{(0,G.execFile)(a.path,[...a.extraArgs,"-m","pip","install",...l],{cwd:n,timeout:3e5,env:c,windowsHide:!0},u=>{u?f(u):_()})}),i.hide(),new F.Notice(o("feat_install_done")),this._vectorDepsOk=!0,this._embedStatusText=Re(n),this.display()}catch(c){i.hide(),new F.Notice(o("feat_install_failed")+(c.stderr||c.message||c)),r.setButtonText(o("feat_retry_btn")),r.setDisabled(!1)}})})}_renderVectorReady(e,t){e.createEl("div",{cls:"paperforge-desc-box"}).setText(Re(t)),this._renderApiConfig(e);let n=e.createEl("div",{cls:"paperforge-embed-section"});n.createEl("div",{cls:"paperforge-embed-header"}).createEl("span",{text:o("retrieval_rebuild_vectors"),cls:"setting-item-name"});let s=n.createEl("div",{cls:"paperforge-embed-controls"}),i=n.createEl("div",{cls:"paperforge-embed-status-text",attr:{"aria-live":"polite"}});(()=>{s.empty(),i.empty();let l=We(t),_=l==null?void 0:l.build_state,f=_&&typeof _=="object"&&!Array.isArray(_)?_:{};this.plugin._embedProgress=this.plugin._embedProgress||{current:0,total:0,key:""},!this.plugin._embedProcess&&f.status==="running"&&(this.plugin._embedProgress={current:typeof f.current=="number"?f.current:0,total:typeof f.total=="number"?f.total:1,key:typeof f.paper_id=="string"?f.paper_id:""});let{current:u,total:g,key:m}=this.plugin._embedProgress,b=typeof(l==null?void 0:l.body_chunk_count)=="number"?l.body_chunk_count:0,h=typeof(l==null?void 0:l.object_chunk_count)=="number"?l.object_chunk_count:0,x=(typeof(l==null?void 0:l.chunk_count)=="number"?l.chunk_count:0)+b+h,k=x>0,y=l!==null&&typeof l.corrupted=="boolean"&&l.corrupted,E=!!this.plugin._embedProcess,w=!this.plugin._embedProcess&&f.status==="running",D=(l==null?void 0:l.deps_installed)!==void 0?!!l.deps_installed:!0,T=typeof f.status=="string"?f.status:"",I=typeof f.message=="string"?f.message:"",B=S=>{var j;if(S==="--resume"&&k&&!y){let O=o("retrieval_rebuild_warning").replace("{n}",String(x));if(!confirm(O))return}if(S==="--force"&&k&&!y){let O="Force rebuild will replace "+x+" existing chunk(s). Continue?";if(!confirm(O))return}if(!he(t,this.plugin.settings).path){new F.Notice(o("retrieval_no_python"));return}let q=Object.assign({},process.env,{PYTHONIOENCODING:"utf-8",PYTHONUTF8:"1",VECTOR_DB_API_KEY:this.plugin.settings.vector_db_api_key||"",VECTOR_DB_API_BASE:this.plugin.settings.vector_db_api_base||"",VECTOR_DB_API_MODEL:this.plugin.settings.vector_db_api_model||""});this.plugin._embedStderr="",this.plugin._embedProgress={current:0,total:0,key:""},this.plugin._embedProcess=this._callPython(["embed","build",S],{stream:!0,env:q,onData:O=>{var ee;let se=typeof O=="string"?O:Buffer.isBuffer(O)?O.toString("utf-8"):String(O),{events:Q,buffer:ce}=yt(se,(ee=this.plugin._embedBuffer)!=null?ee:"");this.plugin._embedBuffer=ce;for(let Z of Q)Z.event==="START"?this.plugin._embedProgress.total=Z.total||0:Z.event==="PROGRESS"?(this.plugin._embedProgress.current=Z.current||0,this.plugin._embedProgress.key=Z.key||""):Z.event==="DONE"&&(this.plugin._embedProcess=null,this.plugin._embedProgress.current=this.plugin._embedProgress.total);this.display()},onStderr:O=>{this.plugin._embedStderr||(this.plugin._embedStderr=""),this.plugin._embedStderr+=String(O)},onError:O=>{this.plugin._embedProcess=null,new F.Notice(o("feat_build_failed")+": "+(O.message||O)),this.display()},onClose:O=>{var se;if(clearInterval((se=this.plugin._embedPollInterval)!=null?se:void 0),this.plugin._embedPollInterval=null,this.plugin._embedProcess=null,O===0)this.plugin._embedProgress.current=this.plugin._embedProgress.total,this.plugin.saveSettings(),this._embedStatusText=Re(t),new F.Notice(o("feat_build_complete"));else{this._embedStatusText=null;let Q=(this.plugin._embedStderr||"").slice(0,200);new F.Notice(o("feat_build_failed")+(Q?": "+Q:""),8e3)}this.plugin._embedStderr="",this.display(),this._refreshSnapshots(t)}}),clearInterval((j=this.plugin._embedPollInterval)!=null?j:void 0),this.plugin._embedPollInterval=setInterval(()=>{this.plugin._embedPolling||(this.plugin._embedPolling=!0,this._callPython(["embed","status","--json"],{timeout:5e3,onClose:(O,se)=>{var Q;if(this.plugin._embedPolling=!1,O===0&&se)try{let ee=JSON.parse(se).data;if(ee&&ee.build_state){let Z=ee.build_state;(Z.status==="stopping"||Z.status==="idle")&&this.plugin._embedProcess&&(this.plugin._embedProcess=null,clearInterval((Q=this.plugin._embedPollInterval)!=null?Q:void 0),this.plugin._embedPollInterval=null,this.display()),Z.current!==void 0&&Z.total!==void 0&&(this.plugin._embedProgress.current=Z.current,this.plugin._embedProgress.total=Z.total||1,this.plugin._embedProgress.key=Z.paper_id||"")}}catch(ce){}}}))},2e3),this.display()},$=Me(t),V=!1;$&&typeof $.summary=="object"&&$.summary!==null&&"status"in $.summary&&(V=$.summary.status==="version_mismatch");let A;switch(D?V?A="runtime-mismatch":T==="stopping"?A="stopping":E&&T==="running"?A="building":T==="failed"?A="failed":T==="stopped"?A="stopped":w?A="stale":y?A="corrupted":k?A="ready":A="idle":A="deps-missing",A){case"building":{let S=s.createEl("div",{cls:"paperforge-progress-track"});S.style.cssText="flex:1;";let N=g>0?(u/g*100).toFixed(1):"0",q=S.createEl("div",{cls:"paperforge-progress-seg done"});if(q.style.cssText=`width:${N}%; min-width:${u>0?"2px":"0"};`,u<g){let O=S.createEl("div",{cls:"paperforge-progress-seg pending"});O.style.cssText=`width:${(100-parseFloat(N)).toFixed(1)}%;`}i.createEl("span",{cls:"paperforge-embed-progress-text",text:`${u}/${g} papers`}),m&&i.createEl("span",{cls:"paperforge-embed-progress-key",text:` (${m})`});let j=s.createEl("button");j.setText(o("retrieval_stop")),j.className="mod-warning",j.addEventListener("click",()=>{this._callPython(["embed","stop","--json"],{timeout:8e3}),this.display()});break}case"stopping":{let S=s.createEl("div",{cls:"paperforge-progress-track"});S.style.cssText="flex:1; opacity:0.5;";let N=g>0?(u/g*100).toFixed(1):"0",q=S.createEl("div",{cls:"paperforge-progress-seg done"});if(q.style.cssText=`width:${N}%; min-width:${u>0?"2px":"0"};`,u<g){let O=S.createEl("div",{cls:"paperforge-progress-seg pending"});O.style.cssText=`width:${(100-parseFloat(N)).toFixed(1)}%;`}i.createEl("span",{text:o("retrieval_build_stopping")});let j=s.createEl("button");j.setText(o("retrieval_stop")),j.className="mod-warning",j.setAttr("disabled","");break}case"failed":{i.createEl("div",{cls:"paperforge-desc-box",text:o("retrieval_build_failed")+(I?": "+I:""),attr:{style:"color:var(--text-error);"}});let S=s.createEl("button");S.setText(o("retrieval_retry")),S.className="mod-cta",S.addEventListener("click",()=>B("--resume"));let N=s.createEl("button");N.setText(o("retrieval_force_rebuild")),N.style.marginLeft="6px",N.addEventListener("click",()=>B("--force"));break}case"stopped":{i.setText(o("retrieval_build_stopped"));let S=s.createEl("button");S.setText(o("retrieval_retry")),S.className="mod-cta",S.addEventListener("click",()=>B("--resume"));break}case"corrupted":{i.createEl("div",{cls:"paperforge-desc-box",text:o("feat_vector_corrupted"),attr:{style:"background:var(--background-modifier-warning);"}});let S=s.createEl("button");S.setText(o("retrieval_force_rebuild")),S.className="mod-cta",S.addEventListener("click",()=>B("--force"));break}case"stale":{i.createEl("div",{cls:"paperforge-desc-box",text:o("retrieval_build_stale"),attr:{style:"color:var(--text-warning);"}});let S=s.createEl("button");S.setText(o("retrieval_rebuild_vectors")),S.className="mod-cta",S.addEventListener("click",()=>B("--resume"));break}case"ready":{s.createEl("span",{text:x+" chunks embedded",cls:"setting-item-description"});let S=s.createEl("button");S.setText(o("retrieval_rebuild_vectors")),S.className="mod-cta",S.addEventListener("click",()=>B("--resume"));let N=s.createEl("button");N.setText(o("retrieval_force_rebuild")),N.style.marginLeft="6px",N.addEventListener("click",()=>B("--force"));break}case"deps-missing":{i.setText(o("retrieval_build_deps_missing"));let S=s.createEl("a");S.setText(o("feat_install_deps")),S.style.cssText="cursor:pointer; text-decoration:underline;",S.addEventListener("click",()=>{this.display()});break}case"runtime-mismatch":{i.createEl("div",{cls:"paperforge-desc-box",text:o("retrieval_build_runtime_mismatch"),attr:{style:"color:var(--text-warning);"}});let S=s.createEl("a");S.setText(o("runtime_health_sync")),S.style.cssText="cursor:pointer; text-decoration:underline;",S.addEventListener("click",()=>{this.display()});break}case"idle":default:{i.setText(o("retrieval_build_idle"));let S=s.createEl("button");S.setText(o("feat_build_btn")),S.className="mod-cta",S.addEventListener("click",()=>B("--resume"));break}}})()}_getCurrentModelKey(){return this.plugin.settings.vector_db_api_model||"text-embedding-3-small"}_parseEmbedStatus(e){let t={};return e&&(e.split(`
|
|
`).forEach(r=>{let n=r.match(/^\s*([^:]+):\s*(.*)/);n&&(t[n[1].trim()]=n[2].trim())}),t.db_exists!==void 0&&(t.db_exists=t.db_exists==="True"),t.chunk_count!==void 0&&(t.chunk_count=parseInt(t.chunk_count,10)||0)),t}_getPythonDesc(e,t){return t==="stale"?`[!!] ${e} (stale \u2014 path no longer exists, update or clear the override below)`:t==="manual"?`${e} (manual)`:`${e} (auto-detected)`}_refreshPythonInterpDesc(e,t){let r=this._pythonInterpDescEl;r&&(t==="stale"?r.textContent=`[!!] ${e} (stale \u2014 path no longer exists, update or clear the override below)`:t==="manual"?r.textContent=`${e} (manual)`:r.textContent=`${e} (auto-detected)`)}_validatePythonOverride(){let e=this.plugin.settings.python_path?this.plugin.settings.python_path.trim():"",t=this._customPathDescEl;if(!e){let r="\u8BF7\u8F93\u5165\u8DEF\u5F84 / Enter a path first";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${r}</span>`),new F.Notice(r);return}if(!W.existsSync(e)){let r="\u8DEF\u5F84\u4E0D\u5B58\u5728 / Path does not exist";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${r}</span>`),new F.Notice(r,4e3);return}try{W.accessSync(e,W.constants.X_OK)}catch(r){let n="\u4E0D\u53EF\u6267\u884C / Not executable";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${n}</span>`),new F.Notice(n,4e3);return}(0,G.execFile)(e,["--version"],{timeout:8e3},(r,n)=>{if(r||!n){let c="\u65E0\u6CD5\u8FD0\u884C / Cannot run";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${c}</span>`),new F.Notice(c,4e3);return}let a=n.match(/Python (\d+)\.(\d+)/);if(!a){let c="\u65E0\u6CD5\u89E3\u6790\u7248\u672C / Cannot parse version";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${c}</span>`),new F.Notice(c,4e3);return}let s=parseInt(a[1],10),i=parseInt(a[2],10);if(s<3||s===3&&i<10){let c="Python \u7248\u672C\u8FC7\u4F4E\uFF0C\u9700\u8981 3.10+ / Python version too low, need 3.10+";t&&(t.innerHTML=`<span style="color:var(--text-error)">\u2717 ${c}</span>`),new F.Notice(c,4e3);return}(0,G.execFile)(e,["-m","pip","--version"],{timeout:8e3},c=>{if(c){let l=`\u2713 Python ${s}.${i} \u6709\u6548\uFF0C\u4F46\u672A\u68C0\u6D4B\u5230 pip / Valid, but pip not found`;t&&(t.innerHTML=`<span style="color:var(--text-warning)">\u26A0 ${l}</span>`),new F.Notice(l,4e3)}else{let l=`\u2713 Python ${s}.${i} \u6709\u6548 / Valid`;t&&(t.innerHTML=`<span style="color:var(--text-accent)">${l}</span>`),new F.Notice(l,4e3)}})})}_syncRuntime(e){let t=this.app.vault.adapter.basePath,{path:r,extraArgs:n=[]}=z(t,this.plugin.settings,void 0,void 0),a=this.plugin.manifest.version,s=Tt(r,a,n);e.setDisabled(!0),e.setButtonText(o("runtime_health_syncing"));let i=(l,_)=>(console.log(`[PaperForge] Sync Runtime: trying ${_}`),At(s.cmd,l,t,s.timeout,void 0,we())),c=()=>{let l="opencode";try{let g=W.readFileSync(te.join(t,"paperforge.json"),"utf-8"),m=JSON.parse(g);m.agent_key&&(l=m.agent_key)}catch(g){}let _=[...n,"-c",'from paperforge.services.skill_deploy import deploy_skills; from pathlib import Path; r=deploy_skills(vault=Path(r"'+t.replace(/\\/g,"\\\\")+'"), agent_key="'+l+'", overwrite=True); print("skills deployed" if r["skill_deployed"] else "skills skipped", flush=True)'],f=(0,G.spawn)(r,_,{cwd:t,timeout:3e4,windowsHide:!0}),u="";f.stdout.on("data",g=>{u+=g.toString("utf-8")}),f.on("close",g=>{console.log(`[PaperForge] Skill deploy: ${u.trim()} (exit ${g})`)})};i(s.pypiArgs,"PyPI").then(l=>{if(l.exitCode===0){console.log("[PaperForge] Sync Runtime: installed via PyPI"),c(),new F.Notice(o("runtime_health_sync_done").replace("{0}",a),5e3),this.display();return}console.warn("[PaperForge] Sync Runtime: PyPI failed, falling back to git..."),i(s.gitArgs,"git").then(_=>{_.exitCode===0?(console.log("[PaperForge] Sync Runtime: installed via git"),c(),new F.Notice(o("runtime_health_sync_done").replace("{0}",a),5e3),this.display()):(e.setDisabled(!1),e.setButtonText(o("runtime_health_sync")),console.error("[PaperForge] git fallback stderr:",_.stderr),new F.Notice(o("runtime_health_sync_fail").replace("{0}","pip exit code "+_.exitCode),8e3))})})}_debouncedSave(){clearTimeout(this._saveTimeout),this._saveTimeout=setTimeout(()=>this.plugin.saveSettings(),500)}_preCheck(e){var a;let t=this.app.vault.adapter.basePath,{path:r,extraArgs:n=[]}=z(t,(a=this.plugin)==null?void 0:a.settings,void 0,void 0);(0,G.execFile)(r,[...n,"--version"],{timeout:8e3},(s,i)=>{let c=[];c.push({label:"Python",ok:!s,detail:s?o("check_python_fail"):i.trim()});let l=!1,_=process.env.HOME||process.env.USERPROFILE||zt.homedir()||"";if(process.platform==="darwin")l=["/Applications/Zotero.app",te.join(_,"Applications","Zotero.app")].some(v=>{try{return W.existsSync(v)}catch(x){return!1}});else if(process.platform==="win32"){let h=process.env.ProgramFiles||"",v=process.env.LOCALAPPDATA||"";l=[te.join(h,"Zotero"),te.join(h,"(x86)","Zotero"),te.join(v,"Programs","Zotero"),te.join(v,"Zotero"),te.join(_,"AppData","Local","Programs","Zotero")].filter(Boolean).some(k=>{try{return W.existsSync(k)}catch(y){return!1}})}else l=[te.join(_,".local","share","zotero","zotero"),"/usr/bin/zotero","/usr/local/bin/zotero"].some(v=>{try{return W.existsSync(v)}catch(x){return!1}});let f=this.plugin.settings.zotero_data_dir;if(!l&&f)try{l=W.existsSync(f)}catch(h){}c.push({label:"Zotero",ok:l,detail:l?o("check_zotero_ok"):o("check_zotero_fail")});let u=!1,g=process.env.APPDATA||"";process.platform==="win32"&&g&&(u=Ke(te.join(g,"Zotero","Zotero","Profiles"))),!u&&process.platform==="darwin"&&_&&(u=Ke(te.join(_,"Library","Application Support","Zotero","Profiles"))),!u&&process.platform!=="win32"&&process.platform!=="darwin"&&_&&(u=Ke(te.join(_,".zotero","zotero","Profiles"))),!u&&f&&String(f).trim()&&(u=pt(f.trim())),!u&&_&&(u=pt(te.join(_,"Zotero"))),c.push({label:"Better BibTeX",ok:u,detail:u?o("check_bbt_ok"):o("check_bbt_fail")});let m={true:"\u2713",false:"\u2717"};if(this._checkEl){this._checkEl.setText(c.map(v=>`${m[String(v.ok)]} ${v.label}: ${v.detail}`).join(`
|
|
`));let h=c.some(v=>!v.ok);this._checkEl.className=`paperforge-message msg-${h?"error":"ok"}`}let b=c.filter(h=>!h.ok);b.length>0&&new F.Notice(`[!!] \u672A\u901A\u8FC7: ${b.map(h=>h.label).join(", ")}`,6e3),e()})}_renderMaintenanceTab(e){var _;e.createEl("h2",{text:o("tab_maintenance")||"\u7EF4\u62A4"});let r=(_=this.app.vault.adapter.basePath)!=null?_:"",n=e.createEl("div"),a={active:"all"},s=null;try{s=Ge(r)}catch(f){}let i=z(r,this.plugin.settings,W,G.execFileSync);if(!i.path){n.createEl("p",{text:"\u26A0 Python \u672A\u914D\u7F6E\uFF0C\u8BF7\u5148\u5728\u300C\u5B89\u88C5\u300D\u6807\u7B7E\u9875\u914D\u7F6E\u3002",cls:"setting-item-description"});return}let c=()=>!!this.plugin._ocrProcess,l=f=>{n.empty();let u=f,g=n.createEl("div",{cls:"pf-maint-filters"}),m=g.createEl("button",{cls:"pf-maint-filter"+(a.active==="all"?" active":""),text:o("maintenance_filter_all")||"All"});m.addEventListener("click",()=>{a.active="all",l(f)});let b=g.createEl("button",{cls:"pf-maint-filter"+(a.active==="recommended"?" active":""),text:o("maintenance_filter_recommended")||"Recommended"});b.addEventListener("click",()=>{a.active="recommended",l(f)});let h=a.active==="recommended"?u.filter(v=>v.needs_derived_rebuild===!0):u;if(h.length===0)n.createEl("p",{text:"\u5F53\u524D\u7B5B\u9009\u6761\u4EF6\u4E0B\u65E0\u6570\u636E",cls:"setting-item-description"});else{let v=i.path,x=i.extraArgs||[],k=n.createEl("div",{cls:"pf-maint-progress"});k.style.display="none";let y=k.createEl("div",{cls:"paperforge-progress-track"});y.style.cssText="flex:1;";let E=y.createEl("div",{cls:"paperforge-progress-seg done"}),w=y.createEl("div",{cls:"paperforge-progress-seg pending"}),D=k.createEl("span",{cls:"pf-maint-progress-text"}),T=k.createEl("span",{cls:"pf-maint-progress-key"}),I=k.createEl("button",{text:o("maintenance_stop")||"Stop"});I.className="mod-warning",I.addEventListener("click",()=>{let P=this.plugin._ocrProcess;P&&(P.stdin&&typeof P.stdin.write=="function"?P.stdin.write(`PAPERFORGE_STOP
|
|
`):typeof P.kill=="function"&&P.kill("SIGINT")),this.plugin._ocrWasStopped=!0,I.disabled=!0,I.textContent=(o("maintenance_stop")||"Stop")+"\u2026"});let B=()=>{let P=this.plugin._ocrProgress;if(!P||P.total===0||!this.plugin._ocrProcess){k.style.display="none";return}k.style.display="flex";let X=P.total>0?(P.current/P.total*100).toFixed(1):"0";E.style.width=`${X}%`,E.style.minWidth=P.current>0?"2px":"0",P.current<P.total?(w.style.display="",w.style.flex="1"):w.style.display="none",D.textContent=(o("maintenance_progress_label")||"{current}/{total} papers").replace("{current}",String(P.current)).replace("{total}",String(P.total)),T.textContent=P.key?` (${P.key})`:""};B();let $=new Map;for(let P of h)$.set(P.key,!1);let V=n.createEl("div",{cls:"pf-maint-table-wrap"}),A=V.createEl("table",{cls:"pf-maint-table"}),S=A.createEl("thead"),N=A.createEl("tbody"),q=S.insertRow();["","Paper","Status Reason","Actions"].forEach(P=>{let X=document.createElement("th");X.textContent=P,q.appendChild(X)});let j=c();for(let P of h){let X=N.insertRow(),C=X.insertCell();C.style.cssText="padding:3px 4px;text-align:center;width:24px;";let L=document.createElement("input");L.type="checkbox",L.className="pf-maint-sel",L.checked=$.get(P.key)||!1,L.addEventListener("change",()=>{$.set(P.key,L.checked),Q()}),C.appendChild(L);let re=X.insertCell();re.style.cssText="padding:3px 4px;";let R=re.createEl("div",{cls:"pf-maint-paper-info"});R.createEl("div",{cls:"pf-maint-paper-title",text:P.title||P.key}),R.createEl("div",{cls:"pf-maint-paper-key",text:P.key});let ne=X.insertCell();ne.style.cssText="padding:3px 4px;",ne.createEl("div",{cls:"pf-maint-reason",text:P.display_reason||""});let de=X.insertCell();de.style.cssText="padding:3px 4px;white-space:nowrap;";let be=de.createEl("div",{cls:"pf-maint-actions"}),De=ht(P);if(De==="rebuild"){let oe=be.createEl("button",{cls:"pf-maint-action-btn rebuild",text:o("maintenance_btn_rebuild")||"Rebuild"});j&&(oe.disabled=!0),oe.addEventListener("click",()=>{(0,G.execFile)(v,[...x,"-m","paperforge","ocr","rebuild",P.key],{cwd:r,timeout:12e4,windowsHide:!0},()=>{new F.Notice((o("maintenance_btn_rebuild")||"Rebuild")+" \u2014 "+P.key)})})}else if(De==="redo"){let oe=be.createEl("button",{cls:"pf-maint-action-btn redo",text:o("ocr_maint_redo_btn")||"Redo"});j&&(oe.disabled=!0),oe.addEventListener("click",()=>{gt("redo")&&!confirm((o("ocr_maint_redo_confirm")||"Rerun OCR for {n} paper(s)? Existing derived OCR artifacts will be replaced.").replace("{n}","1"))||(0,G.execFile)(v,[...x,"-m","paperforge","ocr","redo",P.key],{cwd:r,timeout:3e5,windowsHide:!0},()=>{new F.Notice((o("ocr_maint_redo_btn")||"Redo OCR")+" \u2014 "+P.key)})})}}let O=n.createEl("div",{cls:"pf-maint-batch-bar"}),se=O.createEl("span",{cls:"pf-maint-batch-label",text:"0 selected"}),Q=()=>{let P=h.filter(X=>$.get(X.key)).length;se.textContent=P+" selected"},ce=O.createEl("button",{cls:"mod-cta",text:o("maintenance_batch_rebuild")||"\u25B6 Rebuild selected"});ce.disabled=j;let ee=O.createEl("button",{cls:"mod-cta",text:o("maintenance_batch_redo")||"\u25B6 Full OCR redo selected"});ee.disabled=j;let Z=P=>{let X=h.filter(R=>$.get(R.key)&&ht(R)===P);if(X.length===0){let R=P==="rebuild"?o("maintenance_btn_rebuild")||"Rebuild":o("ocr_maint_redo_btn")||"Redo";new F.Notice("Selected papers are not eligible for "+R+". Uncheck ineligible rows and try again.",6e3);return}if(gt(P)&&!confirm((o("ocr_maint_redo_confirm")||"Rerun OCR for {n} paper(s)? Existing derived OCR artifacts will be replaced.").replace("{n}",String(X.length))))return;let C=X.map(R=>R.key);this.plugin._ocrProgress={current:0,total:C.length,key:""},this.plugin._ocrBuffer="",this.plugin._ocrWasStopped=!1;let L=P==="rebuild"?"OCR_REBUILD":"OCR_REDO";ce.disabled=!0,ee.disabled=!0,Array.from(V.querySelectorAll(".pf-maint-action-btn")).forEach(R=>{R.disabled=!0}),Array.from(V.querySelectorAll(".pf-maint-sel")).forEach(R=>{R.disabled=!0}),m.disabled=!0,b.disabled=!0,I.disabled=!1,I.textContent=o("maintenance_stop")||"Stop";let re=this._callPython(["ocr",P,...C],{stream:!0,onData:R=>{var De;let ne=typeof R=="string"?R:Buffer.isBuffer(R)?R.toString("utf-8"):String(R),{events:de,buffer:be}=yt(ne,(De=this.plugin._ocrBuffer)!=null?De:"");this.plugin._ocrBuffer=be;for(let oe of de)oe.event==="START"?this.plugin._ocrProgress&&(this.plugin._ocrProgress.total=oe.total||C.length):oe.event==="PROGRESS"&&(this.plugin._ocrProgress={current:oe.current||0,total:oe.total||C.length,key:oe.key||""});B()},onError:R=>{this.plugin._ocrProcess=null,new F.Notice("Batch error: "+(R.message||R)),l(f)},onClose:R=>{this.plugin._ocrWasStopped||R===130?(this.plugin._ocrWasStopped=!1,this.plugin._ocrProcess=null,B(),new F.Notice("OCR batch stopped by user.")):R===0?(this.plugin._ocrProgress&&(this.plugin._ocrProgress.current=this.plugin._ocrProgress.total),this.plugin._ocrProcess=null,B(),new F.Notice((o("maintenance_batch_complete")||"Batch operation complete \u2014 {n} papers processed.").replace("{n}",String(C.length)))):(this.plugin._ocrProcess=null,B(),new F.Notice("Batch operation finished with exit code "+R+".",8e3)),mt(r,v,x,s).then(ne=>{s=Ge(r),l(ne.data)}).catch(()=>{l(u)})}});this.plugin._ocrProcess=re,B()};ce.addEventListener("click",()=>Z("rebuild")),ee.addEventListener("click",()=>Z("redo")),Q()}};if(s){let f=Object.values(s.papers);l(f)}else n.createEl("p",{text:"\u6B63\u5728\u52A0\u8F7D OCR \u7EF4\u62A4\u6570\u636E\u2026"});mt(r,i.path,i.extraArgs||[],s||null).then(f=>{s=Ge(r),(f.changed||!s)&&l(f.data)}).catch(()=>{s||(n.empty(),n.createEl("p",{text:"\u65E0\u6CD5\u52A0\u8F7D OCR \u6570\u636E\u3002\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 paperforge \u5E76\u8FD0\u884C\u8FC7 OCR\u3002",cls:"setting-item-description"}))})}_renderReleaseNotesTab(e){e.createEl("h2",{text:"\u66F4\u65B0\u4E0E\u624B\u518C"}),e.createEl("h3",{text:"\u7248\u672C\u66F4\u65B0\u8BB0\u5F55"});let t=Vt.default.versions||[];for(let a of t){let s=e.createEl("div",{cls:"paperforge-release-card"}),i=s.createEl("div",{cls:"paperforge-release-header"});if(i.createEl("strong",{text:`v${a.version} \u2014 ${a.title}`}),i.createEl("span",{cls:"paperforge-release-date",text:` (${a.date})`}),a.breaking_or_migration&&a.breaking_or_migration.length>0){let c=s.createEl("div",{cls:"paperforge-release-section"});c.createEl("div",{cls:"paperforge-release-label",text:"\u884C\u4E3A\u53D8\u66F4 / \u8FC1\u79FB\u6CE8\u610F"});for(let l of a.breaking_or_migration)c.createEl("div",{cls:"paperforge-release-item",text:`\u2022 ${l}`})}if(a.new_features&&a.new_features.length>0){let c=s.createEl("div",{cls:"paperforge-release-section"});c.createEl("div",{cls:"paperforge-release-label",text:"\u65B0\u529F\u80FD"});for(let l of a.new_features)c.createEl("div",{cls:"paperforge-release-item",text:`\u2022 ${l}`})}if(a.fixes&&a.fixes.length>0){let c=s.createEl("div",{cls:"paperforge-release-section"});c.createEl("div",{cls:"paperforge-release-label",text:"\u4FEE\u590D"});for(let l of a.fixes)c.createEl("div",{cls:"paperforge-release-item",text:`\u2022 ${l}`})}if(a.recommended_actions&&a.recommended_actions.length>0){let c=s.createEl("div",{cls:"paperforge-release-section paperforge-release-recommended"});c.createEl("div",{cls:"paperforge-release-label",text:"\u5EFA\u8BAE\u64CD\u4F5C"});for(let l of a.recommended_actions)c.createEl("div",{cls:"paperforge-release-item paperforge-release-item-bold",text:`\u2022 ${l}`})}}e.createEl("h3",{text:"\u4F7F\u7528\u624B\u518C"}),e.createEl("div",{cls:"paperforge-manual-links"}).createEl("a",{text:"\u2192 \u67E5\u770B\u5B8C\u6574\u4F7F\u7528\u624B\u518C\uFF08GitHub\uFF09",href:"https://github.com/LLLin000/PaperForge/blob/master/docs/user-manual.md"}).setAttr("target","_blank")}_initCapabilityState(){let e=this.plugin.settings.capabilityState;this._capabilityState=St(e!=null?e:{},Se),this._persistCapabilityState()}_persistCapabilityState(){this._capabilityState&&(this.plugin.settings.capabilityState=this._capabilityState,this.plugin.saveSettings())}_probeModule(e){var i,c,l,_;if(this._probing.has(e))return;this._probing.add(e);let t=(i=this._capabilityState)==null?void 0:i[e],r={schema_version:1,module:e,capability_state:(c=t==null?void 0:t.capability_state)!=null?c:"unknown",activity_state:"running",activity_label:"Probing...",activity_progress:null,severity:"unknown",reason:{code:`${e}.probing`,text:`Checking ${e} status...`},action:{primary:Le(e)},notices:(l=t==null?void 0:t.notices)!=null?l:[],updated_at:new Date().toISOString(),ttl_seconds:(_=t==null?void 0:t.ttl_seconds)!=null?_:0};this._updateCapabilityEnvelope(e,r);let n=this.app.vault.adapter.basePath,a=he(n,this.plugin.settings);if(!a.path){this._probing.delete(e),this._updateCapabilityEnvelope(e,Pe(e));return}let s=[...a.extraArgs,"-m","paperforge","--vault",n,"probe",e,"--json"];(0,G.execFile)(a.path,s,{cwd:n,timeout:15e3},(f,u,g)=>{if(this._probing.delete(e),f){console.warn(`[PaperForge] Probe ${e} failed:`,f.message),this._updateCapabilityEnvelope(e,Pe(e));return}try{let m=JSON.parse(u);tt(m,e)?this._updateCapabilityEnvelope(e,m):(console.warn(`[PaperForge] Probe ${e}: invalid envelope schema`,u==null?void 0:u.slice(0,200)),this._updateCapabilityEnvelope(e,Pe(e)))}catch(m){console.warn(`[PaperForge] Probe ${e}: unparseable JSON`,u==null?void 0:u.slice(0,200)),this._updateCapabilityEnvelope(e,Pe(e))}})}_updateCapabilityEnvelope(e,t){this._capabilityState||(this._capabilityState={});let r=this._capabilityState[t.module];this._capabilityState[t.module]=t,this._persistCapabilityState(),(r==null?void 0:r.activity_state)==="running"&&t.activity_state!=="running"&&new F.Notice(o("cc_notice_refreshed"),3e3),this.display()}_ccBadgeKey(e,t){return e.severity==="ok"?"cc_badge_ok":e.severity==="error"&&t==="installation"?"cc_badge_setup":e.severity==="warning"||e.severity==="error"?"cc_badge_attention":"cc_badge_pending"}_sevClass(e){return e==="error"?"error":e==="warning"?"warn":e==="unknown"?"unknown":"ok"}_localizeReason(e,t){let r="cc_reason_"+e.replace(/\./g,"_"),n=o(r);if(n!==r)return n.replace("{module}",t);let s="cc_reason_"+e.replace(/^[a-z]+\./,""),i=o(s);return i===s?null:i.replace("{module}",t)}_renderCard(e,t,r){let n=r,a=this._sevClass(n.severity),s=Ne._REAL_PROBE.has(t),i=e.createEl("div",{cls:"pf-cc-card",attr:{role:"listitem",tabindex:"0","aria-label":`${o("cc_module_"+t)} \u2014 ${o(this._ccBadgeKey(n,t))}`}}),c=i.createEl("div",{cls:"pf-cc-card-header"});c.createEl("div",{cls:"pf-cc-card-name",text:o("cc_module_"+t)}),c.createEl("div",{cls:`pf-cc-card-badge pf-cc-card-badge--${a}`,text:o(this._ccBadgeKey(n,t))});let l;if(!s)l=o("cc_reason_placeholder").replace("{module}",o("cc_module_"+t));else{let k=this._localizeReason(n.reason.code,t);l=k!=null?k:n.reason.text}if(i.createEl("div",{cls:"pf-cc-card-reason",text:l}),n.activity_state==="running"&&n.activity_label){let k=i.createEl("div",{cls:"pf-cc-card-activity",attr:{"aria-live":"polite"}});if(k.createEl("span",{text:n.activity_label}),n.activity_progress&&n.activity_progress.total>0){let y=Math.round(n.activity_progress.current/n.activity_progress.total*100),w=k.createEl("div",{cls:"pf-cc-card-progress",attr:{role:"progressbar","aria-valuenow":String(n.activity_progress.current),"aria-valuemin":"0","aria-valuemax":String(n.activity_progress.total)}}).createEl("div",{cls:"pf-cc-card-progress-fill"});w.style.width=y+"%"}}let _=i.createEl("div",{cls:"pf-cc-card-footer"});if(s&&n.action.primary&&!kt(n)){let k=wt(n),E=k.kind==="setup"?"pf-cc-card-action pf-cc-card-action--primary":"pf-cc-card-action";_.createEl("button",{cls:E,text:k.label,attr:{"aria-label":k.label}}).addEventListener("click",()=>{k.kind==="setup"?new qe(this.app,this.plugin,()=>{this._probeModule("installation"),this._probeModule("help")}).open():this._probeModule(t)})}let f=i.createEl("details",{cls:"pf-cc-card-diagnostic"});f.createEl("summary",{text:o("cc_diagnostic_toggle")});let u=f.createEl("div",{cls:"pf-cc-card-diagnostic-body"}),g=o("cc_state_"+n.capability_state)||n.capability_state,m=o("cc_severity_"+n.severity)||n.severity,b=o("cc_activity_"+n.activity_state)||n.activity_state,h;try{h=new Date(n.updated_at).toLocaleString()}catch(k){h=n.updated_at}u.createEl("div",{text:`${o("cc_diag_module")}: ${n.module}`}),u.createEl("div",{text:`${o("cc_diag_state")}: ${g}`}),u.createEl("div",{text:`${o("cc_diag_severity")}: ${m}`}),u.createEl("div",{text:`${o("cc_diag_activity")}: ${b}`});let v=u.createEl("div");v.appendText(o("cc_diag_reason")+": "+l+" ");let x=v.createEl("code",{text:n.reason.code});u.createEl("div",{text:`${o("cc_diag_ttl")}: ${String(n.ttl_seconds)}s`}),u.createEl("div",{text:`${o("cc_diag_updated")}: ${h}`})}_renderControlCenter(e){var g,m,b;let t=e.createEl("div",{cls:"pf-control-center"}),r=Se,n=(g=this._capabilityState)!=null?g:{},a=0,s=0,i=0;for(let h of r){let v=(m=n[h])!=null?m:He(h);v.severity==="ok"&&v.capability_state==="ready"&&v.action.primary===null?a++:Ne._REAL_PROBE.has(h)?(v.severity==="error"||v.severity==="warning"||v.severity==="unknown")&&s++:i++}let c=t.createEl("div",{cls:"pf-cc-summary"});c.createEl("div",{cls:"pf-cc-summary-eyebrow",text:o("cc_title")});let l,_;s>0?(l=o("cc_summary_attention"),_=o("cc_summary_attention_body")):a===r.length?(l=o("cc_summary_ok"),_=o("cc_summary_ok_body")):a>0&&i>0&&s===0?(l=o("cc_summary_core_ok").replace("{n}",String(i)),_=o("cc_summary_core_ok_body")):(l=o("cc_summary_core_ok").replace("{n}",String(r.length-a)),_=o("cc_desc")),c.createEl("div",{cls:"pf-cc-summary-title",text:l}),c.createEl("div",{cls:"pf-cc-summary-body",text:_});let f=c.createEl("div",{cls:"pf-cc-summary-counts"});f.createEl("div",{cls:"pf-cc-summary-count",text:o("cc_n_ready").replace("{n}",String(a))}),i>0&&f.createEl("div",{cls:"pf-cc-summary-count",text:o("cc_n_pending").replace("{n}",String(i))});let u=t.createEl("div",{cls:"pf-cc-grid",attr:{role:"list","aria-label":o("cc_zone_modules")}});for(let h of r){let v=(b=n[h])!=null?b:He(h);this._renderCard(u,h,v)}}_applyStaleTolerance(){if(!this._capabilityState)return;let e=!1;for(let t of Se){let r=this._capabilityState[t];r&&nt(r)&&(this._capabilityState[t]=rt(t),e=!0)}e&&this._persistCapabilityState()}};Ne._REAL_PROBE=new Set(["installation","help"]);var Ye=Ne;var M=require("obsidian"),ye=H(require("fs")),ze=H(require("path")),ve=require("child_process");var $e=H(require("path"));function Ht(p){if(!p)return null;let d=$e.dirname(p);for(;;){let e=$e.basename(d);if(!e||e===".")break;let t=e.match(/^([A-Z0-9]{8})(?:\s*-\s*.*)?$/i);if(t)return t[1];let r=$e.dirname(d);if(r===d)break;d=r}return null}var J=H(require("fs")),xe=H(require("path"));function je(p){return le(p).ocrDir}function ur(p,d){let e=xe.join(je(p),d,"versions","manifest.json");try{if(!J.existsSync(e))return null;let t=J.readFileSync(e,"utf-8"),r=JSON.parse(t);if(r&&typeof r=="object"&&"versions"in r&&"current"in r){let n=r,a=n.versions,s=n.current;if(Array.isArray(a)&&s&&typeof s=="object"&&"label"in s)return r}return null}catch(t){return null}}function _r(p){let d=je(p);try{return J.existsSync(d)?J.readdirSync(d,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name):[]}catch(e){return[]}}function vt(p){let d=_r(p),e=[];for(let t of d){let r=ur(p,t);if(!r)continue;let n=r.versions.map(s=>s.label),a=0;for(let s of n){let i=xe.join(je(p),t,"versions",s,"fulltext.md");try{J.existsSync(i)&&(a+=J.statSync(i).size)}catch(c){}}e.push({key:t,title:t.replace(/_/g," "),versions:r.versions,currentLabel:r.current.label,totalSize:a})}return e.sort((t,r)=>t.title.localeCompare(r.title)),e}function Wt(p,d,e){let t=je(p),r=xe.join(t,d,"versions",e,"fulltext.md"),n=xe.join(t,d,"render"),a=xe.join(n,"fulltext.md");try{return J.existsSync(r)?(J.existsSync(n)||J.mkdirSync(n,{recursive:!0}),J.copyFileSync(r,a),!0):!1}catch(s){return!1}}function Ut(p,d,e,t){var u;let r=je(p),n=xe.join(r,d,"versions",e,"fulltext.md"),a=xe.join(r,d,"versions",t,"fulltext.md"),s="",i="";try{J.existsSync(n)&&(s=J.readFileSync(n,"utf-8"))}catch(g){}try{J.existsSync(a)&&(i=J.readFileSync(a,"utf-8"))}catch(g){}let c=Kt(s),l=Kt(i),_=Math.max(c.length,l.length),f=[];for(let g=0;g<_;g++){let m=g<c.length?c[g]:"",b=g<l.length?l[g]:"",h=(u=(m||b).split(`
|
|
`)[0])!=null?u:"",v=h.startsWith("## ")?h.replace(/^##\s+/,""):"",x="unchanged";!m&&b?x="added":m&&!b?x="removed":m!==b&&(x="changed"),x!=="unchanged"&&f.push({paragraphIndex:g,heading:v,type:x,oldText:m||void 0,newText:b||void 0})}return f}function Kt(p){let d=p.split(`
|
|
`),e=[],t=[];for(let r of d)if(r.startsWith("## ")&&t.length>0)e.push(t.join(`
|
|
`).trim()),t=[r];else if(r.trim()===""&&t.length>0){let n=t.join(`
|
|
`).trim();n&&(e.push(n),t=[])}else t.push(r);if(t.length>0){let r=t.join(`
|
|
`).trim();r&&e.push(r)}return e}var Te=class extends M.ItemView{constructor(e){super(e);this._currentMode=null;this._currentDomain=null;this._currentPaperKey=null;this._currentPaperEntry=null;this._currentFilePath=null;this._cachedItems=null;this._modeSubscribers=[];this._leafChangeTimer=null;this._ocrPrivacyShown=!1;this._cachedStats=null;this._techDetailsExpanded=!1;this._paperforgeVersion="";this._dashboardPermissions={};this._headerTitle=null;this._versionBadge=null;this._messageEl=null;this._metricsEl=null;this._ocrSection=null;this._ocrEmpty=null;this._ocrBadge=null;this._ocrTrack=null;this._ocrCounts=null;this._driftBannerEl=null;this._versionPapers=null;this._versionFilter="";this._searchContainer=null;this._searchInput=null;this._searchResultsEl=null;this._searchTimer=void 0;this._searchState="idle";this._searchMode="M";this._searchResults=null;this._searchActiveIndex=-1;this._onKeyDown=null;this._currentMode=null,this._currentDomain=null,this._currentPaperKey=null,this._currentPaperEntry=null,this._currentFilePath=null,this._cachedItems=null,this._modeSubscribers=[],this._leafChangeTimer=null,this._ocrPrivacyShown=!1}getViewType(){return ke}getDisplayText(){return"PaperForge"}getIcon(){return Be}async onOpen(){this._buildPanel(),this._modeSubscribers=[],this._leafChangeTimer=null,this._setupEventSubscriptions(),this._fetchVersion(),this._detectAndSwitch(),this._onKeyDown=e=>{var t,r,n;if(e.key==="/"&&!e.ctrlKey&&!e.metaKey&&!e.altKey){let a=(r=(t=e.target)==null?void 0:t.tagName)==null?void 0:r.toLowerCase();a!=="input"&&a!=="textarea"&&(e.preventDefault(),(n=this._searchInput)==null||n.focus())}},document.addEventListener("keydown",this._onKeyDown)}async onClose(){if(this._modeSubscribers&&this._modeSubscribers.length>0){for(let e of this._modeSubscribers)e.event==="active-leaf-change"?this.app.workspace.off("active-leaf-change",e.ref):e.event==="modify"&&this.app.vault.off("modify",e.ref);this._modeSubscribers=[]}this._leafChangeTimer&&(clearTimeout(this._leafChangeTimer),this._leafChangeTimer=null),this._onKeyDown&&(document.removeEventListener("keydown",this._onKeyDown),this._onKeyDown=null),this._searchState="idle",this._searchResults=null,this._searchActiveIndex=-1,this._searchTimer=void 0,this._cachedItems=null,this._cachedStats=null}_buildPanel(){let e=this.containerEl;e.empty(),e.addClass("paperforge-status-panel");let t=e.createEl("div",{cls:"paperforge-header"}),r=t.createEl("div",{cls:"paperforge-header-left"});r.createEl("div",{cls:"paperforge-header-logo",text:"P"}),this._modeContextEl=r.createEl("div",{cls:"paperforge-mode-context"}),this._headerTitle=r.createEl("h3",{cls:"paperforge-header-title",text:"PaperForge"}),this._versionBadge=r.createEl("span",{cls:"paperforge-header-badge",text:"v\u2014"});let n=t.createEl("button",{cls:"paperforge-header-refresh",attr:{"aria-label":"Refresh"}});n.innerHTML="\u21BB",n.addEventListener("click",()=>{this._invalidateIndex(),this._detectAndSwitch()}),this._messageEl=e.createEl("div",{cls:"paperforge-message",attr:{"aria-live":"polite"}}),this._contentEl=e.createEl("div",{cls:"paperforge-content-area"})}_fetchVersion(){var s,i;let e=this.app.vault.adapter.basePath,t=this.app.plugins.plugins.paperforge,r=((s=t==null?void 0:t.manifest)==null?void 0:s.version)||"?",{path:n,extraArgs:a=[]}=z(e,(i=t==null?void 0:t.settings)!=null?i:null,void 0,void 0);Ft(n,r,e,1e4,void 0).then(c=>{if(c.status==="not-installed")return;let l=c.pyVersion||"";this._paperforgeVersion=l.startsWith("v")?l:"v"+l,this._versionBadge&&this._versionBadge.setText(this._paperforgeVersion),this._driftBannerEl&&r&&this._paperforgeVersion!=="v"+r.replace(/^v/,"")?(this._driftBannerEl.style.display="block",this._driftBannerEl.setText(o("dashboard_drift_warning").replace("{0}",this._paperforgeVersion).replace("{1}","v"+r.replace(/^v/,"")))):this._driftBannerEl&&(this._driftBannerEl.style.display="none")})}_fetchStats(e){var s;if(!this._metricsEl)return;if(!e&&!this._cachedStats)this._metricsEl.empty(),this._metricsEl.createEl("div",{cls:"paperforge-status-loading",text:"Loading..."});else if(e&&!this._cachedStats)return;let t=this.app.vault.adapter.basePath,r=this.app.plugins.plugins.paperforge,{path:n,extraArgs:a=[]}=z(t,(s=r==null?void 0:r.settings)!=null?s:null,void 0,void 0);(0,ve.execFile)(n,[...a,"-m","paperforge","dashboard","--json"],{cwd:t,timeout:3e4},(i,c)=>{if(!i)try{let l=JSON.parse(c);if(l.ok&&l.data){let _=this._normalizeDashboardData(l.data);this._cachedStats=_,this._metricsEl.empty(),this._renderStats(_),this._renderOcr(_),this._dashboardPermissions=l.data.permissions||{};return}}catch(l){}this._fallbackFetchStats(e,t,r)})}_normalizeDashboardData(e){let t=e.stats||{},r=t.ocr_health||{},n=t.pdf_health||{},a=e.ocr_version_state||{},s=(r.done||0)+(r.pending||0)+(r.failed||0);return{total_papers:t.papers||0,formal_notes:t.papers||0,exports:0,bases:0,ocr:{total:s,pending:r.pending||0,processing:0,done:r.done||0,failed:r.failed||0},path_errors:(n.broken||0)+(n.missing||0),ocr_version_state:{total_papers:a.total_papers||0,derived_stale_count:a.derived_stale_count||0,raw_upgradable_count:a.raw_upgradable_count||0}}}_fallbackFetchStats(e,t,r){var s,i,c;let n=((s=r==null?void 0:r.settings)==null?void 0:s.system_dir)||"System",a=ze.join(t,n,"PaperForge","indexes","formal-library.json");try{let l=ye.readFileSync(a,"utf-8"),_=JSON.parse(l),f=_.items||[],u={},g={pdf_health:{healthy:0,unhealthy:0},ocr_health:{healthy:0,unhealthy:0},note_health:{healthy:0,unhealthy:0},asset_health:{healthy:0,unhealthy:0}},m=0,b=0,h=0,v=0,x=0,k=0;for(let y of f){y.note_path&&k++;let E=y.lifecycle||"pdf_ready";u[E]=(u[E]||0)+1;let w=y.health||{};for(let T of["pdf_health","ocr_health","note_health","asset_health"])(w[T]||"healthy")==="healthy"?g[T].healthy++:g[T].unhealthy++;let D=y.ocr_status||"";m++,D==="done"?b++:D==="pending"?h++:D==="processing"||D==="queued"||D==="running"?v++:x++}this._cachedStats={version:_.paperforge_version||((i=this._cachedStats)==null?void 0:i.version)||"\u2014",total_papers:f.length,formal_notes:k,exports:0,bases:0,ocr:{total:m,pending:h,processing:v,done:b,failed:x},path_errors:0,lifecycle_level_counts:u,health_aggregate:g},this._metricsEl.empty(),this._renderStats(this._cachedStats),this._renderOcr(this._cachedStats)}catch(l){!e&&!this._cachedStats&&this._metricsEl.createEl("div",{cls:"paperforge-status-loading",text:"No index \u2014 trying CLI..."});let{path:_,extraArgs:f=[]}=z(t,(c=r==null?void 0:r.settings)!=null?c:null,void 0,void 0);(0,ve.execFile)(_,[...f,"-m","paperforge","status","--json"],{cwd:t,timeout:3e4},(u,g)=>{if(u){if(this._cachedStats)return;this._metricsEl.createEl("div",{cls:"paperforge-status-error",text:`Cannot reach PaperForge CLI.
|
|
Make sure paperforge is installed and in your PATH.`});return}try{let m=JSON.parse(g);this._cachedStats=m,this._metricsEl.empty(),this._renderStats(m),this._renderOcr(m)}catch(m){this._cachedStats||this._metricsEl.createEl("div",{cls:"paperforge-status-error",text:"Invalid response from paperforge status."})}})}}_renderSkeleton(e){e.addClass("paperforge-loading")}_renderEmptyState(e,t){e.createEl("div",{cls:"paperforge-empty-state",text:t||"No data"})}_buildMetricBar(e,t,r){if(r<=0)return;let n=Math.min(100,t/r*100);e.createEl("div",{cls:"paperforge-metric-progress"}).createEl("div",{cls:"paperforge-metric-progress-fill",attr:{style:`width:${n.toFixed(1)}%`}})}_loadIndex(){var a;let e=this.app.vault.adapter.basePath,t=this.app.plugins.plugins.paperforge,r=((a=t==null?void 0:t.settings)==null?void 0:a.system_dir)||"System",n=ze.join(e,r,"PaperForge","indexes","formal-library.json");try{let s=ye.readFileSync(n,"utf-8");return JSON.parse(s)}catch(s){return null}}_getCachedIndex(){if(!this._cachedItems){let e=this._loadIndex();this._cachedItems=e?e.items||[]:[]}return this._cachedItems}_findEntry(e){if(!e)return null;let t=this._getCachedIndex().find(r=>r.zotero_key===e)||null;return xt(this.app,t)}_patchCachedEntry(e,t){if(!e||!this._cachedItems)return;let r=this._cachedItems.findIndex(n=>n.zotero_key===e);r!==-1&&(this._cachedItems[r]=Qe(this._cachedItems[r],t))}_filterByDomain(e){return e?this._getCachedIndex().filter(t=>t.domain===e):[]}_renderStats(e){var s;if(this._versionBadge&&this._versionBadge.setText(this._paperforgeVersion||(e.version?"v"+e.version:"v\u2014")),!e||typeof e.total_papers=="undefined"){this._metricsEl&&this._renderSkeleton(this._metricsEl);return}if(!this._metricsEl)return;this._metricsEl.removeClass("paperforge-loading");let t=e.total_papers||0,r=e.formal_notes||0,n=[{value:t,label:"Papers",color:"var(--color-cyan)",barMax:0},{value:r,label:"Formal Notes",color:"var(--color-blue)",barMax:t},{value:e.exports||0,label:"Exports",color:"var(--color-purple)",barMax:0}];for(let i of n){let c=this._metricsEl.createEl("div",{cls:"paperforge-metric-card"});c.style.setProperty("--metric-color",i.color),c.createEl("div",{cls:"paperforge-metric-value",text:((s=i.value)==null?void 0:s.toString())||"\u2014"}),c.createEl("div",{cls:"paperforge-metric-label",text:i.label}),i.barMax>0&&this._buildMetricBar(c,i.value,i.barMax)}let a=e.ocr_version_state||{};if(a.total_papers>0&&(a.derived_stale_count>0||a.raw_upgradable_count>0)){let i=[];a.derived_stale_count>0&&i.push(`${a.derived_stale_count} stale`),a.raw_upgradable_count>0&&i.push(`${a.raw_upgradable_count} upgradable`);let c=this._metricsEl.createEl("div",{cls:"paperforge-metric-card"});c.style.setProperty("--metric-color","var(--color-yellow)"),c.createEl("div",{cls:"paperforge-metric-value",text:i.join(", ")}),c.createEl("div",{cls:"paperforge-metric-label",text:"OCR Version"})}}_renderOcr(e){if(!this._ocrSection)return;let t=e.ocr||{},r=t.total||0;if(r===0){this._ocrSection.style.display="none";return}this._ocrSection.style.display="block",this._ocrEmpty&&(this._ocrEmpty.style.display="none");let n=t.done||0,a=t.pending||0,s=t.processing||0,i=t.failed||0;if(this._ocrBadge&&(this._ocrBadge.removeClass("active","idle"),s>0?(this._ocrBadge.addClass("active"),this._ocrBadge.setText("Processing")):a>0?(this._ocrBadge.addClass("idle"),this._ocrBadge.setText("Pending")):(this._ocrBadge.addClass("idle"),this._ocrBadge.setText("Idle"))),this._ocrTrack){this._ocrTrack.empty(),s>0?this._ocrTrack.addClass("paperforge-processing"):this._ocrTrack.removeClass("paperforge-processing");let c=[{cls:"pending",count:a},{cls:"active",count:s},{cls:"done",count:n},{cls:"failed",count:i}];for(let l of c)if(l.count>0){let _=(l.count/r*100).toFixed(1);this._ocrTrack.createEl("div",{cls:`paperforge-progress-seg ${l.cls}`,attr:{style:`width:${_}%`}})}}if(this._ocrCounts){this._ocrCounts.empty();let c=[{cls:"pending",value:a,label:"Pending"},{cls:"active",value:s,label:"Processing"},{cls:"done",value:n,label:"Done"},{cls:"failed",value:i,label:"Failed"}];for(let l of c){let _=this._ocrCounts.createEl("div",{cls:"paperforge-ocr-count"});_.createEl("div",{cls:"paperforge-ocr-count-value",text:l.value.toString()}),_.createEl("div",{cls:"paperforge-ocr-count-label",text:l.label})}}}_renderLifecycleStepper(e,t,r){if(!t||!r){this._renderSkeleton(e);return}let n=[{key:"indexed",label:"Indexed"},{key:"pdf_ready",label:"PDF Ready"},{key:"fulltext_ready",label:"Fulltext Ready"},{key:"deep_read_done",label:"Deep Read"}],a=e.createEl("div",{cls:"paperforge-lifecycle-stepper"}),s=!1;for(let i of n){let c=a.createEl("div",{cls:"step"});c.createEl("div",{cls:"step-indicator"}),c.createEl("div",{cls:"step-label",text:i.label}),i.key===r?(c.addClass("current"),s=!0):s?c.addClass("pending"):c.addClass("completed")}}_renderHealthMatrix(e,t){if(!t){this._renderSkeleton(e);return}let r=[{key:"pdf_health",label:"PDF Health",iconOk:"\u2713",iconWarn:"\u26A0",iconFail:"\u2717"},{key:"ocr_health",label:"OCR Health",iconOk:"\u2713",iconWarn:"\u26A0",iconFail:"\u2717"},{key:"note_health",label:"Note Health",iconOk:"\u2713",iconWarn:"\u26A0",iconFail:"\u2717"},{key:"asset_health",label:"Asset Health",iconOk:"\u2713",iconWarn:"\u26A0",iconFail:"\u2717"}],n=e.createEl("div",{cls:"paperforge-health-matrix"});for(let a of r){let s=t[a.key]||"healthy",i=n.createEl("div",{cls:"paperforge-health-cell"}),c,l,_;s==="healthy"||s==="ok"?(c=a.iconOk,l="ok",_=`${a.label}: OK`):s==="warn"||s==="warning"||s==="degraded"?(c=a.iconWarn,l="warn",_=`${a.label}: Needs Attention`):(c=a.iconFail,l="fail",_=`${a.label}: Failed`),i.addClass(l),i.setAttribute("title",_),i.createEl("div",{cls:"paperforge-health-cell-icon",text:c}),i.createEl("div",{cls:"paperforge-health-cell-label",text:a.label})}}_renderMaturityGauge(e,t,r){if(t==null||t===void 0){this._renderSkeleton(e);return}let n=e.createEl("div",{cls:"paperforge-maturity-gauge"}),a=n.createEl("div",{cls:"gauge-track"}),s=4,i=Math.max(1,Math.min(s,Math.round(t)));for(let c=1;c<=s;c++){let l=a.createEl("div",{cls:"gauge-segment"});c<=i&&(l.addClass("filled"),l.addClass(`level-${c}`))}if(n.createEl("div",{cls:"gauge-level",text:`Level ${i} / ${s}`}),i<s&&r){let c=typeof r=="string"?[r]:r;if(c.length>0){let l=n.createEl("ul",{cls:"gauge-blockers"});for(let _ of c)l.createEl("li",{text:_})}}}_renderBarChart(e,t){if(!t||Object.keys(t).length===0){this._renderEmptyState(e,"No lifecycle data");return}let r=[{key:"indexed",label:"Indexed",cls:"stage-indexed"},{key:"pdf_ready",label:"PDF Ready",cls:"stage-pdf-ready"},{key:"fulltext_ready",label:"Fulltext Ready",cls:"stage-fulltext-ready"},{key:"deep_read_done",label:"Deep Read",cls:"stage-deep-read"}],n=e.createEl("div",{cls:"paperforge-bar-chart"}),a=Math.max(1,...r.map(s=>t[s.key]||0));for(let s of r){let i=t[s.key]||0,c=i/a*100,l=n.createEl("div",{cls:"bar-row"});l.createEl("div",{cls:"bar-label",text:s.label}),l.createEl("div",{cls:"bar-track"}).createEl("div",{cls:`bar-fill ${s.cls}`,attr:{style:`width:${c.toFixed(1)}%`}}),l.createEl("div",{cls:"bar-count",text:i.toString()})}}_invalidateIndex(){this._cachedItems=null}_extractZoteroKeyFromPath(e){return Ht(e)}_resolveModeForFile(e){if(!e)return{mode:"global",filePath:null,key:null,domain:null};let t=e.extension,r=e.path;if(t==="base")return{mode:"collection",filePath:r,key:null,domain:e.basename.trim()};if(t==="md"){let a=this.app.metadataCache.getFileCache(e),s=a&&a.frontmatter&&a.frontmatter.zotero_key;if(s)return{mode:"paper",filePath:r,key:s,domain:null}}if(t==="pdf"){let a=this._getCachedIndex();for(let s of a){let i=(s.pdf_path||"").match(/\[\[([^\]]+)\]\]/);if((i?i[1]:s.pdf_path)===r)return{mode:"paper",filePath:r,key:s.zotero_key,domain:null}}}let n=this._extractZoteroKeyFromPath(r);return n?{mode:"paper",filePath:r,key:n,domain:null}:{mode:"global",filePath:r,key:null,domain:null}}_detectAndSwitch(){let e=this._resolveModeForFile(this.app.workspace.getActiveFile());this._currentDomain=e.domain||null,this._currentPaperKey=e.key||null,this._currentPaperEntry=e.key?this._findEntry(e.key):null,this._switchMode(e.mode,e.filePath)}_switchMode(e,t){if(this._currentMode===e&&this._currentFilePath===t){this._refreshCurrentMode();return}if(this._currentMode=e,this._currentFilePath=t,this._techDetailsExpanded=!1,!!this._contentEl)switch(this._contentEl.empty(),this._contentEl.removeClass("switching"),this._renderModeHeader(e),e){case"global":this._renderGlobalMode();break;case"paper":this._renderPaperMode();break;case"collection":this._renderCollectionMode();break;case"versions":this._renderVersionMode();break}}_renderGlobalMode(){var se,Q,ce,ee,Z,P,X;if(!this._contentEl)return;let e=this._contentEl.createEl("div",{cls:"paperforge-global-view"});this._driftBannerEl=e.createEl("div",{cls:"paperforge-drift-banner"}),this._driftBannerEl.style.display="none";let t=this._getCachedIndex(),r=t.length,n=0,a=0,s=0;for(let C of t)C.has_pdf&&n++,C.ocr_status==="done"&&a++,C.deep_reading_status==="done"&&s++;let i=e.createEl("div",{cls:"paperforge-library-snapshot"});i.createEl("div",{cls:"paperforge-section-label",text:"Library Snapshot"});let c=i.createEl("div",{cls:"paperforge-snapshot-pills"}),l=[{value:r,label:"papers"},{value:n,label:"PDFs ready"},{value:a,label:"OCR done"},{value:s,label:"deep-read done"}];for(let C of l){let L=c.createEl("div",{cls:"paperforge-snapshot-pill"});L.createEl("span",{cls:"paperforge-snapshot-value",text:String(C.value)}),L.createEl("span",{cls:"paperforge-snapshot-label",text:" "+C.label})}let _=e.createEl("div",{cls:"paperforge-system-status"});_.createEl("div",{cls:"paperforge-section-label",text:"System Status"});let f=_.createEl("div",{cls:"paperforge-status-grid"}),u=this.app.plugins.plugins.paperforge,g=((se=u==null?void 0:u.manifest)==null?void 0:se.version)||"?",m=this._paperforgeVersion;if(!m)try{let C=this.app.vault.adapter.basePath,{path:L,extraArgs:re=[]}=z(C,(Q=u==null?void 0:u.settings)!=null?Q:null,void 0,void 0),R=(0,ve.execFileSync)(L,[...re,"-c","import paperforge; print(paperforge.__version__)"],{cwd:C,timeout:5e3,encoding:"utf-8",windowsHide:!0}).trim();R&&(m=R.startsWith("v")?R:"v"+R,this._paperforgeVersion=m)}catch(C){}m=m||"\u2014";let b=m==="v"+g;this._renderSystemStatusRow(f,"Runtime",b?"healthy":"mismatch",b?"v"+g:"plugin v"+g+" \u2260 CLI "+m);let h=this._loadIndex(),v=h&&h.items&&h.items.length>0;this._renderSystemStatusRow(f,"Index",v?"healthy":"missing",v?h.items.length+" entries":"formal-library.json not found");let x=((ce=u==null?void 0:u.settings)==null?void 0:ce.system_dir)||"System",k=this.app.vault.adapter.basePath,y=!1,E="No exports found";try{let C=ze.join(k,x,"PaperForge","exports");if(ye.existsSync(C)){let L=ye.readdirSync(C).filter(re=>re.endsWith(".json"));y=L.length>0,E=y?L.length+" export(s)":"No JSON exports"}}catch(C){}this._renderSystemStatusRow(f,"Zotero Export",y?"healthy":"missing",E);let w=!!((ee=u==null?void 0:u.settings)!=null&&ee.paddleocr_api_key);if(!w)try{let C=((Z=u==null?void 0:u.settings)==null?void 0:Z.system_dir)||"System",L=ze.join(k,C,"PaperForge",".env");if(ye.existsSync(L)){let R=ye.readFileSync(L,"utf-8").match(/^PADDLEOCR_API_TOKEN\s*=\s*(.+)$/m);w=!!(R&&R[1]&&R[1].trim())}}catch(C){}w||(w=!!(process.env.PADDLEOCR_API_TOKEN||process.env.PADDLEOCR_API_KEY||process.env.OCR_TOKEN)),this._renderSystemStatusRow(f,"OCR Token",w?"configured":"missing",w?"Configured":"Not set");let D=!1,T="",I=this.app.vault.adapter.basePath,B=Me(I);D=Bt(I),T=B&&((P=B.summary)==null?void 0:P.reason)||B&&((X=B.summary)==null?void 0:X.status)||"Unknown",this._renderSystemStatusRow(f,"Memory Layer",D?"healthy":"fail",T);let $=!b&&m!=="\u2014";if($||!v||!y||!w){let C=e.createEl("div",{cls:"paperforge-issue-summary"});C.createEl("div",{cls:"paperforge-section-label",text:"\u9700\u8981\u5904\u7406"});let L=C.createEl("div",{cls:"paperforge-issue-list"});$&&L.createEl("div",{cls:"paperforge-issue-item",text:"Runtime version mismatch"}),v||L.createEl("div",{cls:"paperforge-issue-item",text:"Index missing or corrupted"}),y||L.createEl("div",{cls:"paperforge-issue-item",text:"No Zotero export found"}),w||L.createEl("div",{cls:"paperforge-issue-item",text:"PaddleOCR API key not configured"});let re=C.createEl("div",{cls:"paperforge-issue-actions"}),R=re.createEl("button",{cls:"paperforge-contextual-btn"});R.createEl("span",{text:"Run Doctor"}),R.addEventListener("click",()=>{let de=ie.find(be=>be.id==="paperforge-doctor");de&&this._runAction(de,R)});let ne=re.createEl("button",{cls:"paperforge-contextual-btn"});ne.createEl("span",{text:"Repair Issues"}),ne.addEventListener("click",()=>{let de=ie.find(be=>be.id==="paperforge-repair");de&&this._runAction(de,ne)})}let A=e.createEl("div",{cls:"paperforge-global-actions"});A.createEl("div",{cls:"paperforge-section-label",text:"Start Working"});let S=A.createEl("div",{cls:"paperforge-global-actions-row"}),N=S.createEl("button",{cls:"paperforge-contextual-btn primary"});N.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u{1F4C1}"}),N.createEl("span",{text:"Open Literature Hub"}),N.addEventListener("click",()=>{var re;let C=((re=u==null?void 0:u.settings)==null?void 0:re.base_dir)||"Bases",L=this.app.vault.getAbstractFileByPath(C);if(L){let R=null;if(L.children&&(R=L.children.find(ne=>ne.extension==="base")),R){let ne=this.app.workspace.getLeaf(!1);ne&&ne.openFile(R)}else new M.Notice("[!!] No .base file found in "+C,6e3)}else new M.Notice("[!!] Base directory not found: "+C,6e3)});let q=S.createEl("button",{cls:"paperforge-contextual-btn"});q.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u21BB"}),q.createEl("span",{text:"Sync Library"}),q.addEventListener("click",()=>{let C=ie.find(L=>L.id==="paperforge-sync");C&&this._runAction(C,q)});let j=S.createEl("button",{cls:"paperforge-contextual-btn"});j.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u229E"}),j.createEl("span",{text:"Run OCR"}),j.addEventListener("click",()=>{let C=ie.find(L=>L.id==="paperforge-ocr");C&&this._runAction(C,j)});let O=S.createEl("button",{cls:"paperforge-contextual-btn warn"});O.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u21BA"}),O.createEl("span",{text:"Redo OCR"}),O.addEventListener("click",()=>{let C=ie.find(L=>L.id==="paperforge-ocr-redo");C&&this._runAction(C,O)})}_renderSystemStatusRow(e,t,r,n){let a=e.createEl("div",{cls:"paperforge-status-row"});a.createEl("span",{cls:"paperforge-status-dot"}).addClass(r==="healthy"||r==="configured"?"ok":"fail"),a.createEl("span",{cls:"paperforge-status-label",text:t}),a.createEl("span",{cls:"paperforge-status-detail",text:n||""})}_renderPaperMode(){let e=this._currentPaperEntry,t=this._currentPaperKey;if(!this._contentEl)return;if(!t){this._renderEmptyState(this._contentEl,"No paper data available.");return}if(!e){this._contentEl.createEl("div",{cls:"paperforge-content-placeholder",text:'Paper "'+t+'" not found in canonical index. Sync first.'});return}let r=this._contentEl.createEl("div",{cls:"paperforge-paper-view"}),n=r.createEl("div",{cls:"paperforge-paper-header"});n.createEl("div",{cls:"paperforge-paper-title pf-copy",text:e.title||"Untitled"}).addEventListener("click",()=>{navigator.clipboard.writeText(e.title||""),new M.Notice("Title copied")});let s=n.createEl("div",{cls:"paperforge-paper-meta"});e.authors&&e.authors.length>0&&s.createEl("span",{cls:"paperforge-paper-authors",text:e.authors.join(", ")}),e.year&&s.createEl("span",{cls:"paperforge-paper-year",text:String(e.year)});let i=r.createEl("div",{cls:"paperforge-status-strip"}),c=i.createEl("div",{cls:"paperforge-status-strip-left"}),l=i.createEl("div",{cls:"paperforge-status-strip-right"}),_=[{key:"pdf",label:"PDF",ok:e.has_pdf===!0},{key:"ocr",label:"OCR",ok:e.ocr_status==="done",pending:["pending","queued","processing"].includes(e.ocr_status||""),fail:["failed","blocked","done_incomplete","nopdf"].includes(e.ocr_status||"")},{key:"deep",label:"\u7CBE\u8BFB",ok:e.deep_reading_status==="done"}];for(let u of _){let g=c.createEl("span",{cls:"paperforge-status-pill"}),m="pending";u.ok?m="ok":u.fail?m="fail":u.pending&&(m="pending"),g.addClass(m);let b=u.ok?"\u2713":u.fail?"\u2717":"\u25CB";g.createEl("span",{cls:"paperforge-status-pill-icon",text:b}),g.createEl("span",{text:" "+u.label})}if(e.pdf_path){let u=l.createEl("button",{cls:"paperforge-contextual-btn"});u.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u{1F4C4}"}),u.createEl("span",{text:"\u6253\u5F00 PDF"}),u.addEventListener("click",()=>{let g=e.pdf_path.match(/\[\[([^\]]+)\]\]/),m=g?g[1]:e.pdf_path;this.app.vault.getAbstractFileByPath(m)?this.app.workspace.openLinkText(m,""):new M.Notice("[!!] PDF not found: "+m,6e3)})}if(e.fulltext_path){let u=l.createEl("button",{cls:"paperforge-contextual-btn"});u.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u{1F4DD}"}),u.createEl("span",{text:"\u6253\u5F00\u5168\u6587"}),u.addEventListener("click",()=>this._openFulltext(e.fulltext_path))}let f=l.createEl("button",{cls:"paperforge-contextual-btn"});if(f.createEl("span",{text:o("version_panel_title")}),f.addEventListener("click",()=>{this._switchToVersionMode(t)}),this._renderPaperOverviewCard(r,e),e.next_step==="ready"&&e.deep_reading_status==="done"){let u=r.createEl("div",{cls:"paperforge-complete-row"});u.createEl("span",{text:"\u2713"}),u.createEl("span",{text:"\u5DF2\u5B8C\u6210\uFF0C\u53EF\u76F4\u63A5\u4F7F\u7528"})}else this._renderNextStepCard(r,e,t);this._renderRecentDiscussionCard(r,e),this._renderPaperTechnicalDetails(r,e)}_renderPaperOverviewCard(e,t){let r=e.createEl("div",{cls:"paperforge-paper-overview"});r.createEl("div",{cls:"paperforge-paper-overview-header"}).createEl("span",{cls:"paperforge-paper-overview-title",text:"\u6587\u7AE0\u6982\u89C8"});let a=r.createEl("div",{cls:"paperforge-paper-overview-body"}),s=a.createEl("div",{cls:"paperforge-paper-overview-excerpt",text:"\u52A0\u8F7D\u4E2D..."});if(t.note_path){let i=this.app.vault.getAbstractFileByPath(t.note_path);i?this.app.vault.read(i).then(c=>{let l=this._extractOverviewFromNote(c);if(l){let _=l.length>200?l.slice(0,200)+"...":l;if(s.setText(_),l.length>200){let f=a.createEl("div",{cls:"paperforge-expand-container"}),u=f.createEl("button",{cls:"paperforge-expand-icon",title:"\u5C55\u5F00/\u6536\u8D77"});u.innerHTML='<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>';let g=!1;f.addEventListener("click",()=>{s.setText(g?_:l),u.innerHTML=g?'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>':'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"></polyline></svg>',g=!g})}}else s.setText("\u5C1A\u672A\u751F\u6210\u6587\u7AE0\u6982\u89C8\u3002\u8FD0\u884C /pf-deep \u5F00\u59CB\u7CBE\u8BFB\u3002")}).catch(()=>{s.setText("\u65E0\u6CD5\u8BFB\u53D6\u7B14\u8BB0\u5185\u5BB9")}):s.setText("\u7B14\u8BB0\u6587\u4EF6\u4E0D\u5B58\u5728")}else s.setText("\u5C1A\u672A\u751F\u6210\u6587\u7AE0\u6982\u89C8")}_extractOverviewFromNote(e){if(!e)return null;let t=e.indexOf("## \u{1F50D} \u7CBE\u8BFB");if(t===-1)return null;let r=e.slice(t),n=["**\u4E00\u53E5\u8BDD\u603B\u89C8:**","**\u4E00\u53E5\u8BDD\u603B\u89C8**","**\u6587\u7AE0\u6458\u8981:**","**\u6587\u7AE0\u6458\u8981**"];for(let i of n){let c=r.indexOf(i);if(c!==-1){let l=r.slice(c+i.length),_=["**5 Cs","**Figure","**\u8BC1\u636E","### Pass 2","## "],f=l.length;for(let m of _){let b=l.indexOf(m);b!==-1&&b<f&&(f=b)}let u=l.indexOf(`
|
|
|
|
`);u!==-1&&u<f&&(f=u);let g=l.slice(0,f).trim();return g.startsWith("**")&&(g=g.slice(2)),g.endsWith("**")&&(g=g.slice(0,-2)),g||null}}let a=r.indexOf(`
|
|
`);if(a===-1)return null;let s=r.slice(a+1).split(`
|
|
|
|
`)[0].trim();return!s||s.startsWith("###")||s.startsWith("##")?null:s.length>300?s.slice(0,300)+"...":s}_renderRecentDiscussionCard(e,t){let r=e.createEl("div",{cls:"paperforge-discussion-card"});if(r.style.display="none",!t.note_path)return;let n=t.note_path.lastIndexOf("/"),s=(n!==-1?t.note_path.substring(0,n):".")+"/ai/discussion.md";this.app.vault.adapter.exists(s).then(i=>{if(i)return this.app.vault.adapter.read(s)}).then(async i=>{if(!i)return;let c=this._parseDiscussionMD(i);if(!c||c.length===0)return;r.style.display="block",r.createEl("div",{cls:"paperforge-discussion-header"}).createEl("span",{cls:"paperforge-discussion-title",text:"\u6700\u8FD1\u8BA8\u8BBA"});for(let f of c){let u=r.createEl("div",{cls:"paperforge-discussion-item"}),g=u.createEl("div",{cls:"paperforge-discussion-q"});g.createEl("span",{cls:"paperforge-discussion-q-label",text:"\u63D0\u95EE\uFF1A"}),g.createEl("span",{cls:"paperforge-discussion-q-text",text:f.question});let m=u.createEl("div",{cls:"paperforge-discussion-a"}),b=!1;if(f.answer&&f.answer.length>500&&(b=!0,m.classList.add("paperforge-discussion-a-collapsed")),await M.MarkdownRenderer.render(this.app,f.answer||"",m,s,this),b){let h=!1;u.style.cursor="pointer",u.addEventListener("click",()=>{h=!h,m.classList.toggle("paperforge-discussion-a-collapsed",!h),m.classList.toggle("paperforge-discussion-a-expanded",h)})}}r.createEl("a",{cls:"paperforge-discussion-viewall",text:"\u67E5\u770B\u5168\u90E8\u8BA8\u8BBA \u2192"}).addEventListener("click",f=>{f.preventDefault(),this.app.vault.getAbstractFileByPath(s)?this.app.workspace.openLinkText(s,""):new M.Notice("\u8BA8\u8BBA\u6587\u4EF6\u5C1A\u672A\u751F\u6210")})}).catch(i=>{console.error("PaperForge: discussion.md read error",s,i.message)})}_parseDiscussionMD(e){let t=e.split(/\n## /).slice(1);if(t.length===0)return null;let r=t[t.length-1],n=[],a=r.split(/\*\*\u95EE\u9898:\*\*/).slice(1);for(let s of a){let i=s.match(/\*\*\u89E3\u7B54:\*\*/);if(!i)continue;let c=s.substring(0,i.index).trim(),l=s.substring(i.index+3+4).trim();n.push({question:c,answer:l})}return n.slice(-3)}_renderPaperTechnicalDetails(e,t){let r=this._currentPaperKey,n=e.createEl("div",{cls:"paperforge-technical-details"}),a=n.createEl("button",{cls:"paperforge-technical-details-toggle"}),s=n.createEl("div",{cls:"paperforge-technical-details-body"});s.style.display="none",this._techDetailsExpanded?(s.style.display="block",a.setText("\u6280\u672F\u8BE6\u60C5 \u25BE")):a.setText("\u6280\u672F\u8BE6\u60C5 \u25B8"),a.addEventListener("click",()=>{let u=s.style.display!=="none";s.style.display=u?"none":"block",a.setText(u?"\u6280\u672F\u8BE6\u60C5 \u25B8":"\u6280\u672F\u8BE6\u60C5 \u25BE"),this._techDetailsExpanded=!u});let i=s.createEl("div",{cls:"paperforge-workflow-toggles"}),c=[{key:"do_ocr",label:"OCR",hint:"\u52A0\u5165 OCR"},{key:"analyze",label:"\u7CBE\u8BFB",hint:"\u6807\u8BB0\u7CBE\u8BFB"}];for(let u of c){let g=i.createEl("label",{cls:"paperforge-workflow-toggle"}),m=g.createEl("input",{type:"checkbox",cls:"paperforge-workflow-checkbox"});m.checked=t[u.key]===!0,g.createEl("span",{cls:"paperforge-workflow-toggle-label",text:u.label}),g.createEl("span",{cls:"paperforge-workflow-toggle-hint",text:u.hint}),m.addEventListener("change",async()=>{let b=t.note_path?this.app.vault.getAbstractFileByPath(t.note_path):null;if(!b){new M.Notice("[!!] Note file not found",6e3);return}let h=m.checked;await this.app.fileManager.processFrontMatter(b,v=>{v[u.key]=h}),this._patchCachedEntry(r,{[u.key]:h}),this._currentPaperEntry=Qe(this._currentPaperEntry,{[u.key]:h})})}let l=t.health||{},_=[["PDF Health",l.pdf_health||"\u2014"],["OCR Status",t.ocr_status||"\u2014"],["Asset Health",l.asset_health||"\u2014"],["Note Path",t.note_path||"\u2014"],["Fulltext Path",t.fulltext_path||"\u2014"]],f=new Set(["Note Path","Fulltext Path","Key"]);for(let[u,g]of _){let m=s.createEl("div",{cls:"paperforge-technical-row"});m.createEl("span",{cls:"paperforge-technical-label",text:u});let b=m.createEl("span",{cls:"paperforge-technical-value",text:String(g)});f.has(u)&&g&&g!=="\u2014"&&(b.addClass("pf-copy"),b.addEventListener("click",()=>{navigator.clipboard.writeText(g),new M.Notice(u+" copied")}))}}_renderNextStepCard(e,t,r){var c,l;let n=t.next_step||"ready",a={sync:{label:"Sync Needed",text:"This paper needs to be synced from Zotero. Click to run sync.",cmd:"sync",icon:"\u21BB"},ocr:{label:"OCR Needed",text:"Fulltext is missing but PDF is present. Click to run OCR.",cmd:"ocr",icon:"\u229E"},repair:{label:"Repair Needed",text:"State divergence or path errors detected. Click to repair.",cmd:"repair",icon:"\u21BA"},"rebuild index":{label:"Rebuild Needed",text:"Index may be stale. Click to run sync to rebuild.",cmd:"sync",icon:"\u21BB"},"/pf-deep":{label:"Ready for Deep Reading",text:"Fulltext is ready. Copy /pf-deep command and run in your agent.",cmd:null,icon:"\u{1F50D}"},ready:{label:"All Set",text:"This paper is fully processed and ready for use.",cmd:"ready",icon:"\u2713"}},s=a[n]||a.ready,i=e.createEl("div",{cls:"paperforge-next-step-card"});if(n==="ready"&&i.addClass("ready"),i.createEl("div",{cls:"paperforge-next-step-label",text:"Recommended Next Step"}),i.createEl("div",{cls:"paperforge-next-step-text",text:s.text}),s.cmd&&s.cmd!=="ready"){let _=i.createEl("button",{cls:"paperforge-next-step-trigger"});_.createEl("span",{text:s.icon+" "+s.label}),_.addEventListener("click",()=>{let f=ie.find(u=>u.cmd===s.cmd);f&&this._runAction(f,_)})}else if(n==="/pf-deep"){let _=i.createEl("button",{cls:"paperforge-next-step-trigger"});_.createEl("span",{text:"\u{1F4CB} "+o("copy_pf_deep_cmd")}),_.addEventListener("click",()=>{let b="/pf-deep "+r;navigator.clipboard.writeText(b).then(()=>{_.setText("\u2713 "+o("copied")),new M.Notice(b+" copied")}).catch(()=>{new M.Notice("[!!] Clipboard write failed",6e3)})});let f=((l=(c=this.app.plugins.plugins.paperforge)==null?void 0:c.settings)==null?void 0:l.agent_platform)||"opencode",g={opencode:"OpenCode",claude:"Claude Code",cursor:"Cursor",github_copilot:"GitHub Copilot",windsurf:"Windsurf",codex:"Codex",gemini:"Gemini CLI",cline:"Cline"}[f]||f;i.createEl("div",{cls:"paperforge-agent-platform-label"}).setText(o("run_in_agent").replace("{0}",g))}else n==="ready"&&i.createEl("button",{cls:"paperforge-next-step-trigger"}).createEl("span",{text:"\u2713 "+s.label})}_openFulltext(e){if(!e){new M.Notice("[!!] No fulltext path available for this paper",6e3);return}let t=this.app.vault.getAbstractFileByPath(e);t?this.app.workspace.openLinkText(t.path,""):new M.Notice("[!!] Fulltext file not found: "+e,6e3)}_renderCollectionMode(){let e=this._currentDomain||"Unknown",t=this._filterByDomain(e);if(t.length===0){this._renderGlobalMode();return}if(!this._contentEl)return;let r=this._contentEl.createEl("div",{cls:"paperforge-collection-view"}),n=t.length,a=0,s=0,i=0,c=0,l=0,_=0,f=0;for(let y of t){y.has_pdf&&a++,y.ocr_status==="done"&&s++,y.ocr_status==="done"&&y.analyze===!0&&i++,y.deep_reading_status==="done"&&c++;let E=y.ocr_status||"";E==="pending"||E==="queued"?l++:E==="processing"?_++:(E==="failed"||E==="blocked"||E==="done_incomplete"||E==="nopdf")&&f++}r.createEl("div",{cls:"paperforge-collection-header"}).createEl("div",{cls:"paperforge-collection-title",text:e});let g=r.createEl("div",{cls:"paperforge-workflow-overview"});g.createEl("div",{cls:"paperforge-section-label",text:"Workflow Overview"});let m=g.createEl("div",{cls:"paperforge-workflow-funnel"}),b=[{value:n,label:"Total"},{value:a,label:"PDF Ready"},{value:s,label:"OCR Done"},{value:c,label:"Deep Read"}];for(let y=0;y<b.length;y++){let E=m.createEl("div",{cls:"paperforge-workflow-stage"});E.createEl("div",{cls:"paperforge-workflow-stage-value",text:String(b[y].value)}),E.createEl("div",{cls:"paperforge-workflow-stage-label",text:b[y].label}),y<b.length-1&&m.createEl("div",{cls:"paperforge-workflow-arrow",text:"\u2192"})}if(l+_+s+f>0){let y=r.createEl("div",{cls:"paperforge-ocr-section"}),E=y.createEl("div",{cls:"paperforge-collection-ocr-header"});E.createEl("h4",{cls:"paperforge-ocr-title",text:"OCR Pipeline"});let w=E.createEl("span",{cls:"paperforge-ocr-badge idle"});_>0?(w.addClass("active"),w.setText("Processing")):l>0?w.setText("Pending"):(w.addClass("idle"),w.setText("Idle"));let D=y.createEl("div",{cls:"paperforge-progress-track"});_>0&&D.addClass("paperforge-processing");let T=l+_+s+f,I=[{cls:"pending",count:l},{cls:"active",count:_},{cls:"done",count:s},{cls:"failed",count:f}];for(let V of I)if(V.count>0){let A=(V.count/T*100).toFixed(1);D.createEl("div",{cls:`paperforge-progress-seg ${V.cls}`,attr:{style:`width:${A}%`}})}let B=y.createEl("div",{cls:"paperforge-ocr-counts"}),$=[{cls:"pending",value:l,label:"Pending"},{cls:"active",value:_,label:"Processing"},{cls:"done",value:s,label:"Done"},{cls:"failed",value:f,label:"Attention"}];for(let V of $){let A=B.createEl("div",{cls:"paperforge-ocr-count"});A.createEl("div",{cls:"paperforge-ocr-count-value",text:V.value.toString()}),A.createEl("div",{cls:"paperforge-ocr-count-label",text:V.label})}}let h=r.createEl("div",{cls:"paperforge-collection-actions"}),v=h.createEl("button",{cls:"paperforge-contextual-btn primary"});v.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u229E"}),v.createEl("span",{text:"Run OCR"}),v.addEventListener("click",()=>{let y=ie.find(E=>E.id==="paperforge-ocr");y&&this._runAction(y,v)});let x=h.createEl("button",{cls:"paperforge-contextual-btn"});x.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u21BB"}),x.createEl("span",{text:"Sync Library"}),x.addEventListener("click",()=>{let y=ie.find(E=>E.id==="paperforge-sync");y&&this._runAction(y,x)});let k=h.createEl("button",{cls:"paperforge-contextual-btn warn"});k.createEl("span",{cls:"paperforge-contextual-btn-icon",text:"\u21BA"}),k.createEl("span",{text:"Redo OCR"}),k.addEventListener("click",()=>{let y=ie.find(E=>E.id==="paperforge-ocr-redo");y&&this._runAction(y,k)}),this.renderSearchSection(r)}_refreshCurrentMode(){if(!(!this._currentMode||!this._contentEl)){this._contentEl.empty(),this._contentEl.addClass("switching"),this._invalidateIndex(),this._currentPaperEntry=this._currentPaperKey?this._findEntry(this._currentPaperKey):null,this._renderModeHeader(this._currentMode);try{switch(this._currentMode){case"global":this._renderGlobalMode();break;case"paper":this._renderPaperMode();break;case"collection":this._renderCollectionMode();break;case"versions":this._renderVersionMode();break}}finally{setTimeout(()=>{this._contentEl&&this._contentEl.removeClass("switching")},50)}}}_switchToVersionMode(e){let r=this.app.vault.adapter.basePath,n=typeof r=="string"?r:"";if(!n){new M.Notice("Cannot determine vault path");return}this._versionPapers=vt(n),this._versionFilter="",this._currentMode="versions",this._currentFilePath=null,this._techDetailsExpanded=!1,this._contentEl&&(this._contentEl.empty(),this._contentEl.removeClass("switching"),this._renderModeHeader("versions"),this._renderVersionMode())}_renderVersionMode(){if(!this._contentEl)return;let e=this._contentEl.createEl("div",{cls:"paperforge-version-panel"}),r=this.app.vault.adapter.basePath,n=typeof r=="string"?r:"";if(!n){e.createEl("div",{cls:"paperforge-status-error",text:"Could not determine vault path"});return}(!this._versionPapers||this._versionPapers.length===0)&&(this._versionPapers=vt(n));let a=e.createEl("div",{cls:"paperforge-version-left"}),s=e.createEl("div",{cls:"paperforge-version-right"}),i=a.createEl("input",{cls:"paperforge-version-filter",attr:{type:"text",placeholder:o("version_filter_placeholder")}});i.value=this._versionFilter;let c=a.createEl("div",{cls:"paperforge-version-paper-list"}),l=()=>{c.empty();let v=this._versionFilter.toLowerCase(),x=this._versionPapers?this._versionPapers.filter(y=>!v||y.key.toLowerCase().includes(v)||y.title.toLowerCase().includes(v)):[];if(x.length===0){c.createEl("div",{cls:"paperforge-meta",text:o("version_no_backups")});return}let k=c.createEl("div",{cls:"paperforge-meta",text:o("version_papers_count").replace("{n}",String(x.length))});for(let y of x){let E=c.createEl("div",{cls:"paperforge-version-paper-item"}),w=E.createEl("span",{cls:"paperforge-version-paper-title",text:y.title}),D=E.createEl("span",{cls:"paperforge-version-paper-versions",text:y.versions.map(T=>T.label).join(" ")});E.addEventListener("click",()=>{c.querySelectorAll(".paperforge-version-paper-item.selected").forEach(T=>T.removeClass("selected")),E.addClass("selected"),f(y)})}};i.addEventListener("input",()=>{this._versionFilter=i.value,l()});let _=s.createEl("div",{cls:"paperforge-version-timeline-area"}),f=v=>{if(_.empty(),_.createEl("div",{cls:"paperforge-version-timeline-header"}).createEl("span",{cls:"pf-title",text:v.title}),v.versions.length===0){_.createEl("div",{cls:"paperforge-meta",text:o("version_no_backups")});return}let k=_.createEl("div",{cls:"paperforge-version-timeline"});for(let y of v.versions){let E=y.label===v.currentLabel,w=k.createEl("div",{cls:"paperforge-version-entry"+(E?" paperforge-version-current":"")}),D=w.createEl("div",{cls:"paperforge-version-dot"}),T=w.createEl("div",{cls:"paperforge-version-content"}),I=T.createEl("div",{cls:"paperforge-version-label-row"});I.createEl("span",{cls:"paperforge-version-label",text:y.label}),E&&I.createEl("span",{cls:"paperforge-version-current-tag",text:o("version_current")});let B=y.created_at?y.created_at.slice(0,10):"";T.createEl("div",{cls:"paperforge-meta",text:B+" \u2014 "+y.source});let $=y.fulltext_size?y.fulltext_size>1024?(y.fulltext_size/1024).toFixed(0)+"KB":y.fulltext_size+"B":"";$&&T.createEl("div",{cls:"paperforge-meta",text:$});let V=T.createEl("div",{cls:"paperforge-version-actions"});V.createEl("button",{cls:"pf-btn-primary",text:o("version_restore_btn")}).addEventListener("click",()=>{Wt(n,v.key,y.label)?new M.Notice(o("version_restore_done").replace("{label}",y.label)):new M.Notice("Restore failed",6e3)}),v.versions.length>1&&!E&&V.createEl("button",{cls:"pf-btn-secondary",text:o("version_compare_btn")}).addEventListener("click",()=>{g(v,y.label,v.currentLabel)})}},u=s.createEl("div",{cls:"paperforge-version-compare"});u.style.display="none";let g=(v,x,k)=>{let y=Ut(n,v.key,x,k);u.style.display="block",u.empty();let E=u.createEl("div",{cls:"paperforge-version-compare-header"});if(E.createEl("span",{cls:"pf-title",text:o("version_compare_title").replace("{vA}",x).replace("{vB}",k)}),E.createEl("span",{cls:"paperforge-meta",text:o("version_compare_paragraphs").replace("{n}",String(y.length))}),y.length===0){u.createEl("div",{cls:"paperforge-meta",text:"No changes"});return}let w=u.createEl("div",{cls:"paperforge-version-diff-list"});for(let D of y){let T=w.createEl("div",{cls:"paperforge-version-diff-row"}),I=D.type==="added"?"[+]":D.type==="removed"?"[-]":"[~]",B=D.heading||"paragraph "+(D.paragraphIndex+1);T.createEl("span",{cls:"paperforge-version-diff-label",text:I+" "+B}),D.oldText&&T.createEl("pre",{cls:"paperforge-version-diff-old",text:D.oldText.slice(0,200)}),D.newText&&T.createEl("pre",{cls:"paperforge-version-diff-new",text:D.newText.slice(0,200)})}},m=e.createEl("div",{cls:"paperforge-version-actions-bar"}),b=m.createEl("button",{cls:"pf-btn-primary",text:o("version_restore_selected")}),h=m.createEl("button",{cls:"pf-btn-secondary",text:o("version_clear_old").replace("{size}","")});l()}renderSearchSection(e){this._searchContainer=e.createEl("div",{cls:"paperforge-search-section"}),this._searchContainer.createEl("div",{cls:"paperforge-search-header"}).createEl("span",{cls:"pf-label",text:"Search"});let r=this._searchContainer.createEl("div",{cls:"paperforge-search-input-row"}),n=r.createEl("span",{cls:"paperforge-search-mode",text:"M"});this._searchInput=r.createEl("input",{cls:"paperforge-search-input",attr:{type:"text",placeholder:"Search papers... (@ for deep search)"}}),this._searchResultsEl=this._searchContainer.createEl("div",{cls:"paperforge-search-results"}),this._searchInput.placeholder=o("retrieval_search_placeholder"),this._searchInput.addEventListener("input",()=>{var s;let a=((s=this._searchInput)==null?void 0:s.value)||"";if(a.startsWith("@")&&!a.startsWith("@ ")?(this._searchMode="@",n.setText("@"),n.addClass("deep"),this._searchInput&&(this._searchInput.placeholder=o("retrieval_search_placeholder_deep"))):(this._searchMode="M",n.setText("M"),n.removeClass("deep"),this._searchInput&&(this._searchInput.placeholder=o("retrieval_search_placeholder"))),clearTimeout(this._searchTimer),!a.trim()){this._searchState="idle",this._searchResults=null,this._searchActiveIndex=-1,this._renderSearchState();return}a.startsWith("@")||(this._searchTimer=setTimeout(()=>{this.executeSearch()},200))}),this._searchInput.addEventListener("keydown",a=>{var s,i;if(a.key==="Escape"){a.preventDefault(),this._searchInput&&(this._searchInput.value="",this._searchInput.blur()),this._searchState="idle",this._searchResults=null,this._searchActiveIndex=-1,this._renderSearchState();return}if(a.key==="ArrowDown"||a.key==="ArrowUp"){if(this._searchState!=="results"||!((s=this._searchResults)!=null&&s.length))return;a.preventDefault();let c=this._searchResults.length;a.key==="ArrowDown"?this._searchActiveIndex=Math.min(this._searchActiveIndex+1,c-1):this._searchActiveIndex=Math.max(this._searchActiveIndex-1,-1);let l=(i=this._searchResultsEl)==null?void 0:i.querySelectorAll(".paperforge-search-result-card");l&&l.forEach((_,f)=>{f===this._searchActiveIndex?(_.setAttribute("aria-selected","true"),_.classList.add("active")):(_.setAttribute("aria-selected","false"),_.classList.remove("active"))});return}if(a.key==="Enter"&&a.ctrlKey){a.preventDefault(),this._searchTimer&&(clearTimeout(this._searchTimer),this._searchTimer=void 0);let c=this._searchMode;this._searchMode="@",this.executeSearch(),this._searchMode=c;return}a.key==="Enter"&&(a.preventDefault(),this._searchTimer&&(clearTimeout(this._searchTimer),this._searchTimer=void 0),this.executeSearch())})}_renderSearchState(){if(!this._searchResultsEl)return;switch(this._searchResultsEl.empty(),this._searchResultsEl.removeAttribute("role"),this._searchResultsEl.removeAttribute("aria-live"),this._searchInput&&(this._searchInput.disabled=!1),this._searchState){case"idle":break;case"searching":{let t=this._searchMode==="@";this._searchResultsEl.createEl("div",{cls:"paperforge-search-loading",text:t?o("retrieval_searching_deep"):o("retrieval_searching_metadata")}),this._searchResultsEl.setAttr("aria-live","polite"),t&&this._searchInput&&(this._searchInput.disabled=!0);break}case"results":{this._searchResultsEl.setAttr("role","listbox"),this._searchResultsEl.setAttr("aria-live","polite"),this._searchResults&&this._renderSearchResultsList(this._searchResults,this._searchMode==="@"),setTimeout(()=>{var r;let t=(r=this._searchResultsEl)==null?void 0:r.querySelector(".paperforge-search-result-card");t&&t instanceof HTMLElement&&t.focus()},100);break}case"empty":{let t=this._searchResultsEl.createEl("div",{cls:"paperforge-search-empty"});t.setAttr("role","alert"),t.createEl("div",{text:o("retrieval_empty")}),t.createEl("div",{cls:"paperforge-search-empty-tips",text:o("retrieval_empty_tips")});break}case"vectors-not-built":{let t=this._searchResultsEl.createEl("div",{cls:"paperforge-search-state-card",attr:{role:"alert"}});t.addClass("warning-soft"),t.createEl("div",{cls:"paperforge-search-state-title",text:o("retrieval_vectors_not_built")}),t.createEl("div",{cls:"paperforge-search-state-desc",text:o("retrieval_vectors_not_built_desc")});let r=t.createEl("button",{cls:"pf-btn-link",text:o("retrieval_open_vector_settings")});r.addEventListener("click",()=>{let n=this.app.setting;if(n&&typeof n=="object"){let a=n.openTab;typeof a=="function"&&a.call(n,"paperforge")}}),setTimeout(()=>{r.focus()},100);break}case"backend-unavailable":{let t=this._searchResultsEl.createEl("div",{cls:"paperforge-search-state-card",attr:{role:"alert"}});t.addClass("error-soft"),t.createEl("div",{cls:"paperforge-search-state-title",text:o("retrieval_backend_unavailable")}),t.createEl("div",{cls:"paperforge-search-state-desc",text:o("retrieval_backend_unavailable_desc")});let r=t.createEl("div",{cls:"paperforge-search-state-actions"}),n=r.createEl("button",{cls:"pf-btn-primary",text:o("retrieval_run_doctor")});n.addEventListener("click",()=>{let s=this.app.vault.adapter.basePath;if(typeof s=="string"){let{path:i,extraArgs:c=[]}=z(s,null,void 0,void 0);(0,ve.spawn)(i,[...c,"-m","paperforge","doctor"],{cwd:s,stdio:"inherit"})}}),r.createEl("button",{cls:"pf-btn-secondary",text:o("retrieval_retry")}).addEventListener("click",()=>{this.executeSearch()}),setTimeout(()=>{n.focus()},100);break}case"timeout":{let t=this._searchResultsEl.createEl("div",{cls:"paperforge-search-state-card",attr:{role:"alert"}});t.addClass("warning-soft"),t.createEl("div",{cls:"paperforge-search-state-title",text:o("retrieval_timeout_title")}),t.createEl("div",{cls:"paperforge-search-state-desc",text:o("retrieval_timeout_desc")});let r=t.createEl("button",{cls:"pf-btn-primary",text:o("retrieval_retry")});r.addEventListener("click",()=>{this.executeSearch()}),setTimeout(()=>{r.focus()},100);break}case"model-changed":{let t=this._searchResultsEl.createEl("div",{cls:"paperforge-search-state-card",attr:{role:"alert"}});t.addClass("warning-soft"),t.createEl("div",{cls:"paperforge-search-state-title",text:o("retrieval_model_changed")}),t.createEl("div",{cls:"paperforge-search-state-desc",text:o("retrieval_model_changed_desc")});let r=t.createEl("button",{cls:"pf-btn-primary",text:o("retrieval_rebuild_vectors")});r.addEventListener("click",()=>{let n=this.app.setting;if(n&&typeof n=="object"){let a=n.openTab;typeof a=="function"&&a.call(n,"paperforge")}}),setTimeout(()=>{r.focus()},100);break}default:{this._searchResultsEl.createEl("div",{cls:"paperforge-search-state-card",text:o("retrieval_internal_error"),attr:{role:"alert"}}).addClass("error-soft"),setTimeout(()=>{this._searchInput&&this._searchInput.focus()},100);break}}}async executeSearch(){if(!this._searchInput||!this._searchResultsEl)return;let e=this._searchInput.value.trim();if(!e)return;let t=this._searchMode==="@"||e.startsWith("@"),r=t?e.replace(/^@\s*/,"").trim():e;if(!r)return;let n=t?"retrieve":"search";this._searchState="searching",this._searchResults=null,this._searchActiveIndex=-1,this._renderSearchState();let a=this.app.vault.adapter,s="";if(a&&typeof a=="object"&&"basePath"in a){let b=a.basePath;s=typeof b=="string"?b:""}if(!s){this._searchState="backend-unavailable",this._renderSearchState();return}let i=null,l=this.app.plugins;if(l&&typeof l=="object"&&"plugins"in l){let b=l.plugins;if(b&&typeof b=="object"&&"paperforge"in b){let h=b.paperforge;h&&typeof h=="object"&&"settings"in h&&(i=h.settings)}}let{path:_,extraArgs:f=[]}=z(s,i,void 0,void 0),u=n==="retrieve"?["--deep"]:[],g=(0,ve.spawn)(_,[...f,"-m","paperforge","--vault",s,n,r,...u,"--json"],{cwd:s,timeout:3e4}),m=[];g.stdout.on("data",b=>{m.push(b.toString("utf-8"))}),g.stderr.on("data",()=>{}),g.on("close",b=>{if(b!==0){let y=lt(String(b));this._searchState=this._mapErrorToSearchState(y.type),this._renderSearchState();return}let h=m.join(""),v=h.indexOf("{"),x=h.lastIndexOf("}"),k="";if(v!==-1&&x>v)k=h.slice(v,x+1);else{let y=h.indexOf("["),E=h.lastIndexOf("]");y!==-1&&E>y&&(k=h.slice(y,E+1))}if(!k){this._searchState="internal-error",this._renderSearchState();return}try{let y=JSON.parse(k),E=[];if(y&&typeof y=="object"&&"data"in y){let w=y.data;if(w&&typeof w=="object"){let D=w;"matches"in D&&Array.isArray(D.matches)&&(E=D.matches)}}this._searchResults=E,this._searchState=E.length>0?"results":"empty",this._renderSearchState()}catch(y){let E=y instanceof Error?y.message:String(y);this._searchState="internal-error",this._renderSearchState()}}),g.on("error",b=>{let h=b.code;if(typeof h=="string"){let v=lt(h);this._searchState=this._mapErrorToSearchState(v.type)}else this._searchState="backend-unavailable";this._renderSearchState()})}_mapErrorToSearchState(e){switch(e){case"vectors_not_built":return"vectors-not-built";case"vectors_corrupted":return"vectors-not-built";case"backend_unavailable":return"backend-unavailable";case"model_changed":return"model-changed";case"timeout":return"timeout";case"no_python":case"python_missing":case"import_failed":case"version_mismatch":return"backend-unavailable";default:return"backend-unavailable"}}_renderSearchResultsList(e,t){if(!this._searchResultsEl)return;if(this._searchResultsEl.setAttr("aria-live","polite"),e.length===0){this._searchResultsEl.createEl("div",{cls:"paperforge-search-empty",text:"No results found."});return}let r=this._searchResultsEl.createEl("div",{cls:"paperforge-search-results-header"});r.createEl("span",{text:o("retrieval_results_count").replace("{n}",String(e.length)).replace("{s}",e.length!==1?"s":"")}).setAttr("aria-live","polite"),r.createEl("span",{cls:"paperforge-search-mode",text:t?"@":"M"});for(let a=0;a<e.length;a++){let s=e[a];if(!s||typeof s!="object")continue;let i=s,c=a===this._searchActiveIndex,l=this._searchResultsEl.createEl("div",{cls:"paperforge-search-result-card",attr:{role:"option",tabindex:"0","aria-selected":c?"true":"false","aria-posinset":String(a+1),"aria-setsize":String(e.length)}});c&&l.addClass("active");let _=typeof i.title=="string"?i.title:typeof i.file_name=="string"?i.file_name:"(untitled)";l.createEl("div",{cls:"paperforge-search-result-title",text:_});let f=typeof i.zotero_key=="string"?i.zotero_key:"",u=typeof i.main_note_path=="string"&&i.main_note_path?i.main_note_path:null,g=typeof i.note_path=="string"&&i.note_path?i.note_path:null,m=u||g;if(!m&&f){let v=this._getCachedIndex().find(x=>x!==null&&typeof x=="object"&&"zotero_key"in x&&x.zotero_key===f);if(v&&typeof v=="object"){let x=v;m=typeof x.main_note_path=="string"&&x.main_note_path?x.main_note_path:typeof x.note_path=="string"&&x.note_path?x.note_path:null}}m?l.addEventListener("click",h=>{let v=h.ctrlKey||h.metaKey;this.app.workspace.openLinkText(m,"",v)}):l.addEventListener("click",()=>{new M.Notice("[!!] Note not found: "+(f||"unknown"),6e3)}),l.addEventListener("keydown",h=>{if(h.key==="Enter"&&m){h.preventDefault();let v=h.ctrlKey||h.metaKey;this.app.workspace.openLinkText(m,"",v)}});let b=l.createEl("div",{cls:"paperforge-search-result-meta"});if(typeof i.first_author=="string"&&i.first_author&&b.createEl("span",{cls:"paperforge-search-result-author",text:i.first_author}),typeof i.journal=="string"&&i.journal&&b.createEl("span",{cls:"paperforge-search-result-journal",text:i.journal}),i.score!==void 0){let h=i.score,v=typeof h=="number"?h.toFixed(3):String(h);b.createEl("span",{cls:"paperforge-search-result-score",text:"Score: "+v})}if(typeof i.domain=="string"&&i.domain&&l.createEl("span",{cls:"paperforge-search-result-tag",text:i.domain}),typeof i.abstract=="string"&&i.abstract){let h=i.abstract;l.createEl("div",{cls:"paperforge-search-result-abstract",text:h.length>200?h.slice(0,200)+"...":h})}if(t&&typeof i.text=="string"&&i.text){let h=i.text;l.createEl("div",{cls:"paperforge-search-result-source",text:h.length>300?h.slice(0,300)+"...":h})}}}_renderSearchError(e){this._searchResultsEl&&(this._searchResultsEl.empty(),this._searchResultsEl.createEl("div",{cls:"paperforge-search-error",text:e}))}_runAction(e,t){var u,g;if(e.disabled){new M.Notice(`[i] ${e.disabledMsg||"This action is not yet available."}`,6e3);return}if(t.classList.contains("running"))return;t.addClass("running");let r=this.app.vault.adapter.basePath;this._showMessage("Processing...","running");let n=Array.isArray(e.args)?[...e.args]:[];if(e.needsKey){let m=this.app.workspace.getActiveFile(),b=null;if(m){let h=this.app.metadataCache.getFileCache(m);if(h&&h.frontmatter&&h.frontmatter.zotero_key?b=h.frontmatter.zotero_key:b=this._extractZoteroKeyFromPath(m.path),b)n=[...n,b];else if(h&&h.frontmatter){this._showMessage("[!!] No zotero_key in active note frontmatter","error"),new M.Notice("[!!] Open a paper note with a zotero_key in its frontmatter first",6e3),t.removeClass("running");return}else{this._showMessage("[!!] No frontmatter in active note","error"),new M.Notice("[!!] The active note has no frontmatter with a zotero_key",6e3),t.removeClass("running");return}}else{this._showMessage("[!!] No active note open","error"),new M.Notice("[!!] Open a paper note with a zotero_key in its frontmatter first",6e3),t.removeClass("running");return}}e.needsFilter&&(n=[...n,"--all"]);let a=e.needsFilter?6e4:e.needsKey?3e4:6e5,{path:s,extraArgs:i=[]}=z(r,(g=(u=this.app.plugins.plugins.paperforge)==null?void 0:u.settings)!=null?g:null,void 0,void 0),c=(0,ve.spawn)(s,[...i,"-m","paperforge",e.cmd,...n],{cwd:r,timeout:a}),l=[],_=Date.now(),f=setInterval(()=>this._fetchStats(!0),4e3);c.stdout.on("data",m=>{let b=m.toString("utf-8").split(`
|
|
`).filter(Boolean);for(let h of b){let v=h.trim();v&&(l.push(v),this._showMessage(l.slice(-8).join(`
|
|
`),"running"))}}),c.stderr.on("data",m=>{let b=m.toString("utf-8").split(`
|
|
`).filter(Boolean);for(let h of b){if(h.includes("\r")||h.includes("%")||h.includes("\u2588"))continue;let v=h.trim();v&&!v.match(/^\d+%|^\|/)&&(l.push(v),this._showMessage(l.slice(-8).join(`
|
|
`),"running"))}}),c.on("close",m=>{clearInterval(f),t.removeClass("running");let b=((Date.now()-_)/1e3).toFixed(1);if(m!==0){let h=l.slice(-3).join(" | ")||"exit code "+m;(e.cmd==="repair"||e.cmd==="ocr")&&m===1?(this._showMessage("[WARN] "+h,"running"),new M.Notice("[WARN] "+e.cmd+" partial: "+h,8e3),this._fetchStats(!0)):(this._showMessage("[!!] "+h,"error"),new M.Notice("[!!] "+e.cmd+" failed: "+h,8e3))}else if(e.needsKey||e.needsFilter){let h=l.join(`
|
|
`);if(h.trim())try{JSON.parse(h),navigator.clipboard.writeText(h).then(()=>{let v=`${b}s \u2014 ${h.length} chars copied`;this._showMessage("[OK] "+e.title+": "+v,"ok"),new M.Notice("[OK] "+e.okMsg+" \u2014 "+h.length+" chars")}).catch(v=>{this._showMessage("[!!] Clipboard write failed: "+v.message,"error"),new M.Notice("[!!] Clipboard error",6e3)})}catch(v){this._showMessage("[!!] Invalid JSON from "+e.title,"error"),new M.Notice("[!!] "+e.title+" returned invalid JSON: "+v.message.slice(0,100),8e3)}else this._showMessage("[!!] No output from context command","error"),new M.Notice("[!!] Context command returned empty output",8e3);this._fetchStats(!0)}else{let v=l.filter(k=>k.match(/updated \d+/)).pop()||l[l.length-1]||"",x=`${b}s \u2014 ${v}`;this._showMessage("[OK] "+e.title+": "+x,"ok"),new M.Notice("[OK] "+e.okMsg),this._contentEl&&this._contentEl.removeClass("switching"),this._cachedStats=null;try{this._fetchStats(!1)}catch(k){console.log("[PF] fetchStats error:",k)}console.log("[PF] close cmd="+e.cmd+" id="+e.id),e.cmd==="sync"&&Ze(this.app,this.app.plugins.plugins.paperforge,r)}}),c.on("error",m=>{t.removeClass("running"),this._contentEl&&this._contentEl.removeClass("switching"),this._showMessage("[!!] "+m.message,"error"),new M.Notice("[!!] Cannot start: "+m.message,8e3)})}_showMessage(e,t){this._messageEl&&(this._messageEl.setText(e),this._messageEl.className=`paperforge-message msg-${t}`)}_renderModeHeader(e){if(!this._modeContextEl)return;this._modeContextEl.empty();let t=this._modeContextEl.createEl("span",{cls:"paperforge-mode-badge"}),r="";switch(e){case"global":t.addClass("global"),t.setText("Global"),this._headerTitle&&this._headerTitle.setText("PaperForge");break;case"paper":t.addClass("paper"),t.setText("Paper"),this._headerTitle&&this._headerTitle.setText("Paper"),this._currentPaperEntry&&this._currentPaperEntry.title?r=this._currentPaperEntry.title:this._currentPaperKey?(r=this._currentPaperKey,this._modeContextEl.createEl("span",{cls:"paperforge-mode-warning",text:"Not found in index"})):r="Unknown paper";break;case"collection":t.addClass("collection"),t.setText("Collection"),this._headerTitle&&this._headerTitle.setText("Collection"),r=this._currentDomain||"Unknown Domain";break;case"versions":t.addClass("versions"),t.setText(o("version_panel_title")),this._headerTitle&&this._headerTitle.setText(o("version_panel_title"));break}r&&this._modeContextEl.createEl("span",{cls:"paperforge-mode-name",text:r})}_setupEventSubscriptions(){let e=this.app.workspace.on("active-leaf-change",()=>{this._leafChangeTimer&&clearTimeout(this._leafChangeTimer),this._leafChangeTimer=setTimeout(()=>{let r=this._resolveModeForFile(this.app.workspace.getActiveFile()),n=r.mode,a=r.filePath;this._currentMode===n&&this._currentFilePath===a||this._detectAndSwitch()},300)});this._modeSubscribers.push({event:"active-leaf-change",ref:e});let t=this.app.vault.on("modify",r=>{r&&r.path&&r.path.endsWith("formal-library.json")&&(this._invalidateIndex(),this._refreshCurrentMode())});this._modeSubscribers.push({event:"modify",ref:t})}static async open(e){let t=e.app.workspace.getLeavesOfType(ke);if(t.length>0){e.app.workspace.revealLeaf(t[0]);return}let r=e.app.workspace.getRightLeaf(!1);r&&(await r.setViewState({type:ke,active:!0}),e.app.workspace.revealLeaf(r))}};var Xe=class extends Y.Plugin{constructor(){super(...arguments);this._lastExportMtime=0;this._lastOcrMtimes={};this._autoSyncRunning=!1;this._lastSyncTime=null;this._pollTimer=null;this._embedProcess=null;this._embedProgress={current:0,total:0,key:""};this._embedStderr="";this._memoryStatusText=null}async onload(){await this.loadSettings(),this.saveSettings(),Pt(this.app),this.registerView(ke,t=>new Te(t));try{(0,Y.addIcon)(Be,Et)}catch(t){}this.addRibbonIcon(Be,"PaperForge Dashboard",()=>Te.open(this)),ie.find(t=>t.id==="paperforge-ocr-redo")&&this.addRibbonIcon("reset","PaperForge: Redo OCR",()=>{let t=this.app.vault.adapter.basePath;new Y.Notice("PaperForge: Redo OCR starting...");let{path:r,extraArgs:n}=z(t,this.settings,void 0,void 0);(0,ge.execFile)(r,[...n,"-m","paperforge","ocr","redo"],{cwd:t,timeout:6e5},(a,s,i)=>{if(a){new Y.Notice("PaperForge: Redo OCR failed");return}new Y.Notice("PaperForge: Redo OCR done")})}),this.addSettingTab(new Ye(this.app,this)),this.addCommand({id:"paperforge-status-panel",name:`PaperForge: ${o("guide_open")}`,callback:()=>Te.open(this)});for(let t of ie)this.addCommand({id:t.id,name:`PaperForge: ${t.title}`,callback:()=>{if(t.disabled){new Y.Notice(`[i] ${t.disabledMsg||"This action is not yet available."}`,6e3);return}let r=this.app.vault.adapter.basePath;new Y.Notice(`PaperForge: running ${t.cmd}...`);let{path:n,extraArgs:a=[]}=z(r,this.settings,void 0,void 0),s=Array.isArray(t.args)?[...t.args]:[];(0,ge.execFile)(n,[...a,"-m","paperforge",t.cmd,...s],{cwd:r,timeout:3e5},(i,c,l)=>{if(i){new Y.Notice(`[!!] ${t.cmd} failed: ${(l||i.message).slice(0,120)}`,8e3);return}new Y.Notice(`[OK] ${t.okMsg||c.trim().split(`
|
|
`)[0].slice(0,80)}`)})}});this.settings.auto_update_on_startup===!0&&this.settings.setup_complete&&setTimeout(()=>this._autoUpdate(),3e3),this._startFilePolling(),this._firstLaunchSnapshotMigration(),this._checkReleaseNotes()}_firstLaunchSnapshotMigration(){let e=this.app.vault.adapter.basePath;if(!e)return;let r=le(e).memoryStatePath;if(!U.existsSync(r)){let n=z(e,this.settings,void 0,void 0);[["runtime-health","--json"],["memory","status","--json"],["embed","status","--json"]].forEach(s=>{let i=[...n.extraArgs,"-m","paperforge","--vault",e,...s];(0,ge.execFile)(n.path,i,{cwd:e,timeout:6e4,windowsHide:!0},()=>{})})}}_autoUpdate(){let e=this.app.vault.adapter.basePath,{path:t,extraArgs:r=[]}=z(e,this.settings,void 0,void 0),n=this.manifest.version,a=`paperforge==${n}`,s=`git+https://github.com/LLLin000/PaperForge.git@${n}`,i=(c,l)=>{(0,ge.spawn)(t,[...r,"-m","pip","install","--upgrade",c],{cwd:e,timeout:12e4,env:we()}).on("close",f=>l(f===0))};(0,ge.execFile)(t,[...r,"-c","import paperforge; print(paperforge.__version__)"],{cwd:e,timeout:1e4},(c,l)=>{let _=u=>{console.log(`[PaperForge] Auto-update: trying PyPI (paperforge==${n})`),i(a,g=>{if(g){console.log("[PaperForge] Auto-update: installed via PyPI"),new Y.Notice(`[OK] PaperForge CLI ${u}`,5e3);return}console.warn("[PaperForge] Auto-update: PyPI failed, falling back to git..."),i(s,m=>{m&&(console.log("[PaperForge] Auto-update: installed via git"),new Y.Notice(`[OK] PaperForge CLI ${u} (via git)`,5e3))})})};if(c){_("installed");return}let f=l.trim();f!==n&&_(`${f} -> ${n}`)})}_startFilePolling(){let e=this.app.vault.adapter.basePath;this._pollTimer=setInterval(()=>{this._checkExports(e),this._checkOcr(e)},12e4)}_checkExports(e){if(this._autoSyncRunning)return;let t=le(e).exportsDir;if(!U.existsSync(t))return;let r=0;try{U.readdirSync(t).forEach(n=>{if(!n.endsWith(".json"))return;let a=U.statSync(Ae.join(t,n));a.mtimeMs>r&&(r=a.mtimeMs)})}catch(n){return}r>this._lastExportMtime&&(this._lastExportMtime=r,this._autoSync(e))}_autoSync(e){if(this._autoSyncRunning)return;this._autoSyncRunning=!0;let t=z(e,this.settings,void 0,void 0);if(!t.path){this._autoSyncRunning=!1;return}let r=`"${t.path}" -m paperforge --vault "${e}" sync`;(0,ge.exec)(r,{timeout:12e4,encoding:"utf-8"},(n,a,s)=>{this._autoSyncRunning=!1,this._memoryStatusText=null,n||(this._lastSyncTime=new Date().toLocaleTimeString());try{let i=le(e).exportsDir,c=0;U.readdirSync(i).forEach(l=>{l.endsWith(".json")&&(c=Math.max(c,U.statSync(Ae.join(i,l)).mtimeMs))}),this._lastExportMtime=c}catch(i){}})}_checkOcr(e){if(this._autoSyncRunning)return;let t=le(e).ocrDir;if(U.existsSync(t))try{U.readdirSync(t,{withFileTypes:!0}).forEach(r=>{if(!r.isDirectory())return;let n=Ae.join(t,r.name,"meta.json");if(!U.existsSync(n))return;let a=U.statSync(n),s=this._lastOcrMtimes[r.name]||0;if(a.mtimeMs<=s||(this._lastOcrMtimes[r.name]=a.mtimeMs,this._autoSyncRunning))return;this._autoSyncRunning=!0;let i=z(e,this.settings,void 0,void 0);if(!i.path){this._autoSyncRunning=!1;return}let c=`"${i.path}" -m paperforge --vault "${e}" sync`;(0,ge.exec)(c,{timeout:3e4,encoding:"utf-8"},()=>{this._autoSyncRunning=!1,this._memoryStatusText=null})})}catch(r){}}readPaperforgeJson(){let e=this.app.vault.adapter.basePath,t=Ae.join(e,"paperforge.json"),r={system_dir:"System",resources_dir:"Resources",literature_dir:"Literature",base_dir:"Bases"};try{if(!U.existsSync(t))return r;let n=U.readFileSync(t,"utf-8"),a=JSON.parse(n),s=a.vault_config||{};return{system_dir:s.system_dir||a.system_dir||r.system_dir,resources_dir:s.resources_dir||a.resources_dir||r.resources_dir,literature_dir:s.literature_dir||a.literature_dir||r.literature_dir,base_dir:s.base_dir||a.base_dir||r.base_dir}}catch(n){return console.warn("PaperForge: Failed to read paperforge.json, using defaults",n),r}}savePaperforgeJson(e){let t=this.app.vault.adapter.basePath,r=Ae.join(t,"paperforge.json"),n={};try{U.existsSync(r)&&(n=JSON.parse(U.readFileSync(r,"utf-8")))}catch(s){console.warn("PaperForge: Failed to read paperforge.json for update",s)}(!n.vault_config||typeof n.vault_config!="object")&&(n.vault_config={});let a=["system_dir","resources_dir","literature_dir","base_dir"];for(let s of a)e[s]!==void 0&&(n.vault_config[s]=e[s]);n.schema_version||(n.schema_version="2");for(let s of a)delete n[s];try{if(U.writeFileSync(r,JSON.stringify(n,null,2),"utf-8"),this.settings){let s=this.readPaperforgeJson();this.settings.system_dir=s.system_dir,this.settings.resources_dir=s.resources_dir,this.settings.literature_dir=s.literature_dir,this.settings.base_dir=s.base_dir}}catch(s){console.error("PaperForge: Failed to write paperforge.json",s),new Y.Notice("PaperForge: Failed to save configuration to paperforge.json")}}onunload(){this._pollTimer&&clearInterval(this._pollTimer),this.app.workspace.detachLeavesOfType(ke)}async loadSettings(){this.settings=Object.assign({},Oe,await this.loadData()),this.settings.features&&Oe.features&&(this.settings.features=Object.assign({},Oe.features,this.settings.features||{})),this.settings.frozen_skills||(this.settings.frozen_skills={});let e=this.readPaperforgeJson();if(this.settings.system_dir=e.system_dir,this.settings.resources_dir=e.resources_dir,this.settings.literature_dir=e.literature_dir,this.settings.base_dir=e.base_dir,this.settings.python_path&&this.settings.python_path.trim()){let t=this.settings.python_path.trim();U.existsSync(t)?this.settings._python_path_stale=!1:(console.warn(`PaperForge: Saved python_path "${t}" no longer exists - showing stale warning`),this.settings._python_path_stale=!0)}}async saveSettings(){let e={};for(let t of Object.keys(Oe))t in this.settings&&(e[t]=this.settings[t]);await this.saveData(e)}_checkReleaseNotes(){let e=this.manifest.version;if(this.settings.last_seen_version===e)return;let a=(it().versions||[]).find(i=>i.version===e);class s extends Y.Modal{constructor(c,l){super(c),this._entry=l}onOpen(){let{contentEl:c}=this;if(c.createEl("h2",{text:`PaperForge v${e} \u66F4\u65B0\u8BF4\u660E`}),this._entry){if(c.createEl("p",{text:this._entry.title,cls:"paperforge-modal-subtitle"}),this._entry.breaking_or_migration&&this._entry.breaking_or_migration.length>0){c.createEl("h4",{text:"\u884C\u4E3A\u53D8\u66F4 / \u8FC1\u79FB\u6CE8\u610F"});for(let l of this._entry.breaking_or_migration)c.createEl("p",{text:`\u2022 ${l}`,cls:"paperforge-modal-item"})}if(this._entry.new_features&&this._entry.new_features.length>0){c.createEl("h4",{text:"\u65B0\u529F\u80FD"});for(let l of this._entry.new_features)c.createEl("p",{text:`\u2022 ${l}`,cls:"paperforge-modal-item"})}if(this._entry.fixes&&this._entry.fixes.length>0){c.createEl("h4",{text:"\u4FEE\u590D"});for(let l of this._entry.fixes)c.createEl("p",{text:`\u2022 ${l}`,cls:"paperforge-modal-item"})}if(this._entry.recommended_actions&&this._entry.recommended_actions.length>0){let l=c.createEl("div",{cls:"paperforge-release-recommended"});l.createEl("h4",{text:"\u5EFA\u8BAE\u64CD\u4F5C",cls:""}),l.style.marginBottom="8px";for(let _ of this._entry.recommended_actions)l.createEl("p",{text:`\u2022 ${_}`,cls:"paperforge-release-item-bold"})}}else c.createEl("p",{text:"\u7248\u672C\u5DF2\u66F4\u65B0\u81F3 v"+e+"\uFF0C\u8BF7\u524D\u5F80\u8BBE\u7F6E \u2192 \u66F4\u65B0\u4E0E\u624B\u518C \u67E5\u770B\u5B8C\u6574\u66F4\u65B0\u8BB0\u5F55\u3002"});new Y.Setting(c).addButton(l=>l.setButtonText("\u77E5\u9053\u4E86").setCta().onClick(()=>{this.close()}))}onClose(){let{contentEl:c}=this;c.empty()}}new s(this.app,a).open(),this.settings.last_seen_version=e,this.saveSettings()}};
|