main.js 103 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541
  1. /*
  2. THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
  3. if you want to view the source, please visit the github repository of this plugin
  4. */
  5. var __defProp = Object.defineProperty;
  6. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  7. var __getOwnPropNames = Object.getOwnPropertyNames;
  8. var __hasOwnProp = Object.prototype.hasOwnProperty;
  9. var __export = (target, all) => {
  10. for (var name in all)
  11. __defProp(target, name, { get: all[name], enumerable: true });
  12. };
  13. var __copyProps = (to, from, except, desc) => {
  14. if (from && typeof from === "object" || typeof from === "function") {
  15. for (let key of __getOwnPropNames(from))
  16. if (!__hasOwnProp.call(to, key) && key !== except)
  17. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  18. }
  19. return to;
  20. };
  21. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  22. // src/main.ts
  23. var main_exports = {};
  24. __export(main_exports, {
  25. default: () => AttachmentManagementPlugin
  26. });
  27. module.exports = __toCommonJS(main_exports);
  28. var import_obsidian12 = require("obsidian");
  29. // src/settings/settings.ts
  30. var import_obsidian4 = require("obsidian");
  31. // src/lib/constant.ts
  32. var SETTINGS_VARIABLES_DATES = "${date}";
  33. var SETTINGS_VARIABLES_NOTEPATH = "${notepath}";
  34. var SETTINGS_VARIABLES_NOTENAME = "${notename}";
  35. var SETTINGS_VARIABLES_NOTEPARENT = "${parent}";
  36. var SETTINGS_VARIABLES_ORIGINALNAME = "${originalname}";
  37. var SETTINGS_VARIABLES_MD5 = "${md5}";
  38. var SETTINGS_ROOT_OBSFOLDER = "obsFolder";
  39. var SETTINGS_ROOT_INFOLDER = "inFolderBelow";
  40. var SETTINGS_ROOT_NEXTTONOTE = "nextToNote";
  41. // src/model/extensionOverride.ts
  42. var import_obsidian3 = require("obsidian");
  43. // src/utils.ts
  44. var import_obsidian2 = require("obsidian");
  45. // src/i18n/index.ts
  46. var import_obsidian = require("obsidian");
  47. // src/i18n/locales/ja.ts
  48. var ja = {
  49. common: {
  50. cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB"
  51. },
  52. settings: {
  53. title: "Attachment Management \u8A2D\u5B9A",
  54. rootPath: {
  55. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u5148\u30EB\u30FC\u30C8\u30D1\u30B9",
  56. desc: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D1\u30B9\u3092\u9078\u629E",
  57. options: {
  58. obsidian: "Obsidian \u306E\u8A2D\u5B9A\u3092\u30B3\u30D4\u30FC",
  59. inFolder: "\u6307\u5B9A\u3057\u305F\u30D5\u30A9\u30EB\u30C0\u5185",
  60. nextToNote: "\u30CE\u30FC\u30C8\u3068\u540C\u3058\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6307\u5B9A\u3057\u305F\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0"
  61. }
  62. },
  63. rootFolder: {
  64. name: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0",
  65. desc: "\u65B0\u3057\u3044\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0"
  66. },
  67. attachmentPath: {
  68. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9",
  69. desc: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u3002\u5229\u7528\u53EF\u80FD\u306A\u5909\u6570\uFF1A${notepath}\u3001${notename}\u3001${parent}"
  70. },
  71. attachmentFormat: {
  72. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
  73. desc: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u306E\u4ED8\u3051\u65B9\u3092\u5B9A\u7FA9\u3057\u307E\u3059\u3002\u5229\u7528\u53EF\u80FD\u306A\u5909\u6570\uFF1A${date}\u3001${notename}\u3001${md5}\u3001${originalname}\u3002"
  74. },
  75. dateFormat: {
  76. name: "\u65E5\u4ED8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
  77. desc: "\u4F7F\u7528\u3059\u308B Moment.js \u306E\u65E5\u4ED8\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
  78. linkText: "Moment.js \u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u30AA\u30D7\u30B7\u30E7\u30F3"
  79. },
  80. autoRename: {
  81. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u81EA\u52D5\u3067\u30EA\u30CD\u30FC\u30E0",
  82. desc: "\u5BFE\u5FDC\u3059\u308B md/canvas \u30D5\u30A1\u30A4\u30EB\u304C\u7F6E\u304B\u308C\u3066\u3044\u308B\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u3092\u5909\u66F4\u3059\u308B\u3068\u3001\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30EB\u30C0/\u30D5\u30A1\u30A4\u30EB\u540D\u3082\u81EA\u52D5\u7684\u306B\u5909\u66F4\u3055\u308C\u307E\u3059\u3002"
  83. },
  84. extensionOverride: {
  85. name: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A",
  86. desc: "\u7279\u5B9A\u306E\u62E1\u5F35\u5B50\uFF08\u4F8B\uFF1Apdf \u3084 zip\uFF09\u3092\u6301\u3064\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u81EA\u52D5\u30EA\u30CD\u30FC\u30E0\u3057\u305F\u3044\u5834\u5408\u3001\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002",
  87. addButton: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u8FFD\u52A0",
  88. extension: {
  89. name: "\u62E1\u5F35\u5B50",
  90. desc: "\u4E0A\u66F8\u304D\u3059\u308B\u62E1\u5F35\u5B50",
  91. placeholder: "pdf|docx?"
  92. },
  93. tooltips: {
  94. remove: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u524A\u9664",
  95. edit: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u7DE8\u96C6",
  96. save: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4FDD\u5B58"
  97. },
  98. saveNotice: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F"
  99. },
  100. excludeExtension: {
  101. name: "\u9664\u5916\u3059\u308B\u62E1\u5F35\u5B50\u306E\u30D1\u30BF\u30FC\u30F3",
  102. desc: "\u51E6\u7406\u5BFE\u8C61\u304B\u3089\u9664\u5916\u3059\u308B\u62E1\u5F35\u5B50\u3092\u6B63\u898F\u8868\u73FE\u3067\u6307\u5B9A\u3057\u307E\u3059\u3002",
  103. placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
  104. },
  105. excludedPaths: {
  106. name: "\u9664\u5916\u30D1\u30B9",
  107. desc: "\u30EA\u30CD\u30FC\u30E0\u304B\u3089\u9664\u5916\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u306E\u30D5\u30EB\u30D1\u30B9\u3092\u30BB\u30DF\u30B3\u30ED\u30F3\uFF08;\uFF09\u3067\u533A\u5207\u3063\u3066\u6307\u5B9A\u3057\u307E\u3059\uFF08\u5927\u6587\u5B57\u3068\u5C0F\u6587\u5B57\u3092\u533A\u5225\u3057\u3001\u5148\u982D\u306B\u30B9\u30E9\u30C3\u30B7\u30E5\u300C/\u300D\u3092\u4ED8\u3051\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF09\u3002"
  108. },
  109. excludeSubpaths: {
  110. name: "\u30B5\u30D6\u30D1\u30B9\u3092\u9664\u5916",
  111. desc: "\u3053\u306E\u30AA\u30D7\u30B7\u30E7\u30F3\u3092\u30AA\u30F3\u306B\u3059\u308B\u3068\u3001\u4E0A\u8A18\u3067\u6307\u5B9A\u3057\u305F\u30D5\u30A9\u30EB\u30C0\u30D1\u30B9\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0\u3082\u9664\u5916\u3055\u308C\u307E\u3059\u3002"
  112. }
  113. },
  114. override: {
  115. title: "\u4E0A\u66F8\u304D\u8A2D\u5B9A",
  116. menuTitle: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u4E0A\u66F8\u304D",
  117. addExtensionOverrides: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u8FFD\u52A0",
  118. extension: {
  119. name: "\u62E1\u5F35\u5B50",
  120. desc: "\u4E0A\u66F8\u304D\u3059\u308B\u62E1\u5F35\u5B50",
  121. placeholder: "pdf"
  122. },
  123. buttons: {
  124. reset: "\u30EA\u30BB\u30C3\u30C8",
  125. submit: "\u9001\u4FE1"
  126. },
  127. notifications: {
  128. reset: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F",
  129. overridden: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u4E0A\u66F8\u304D\u3057\u307E\u3057\u305F"
  130. }
  131. },
  132. extensionOverride: {
  133. title: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A",
  134. rootPath: {
  135. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u4FDD\u5B58\u5148\u30EB\u30FC\u30C8\u30D1\u30B9",
  136. desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30EB\u30FC\u30C8\u30D1\u30B9\u3092\u9078\u629E"
  137. },
  138. rootFolder: {
  139. name: "\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0",
  140. desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0"
  141. },
  142. attachmentPath: {
  143. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9",
  144. desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u30EB\u30FC\u30C8\u30D5\u30A9\u30EB\u30C0\u5185\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9"
  145. },
  146. attachmentFormat: {
  147. name: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8",
  148. desc: "\u3053\u306E\u62E1\u5F35\u5B50\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u306E\u4ED8\u3051\u65B9\u3092\u5B9A\u7FA9\u3057\u307E\u3059"
  149. },
  150. buttons: {
  151. save: "\u4FDD\u5B58"
  152. }
  153. },
  154. confirm: {
  155. title: "\u30D2\u30F3\u30C8",
  156. message: "\u3053\u306E\u64CD\u4F5C\u306F\u5143\u306B\u623B\u305B\u305A\u3001\u5B9F\u9A13\u7684\u306A\u3082\u306E\u3067\u3059\u3002\u6700\u521D\u306B Vault \u3092\u30D0\u30C3\u30AF\u30A2\u30C3\u30D7\u3057\u3066\u304F\u3060\u3055\u3044\uFF01\u672C\u5F53\u306B\u7D9A\u884C\u3057\u307E\u3059\u304B\uFF1F",
  157. continue: "\u7D9A\u884C"
  158. },
  159. notices: {
  160. fileExcluded: "{path} \u306F\u9664\u5916\u3055\u308C\u307E\u3057\u305F",
  161. overrideRemoved: "{path} \u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u524A\u9664\u3057\u307E\u3057\u305F",
  162. fileRenamed: "{from} \u304B\u3089 {to} \u306B\u30EA\u30CD\u30FC\u30E0\u3057\u307E\u3057\u305F",
  163. filesRenamedBatch: "{count} \u4EF6\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u30EA\u30CD\u30FC\u30E0\u3057\u307E\u3057\u305F",
  164. arrangeCompleted: "\u6574\u7406\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F",
  165. resetAttachmentSetting: "{path} \u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8\u3057\u307E\u3057\u305F",
  166. error: {
  167. unknownError: "\u4E0D\u660E\u306A\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"
  168. }
  169. },
  170. commands: {
  171. rearrangeAllLinks: "\u30EA\u30F3\u30AF\u3055\u308C\u3066\u3044\u308B\u3059\u3079\u3066\u306E\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u518D\u6574\u7406",
  172. rearrangeActiveLinks: "\u30EA\u30F3\u30AF\u3055\u308C\u3066\u3044\u308B\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u3092\u518D\u6574\u7406",
  173. resetOverrideSetting: "\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3092\u30EA\u30BB\u30C3\u30C8",
  174. clearUnusedStorage: "\u672A\u4F7F\u7528\u306E\u5143\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u30B9\u30C8\u30EC\u30FC\u30B8\u3092\u30AF\u30EA\u30A2"
  175. },
  176. errors: {
  177. canvasNotSupported: "Canvas \u306F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3068\u3057\u3066\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
  178. markdownNotSupported: "Markdown \u306F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3068\u3057\u3066\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002",
  179. extensionEmpty: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u306F\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
  180. duplicateExtension: "\u91CD\u8907\u3057\u305F\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u3002",
  181. excludedExtension: "\u62E1\u5F35\u5B50\u3054\u3068\u306E\u4E0A\u66F8\u304D\u8A2D\u5B9A\u306F\u3001\u9664\u5916\u3055\u308C\u305F\u62E1\u5F35\u5B50\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
  182. attachFormatEmpty: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u3092\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
  183. attachFormatIllegalChar: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u306B\u4E0D\u6B63\u306A\u30D5\u30A1\u30A4\u30EB\u540D\u6587\u5B57\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A{char}",
  184. attachFormatUnknownVariable: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\u5185\u306E\u672A\u77E5\u306E\u5909\u6570\uFF1A{name}",
  185. attachmentPathEmpty: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u3092\u7A7A\u306B\u3067\u304D\u307E\u305B\u3093\u3002",
  186. attachmentPathIllegalChar: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u306B\u4E0D\u6B63\u306A\u30D5\u30A1\u30A4\u30EB\u540D\u6587\u5B57\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\uFF1A{char}",
  187. attachmentPathUnknownVariable: "\u6DFB\u4ED8\u30D5\u30A1\u30A4\u30EB\u306E\u30D1\u30B9\u5185\u306E\u672A\u77E5\u306E\u5909\u6570\uFF1A{name}"
  188. }
  189. };
  190. // src/i18n/locales/en.ts
  191. var en = {
  192. common: {
  193. cancel: "Cancel"
  194. },
  195. settings: {
  196. title: "Attachment Management Settings",
  197. rootPath: {
  198. name: "Root path to save attachment",
  199. desc: "Select root path of attachment",
  200. options: {
  201. obsidian: "Copy Obsidian settings",
  202. inFolder: "In the folder specified below",
  203. nextToNote: "Next to note in folder specified below"
  204. }
  205. },
  206. rootFolder: {
  207. name: "Root folder",
  208. desc: "Root folder of new attachment"
  209. },
  210. attachmentPath: {
  211. name: "Attachment path",
  212. desc: "Path of attachment in root folder, available variables ${notepath}, ${notename}, ${parent}"
  213. },
  214. attachmentFormat: {
  215. name: "Attachment format",
  216. desc: "Define how to name the attachment file, available variables ${date}, ${notename}, ${md5} and ${originalname}."
  217. },
  218. dateFormat: {
  219. name: "Date format",
  220. desc: "Moment date format to use",
  221. linkText: "Moment format options"
  222. },
  223. autoRename: {
  224. name: "Automatically rename attachment",
  225. desc: "Automatically rename the attachment folder/filename when you rename the folder/filename where the corresponding md/canvas file be placed."
  226. },
  227. extensionOverride: {
  228. name: "Extension override",
  229. desc: "Using the extension override if you want to autorename the attachment with a specific extension (e.g. pdf or zip).",
  230. addButton: "Add extension overrides",
  231. extension: {
  232. name: "Extension",
  233. desc: "Extension to override",
  234. placeholder: "pdf|docx?"
  235. },
  236. tooltips: {
  237. remove: "Remove extension override",
  238. edit: "Edit extension override",
  239. save: "Save extension override"
  240. },
  241. saveNotice: "Saved extension override"
  242. },
  243. excludeExtension: {
  244. name: "Exclude extension pattern",
  245. desc: "Regex pattern to exclude certain extensions from being handled.",
  246. placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
  247. },
  248. excludedPaths: {
  249. name: "Excluded paths",
  250. desc: "Provide the full path of the folder names (case sensitive and without leading slash '/') divided by semicolon (;) to be excluded from renaming."
  251. },
  252. excludeSubpaths: {
  253. name: "Exclude subpaths",
  254. desc: "Turn on this option if you want to also exclude all subfolders of the folder paths provided above."
  255. }
  256. },
  257. override: {
  258. title: "Overriding Settings",
  259. menuTitle: "Overriding attachment setting",
  260. addExtensionOverrides: "Add extension overrides",
  261. extension: {
  262. name: "Extension",
  263. desc: "Extension to override",
  264. placeholder: "pdf"
  265. },
  266. buttons: {
  267. reset: "Reset",
  268. submit: "Submit"
  269. },
  270. notifications: {
  271. reset: "Reset attachment setting of {path}",
  272. overridden: "Overridden attachment setting of {path}"
  273. }
  274. },
  275. extensionOverride: {
  276. title: "Extension Override Settings",
  277. rootPath: {
  278. name: "Root path to save attachment",
  279. desc: "Select root path of attachment for this extension"
  280. },
  281. rootFolder: {
  282. name: "Root folder",
  283. desc: "Root folder for this extension"
  284. },
  285. attachmentPath: {
  286. name: "Attachment path",
  287. desc: "Path of attachment in root folder for this extension"
  288. },
  289. attachmentFormat: {
  290. name: "Attachment format",
  291. desc: "Define how to name the attachment file for this extension"
  292. },
  293. buttons: {
  294. save: "Save"
  295. }
  296. },
  297. confirm: {
  298. title: "Tips",
  299. message: "This operation is irreversible and experimental. Please backup your vault first! Are you sure you want to continue?",
  300. continue: "Yes"
  301. },
  302. notices: {
  303. fileExcluded: "{path} was excluded",
  304. overrideRemoved: "Removed override setting of {path}",
  305. fileRenamed: "Renamed {from} to {to}",
  306. filesRenamedBatch: "Renamed {count} attachments",
  307. arrangeCompleted: "Arrange completed",
  308. resetAttachmentSetting: "Reset attachment setting of {path}",
  309. error: {
  310. unknownError: "An unknown error occurred"
  311. }
  312. },
  313. commands: {
  314. rearrangeAllLinks: "Rearrange all linked attachments",
  315. rearrangeActiveLinks: "Rearrange linked attachments",
  316. resetOverrideSetting: "Reset override setting",
  317. clearUnusedStorage: "Clear unused original name storage"
  318. },
  319. errors: {
  320. canvasNotSupported: "Canvas is not supported as an extension override.",
  321. markdownNotSupported: "Markdown is not supported as an extension override.",
  322. extensionEmpty: "Extension override cannot be empty.",
  323. duplicateExtension: "Duplicate extension override.",
  324. excludedExtension: "Extension override cannot be an excluded extension.",
  325. attachFormatEmpty: "Attachment format cannot be empty.",
  326. attachFormatIllegalChar: "Attachment format contains illegal filename character: {char}",
  327. attachFormatUnknownVariable: "Unknown variable in attachment format: {name}",
  328. attachmentPathEmpty: "Attachment path cannot be empty.",
  329. attachmentPathIllegalChar: "Attachment path contains illegal filename character: {char}",
  330. attachmentPathUnknownVariable: "Unknown variable in attachment path: {name}"
  331. }
  332. };
  333. // src/i18n/locales/zh.ts
  334. var zhCn = {
  335. common: {
  336. cancel: "\u53D6\u6D88"
  337. },
  338. settings: {
  339. title: "\u9644\u4EF6\u7BA1\u7406\u8BBE\u7F6E",
  340. rootPath: {
  341. name: "\u9644\u4EF6\u4FDD\u5B58\u6839\u8DEF\u5F84",
  342. desc: "\u9009\u62E9\u9644\u4EF6\u7684\u6839\u8DEF\u5F84",
  343. options: {
  344. obsidian: "\u590D\u5236 Obsidian \u8BBE\u7F6E",
  345. inFolder: "\u5728\u4E0B\u65B9\u6307\u5B9A\u7684\u6587\u4EF6\u5939\u4E2D",
  346. nextToNote: "\u5728\u7B14\u8BB0\u65C1\u8FB9\u7684\u6307\u5B9A\u6587\u4EF6\u5939\u4E2D"
  347. }
  348. },
  349. rootFolder: {
  350. name: "\u6839\u6587\u4EF6\u5939",
  351. desc: "\u65B0\u9644\u4EF6\u7684\u6839\u6587\u4EF6\u5939"
  352. },
  353. attachmentPath: {
  354. name: "\u9644\u4EF6\u8DEF\u5F84",
  355. desc: "\u9644\u4EF6\u5728\u6839\u6587\u4EF6\u5939\u4E2D\u7684\u8DEF\u5F84\uFF0C\u53EF\u7528\u53D8\u91CF ${notepath}\u3001${notename}\u3001${parent}"
  356. },
  357. attachmentFormat: {
  358. name: "\u9644\u4EF6\u683C\u5F0F",
  359. desc: "\u5B9A\u4E49\u5982\u4F55\u547D\u540D\u9644\u4EF6\u6587\u4EF6\uFF0C\u53EF\u7528\u53D8\u91CF ${date}\u3001${notename}\u3001${md5} \u548C ${originalname}\u3002"
  360. },
  361. dateFormat: {
  362. name: "\u65E5\u671F\u683C\u5F0F",
  363. desc: "\u4F7F\u7528\u7684 Moment \u65E5\u671F\u683C\u5F0F",
  364. linkText: "Moment \u683C\u5F0F\u9009\u9879"
  365. },
  366. autoRename: {
  367. name: "\u81EA\u52A8\u91CD\u547D\u540D\u9644\u4EF6",
  368. desc: "\u5F53\u60A8\u91CD\u547D\u540D\u5BF9\u5E94 md/canvas \u6587\u4EF6\u6240\u5728\u7684\u6587\u4EF6\u5939/\u6587\u4EF6\u540D\u65F6\uFF0C\u81EA\u52A8\u91CD\u547D\u540D\u9644\u4EF6\u6587\u4EF6\u5939/\u6587\u4EF6\u540D\u3002"
  369. },
  370. extensionOverride: {
  371. name: "\u6269\u5C55\u540D\u8986\u76D6",
  372. desc: "\u5982\u679C\u60A8\u60F3\u8981\u5BF9\u7279\u5B9A\u6269\u5C55\u540D\u7684\u9644\u4EF6\u8FDB\u884C\u81EA\u52A8\u91CD\u547D\u540D\uFF08\u4F8B\u5982 pdf \u6216 zip),\u8BF7\u4F7F\u7528\u6269\u5C55\u540D\u8986\u76D6\u3002",
  373. addButton: "\u6DFB\u52A0\u6269\u5C55\u540D\u8986\u76D6",
  374. extension: {
  375. name: "\u6269\u5C55\u540D",
  376. desc: "\u8981\u8986\u76D6\u7684\u6269\u5C55\u540D",
  377. placeholder: "pdf|docx?"
  378. },
  379. tooltips: {
  380. remove: "\u79FB\u9664\u6269\u5C55\u540D\u8986\u76D6",
  381. edit: "\u7F16\u8F91\u6269\u5C55\u540D\u8986\u76D6",
  382. save: "\u4FDD\u5B58\u6269\u5C55\u540D\u8986\u76D6"
  383. },
  384. saveNotice: "\u5DF2\u4FDD\u5B58\u6269\u5C55\u540D\u8986\u76D6"
  385. },
  386. excludeExtension: {
  387. name: "\u6392\u9664\u6269\u5C55\u540D\u6A21\u5F0F",
  388. desc: "\u7528\u4E8E\u6392\u9664\u67D0\u4E9B\u6269\u5C55\u540D\u4E0D\u88AB\u5904\u7406\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\u6A21\u5F0F\u3002",
  389. placeholder: "pdf|docx?|xlsx?|pptx?|zip|rar"
  390. },
  391. excludedPaths: {
  392. name: "\u6392\u9664\u8DEF\u5F84",
  393. desc: "\u63D0\u4F9B\u8981\u4ECE\u91CD\u547D\u540D\u4E2D\u6392\u9664\u7684\u6587\u4EF6\u5939\u540D\u79F0\u7684\u5B8C\u6574\u8DEF\u5F84\uFF08\u533A\u5206\u5927\u5C0F\u5199\u4E14\u4E0D\u5E26\u524D\u5BFC\u659C\u6760 '/'\uFF09\uFF0C\u7528\u5206\u53F7\uFF08;\uFF09\u5206\u9694\u3002"
  394. },
  395. excludeSubpaths: {
  396. name: "\u6392\u9664\u5B50\u8DEF\u5F84",
  397. desc: "\u5982\u679C\u60A8\u8FD8\u60F3\u6392\u9664\u4E0A\u9762\u63D0\u4F9B\u7684\u6587\u4EF6\u5939\u8DEF\u5F84\u7684\u6240\u6709\u5B50\u6587\u4EF6\u5939\uFF0C\u8BF7\u6253\u5F00\u6B64\u9009\u9879\u3002"
  398. }
  399. },
  400. override: {
  401. title: "\u8986\u76D6\u8BBE\u7F6E",
  402. menuTitle: "\u8986\u76D6\u9644\u4EF6\u8BBE\u7F6E",
  403. addExtensionOverrides: "\u6DFB\u52A0\u6269\u5C55\u540D\u8986\u76D6",
  404. extension: {
  405. name: "\u6269\u5C55\u540D",
  406. desc: "\u8981\u8986\u76D6\u7684\u6269\u5C55\u540D",
  407. placeholder: "pdf"
  408. },
  409. buttons: {
  410. reset: "\u91CD\u7F6E",
  411. submit: "\u63D0\u4EA4"
  412. },
  413. notifications: {
  414. reset: "\u5DF2\u91CD\u7F6E {path} \u7684\u9644\u4EF6\u8BBE\u7F6E",
  415. overridden: "\u5DF2\u8986\u76D6 {path} \u7684\u9644\u4EF6\u8BBE\u7F6E"
  416. }
  417. },
  418. extensionOverride: {
  419. title: "\u6269\u5C55\u540D\u8986\u76D6\u8BBE\u7F6E",
  420. rootPath: {
  421. name: "\u9644\u4EF6\u4FDD\u5B58\u6839\u8DEF\u5F84",
  422. desc: "\u9009\u62E9\u6B64\u6269\u5C55\u540D\u7684\u9644\u4EF6\u6839\u8DEF\u5F84"
  423. },
  424. rootFolder: {
  425. name: "\u6839\u6587\u4EF6\u5939",
  426. desc: "\u6B64\u6269\u5C55\u540D\u7684\u6839\u6587\u4EF6\u5939"
  427. },
  428. attachmentPath: {
  429. name: "\u9644\u4EF6\u8DEF\u5F84",
  430. desc: "\u6B64\u6269\u5C55\u540D\u5728\u6839\u6587\u4EF6\u5939\u4E2D\u7684\u9644\u4EF6\u8DEF\u5F84"
  431. },
  432. attachmentFormat: {
  433. name: "\u9644\u4EF6\u683C\u5F0F",
  434. desc: "\u5B9A\u4E49\u6B64\u6269\u5C55\u540D\u7684\u9644\u4EF6\u6587\u4EF6\u547D\u540D\u65B9\u5F0F"
  435. },
  436. buttons: {
  437. save: "\u4FDD\u5B58"
  438. }
  439. },
  440. confirm: {
  441. title: "\u63D0\u793A",
  442. message: "\u6B64\u64CD\u4F5C\u4E0D\u53EF\u9006\u4E14\u4E3A\u5B9E\u9A8C\u6027\u529F\u80FD\uFF0C\u8BF7\u5148\u5907\u4EFD\u60A8\u7684\u5E93\uFF01\u786E\u5B9A\u8981\u7EE7\u7EED\u5417\uFF1F",
  443. continue: "\u7EE7\u7EED"
  444. },
  445. notices: {
  446. fileExcluded: "{path} \u5DF2\u88AB\u6392\u9664",
  447. overrideRemoved: "\u5DF2\u79FB\u9664 {path} \u7684\u8986\u76D6\u8BBE\u7F6E",
  448. fileRenamed: "\u5DF2\u5C06 {from} \u91CD\u547D\u540D\u4E3A {to}",
  449. filesRenamedBatch: "\u5DF2\u91CD\u547D\u540D {count} \u4E2A\u9644\u4EF6",
  450. arrangeCompleted: "\u6574\u7406\u5B8C\u6210",
  451. resetAttachmentSetting: "\u5DF2\u91CD\u7F6E {path} \u7684\u9644\u4EF6\u8BBE\u7F6E",
  452. error: {
  453. unknownError: "\u53D1\u751F\u672A\u77E5\u9519\u8BEF"
  454. }
  455. },
  456. commands: {
  457. rearrangeAllLinks: "\u91CD\u65B0\u6574\u7406\u6240\u6709\u94FE\u63A5\u7684\u9644\u4EF6",
  458. rearrangeActiveLinks: "\u91CD\u65B0\u6574\u7406\u94FE\u63A5\u7684\u9644\u4EF6",
  459. resetOverrideSetting: "\u91CD\u7F6E\u8986\u76D6\u8BBE\u7F6E",
  460. clearUnusedStorage: "\u6E05\u7406\u672A\u4F7F\u7528\u7684\u539F\u59CB\u6587\u4EF6\u540D\u5B58\u50A8"
  461. },
  462. errors: {
  463. canvasNotSupported: "\u4E0D\u652F\u6301\u5C06 Canvas \u4F5C\u4E3A\u6269\u5C55\u8986\u76D6\u3002",
  464. markdownNotSupported: "\u4E0D\u652F\u6301\u5C06 Markdown \u4F5C\u4E3A\u6269\u5C55\u8986\u76D6\u3002",
  465. extensionEmpty: "\u6269\u5C55\u8986\u76D6\u4E0D\u80FD\u4E3A\u7A7A\u3002",
  466. duplicateExtension: "\u91CD\u590D\u7684\u6269\u5C55\u8986\u76D6\u3002",
  467. excludedExtension: "\u6269\u5C55\u8986\u76D6\u4E0D\u80FD\u662F\u88AB\u6392\u9664\u7684\u6269\u5C55\u3002",
  468. attachFormatEmpty: "\u9644\u4EF6\u683C\u5F0F\u4E0D\u80FD\u4E3A\u7A7A\u3002",
  469. attachFormatIllegalChar: "\u9644\u4EF6\u683C\u5F0F\u5305\u542B\u975E\u6CD5\u6587\u4EF6\u540D\u5B57\u7B26\uFF1A{char}",
  470. attachFormatUnknownVariable: "\u9644\u4EF6\u683C\u5F0F\u4E2D\u5B58\u5728\u672A\u77E5\u53D8\u91CF\uFF1A{name}",
  471. attachmentPathEmpty: "\u9644\u4EF6\u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A\u3002",
  472. attachmentPathIllegalChar: "\u9644\u4EF6\u8DEF\u5F84\u5305\u542B\u975E\u6CD5\u6587\u4EF6\u540D\u5B57\u7B26\uFF1A{char}",
  473. attachmentPathUnknownVariable: "\u9644\u4EF6\u8DEF\u5F84\u4E2D\u5B58\u5728\u672A\u77E5\u53D8\u91CF\uFF1A{name}"
  474. }
  475. };
  476. // src/i18n/loader.ts
  477. function loadAllTranslations() {
  478. registerTranslations("en", en);
  479. registerTranslations("zh", zhCn);
  480. registerTranslations("ja", ja);
  481. }
  482. // src/i18n/index.ts
  483. var currentLanguage = "en";
  484. var translations = {
  485. en: {},
  486. zh: {},
  487. ja: {}
  488. };
  489. function setLanguage(language) {
  490. currentLanguage = language;
  491. }
  492. function registerTranslations(language, translationMap) {
  493. translations[language] = { ...translations[language], ...translationMap };
  494. }
  495. function t(key, ...args) {
  496. const params = args[0];
  497. const keys = key.split(".");
  498. let value = translations[currentLanguage];
  499. for (const k of keys) {
  500. if (value && typeof value === "object" && k in value) {
  501. value = value[k];
  502. } else {
  503. if (currentLanguage !== "en") {
  504. let fallbackValue = translations["en"];
  505. for (const fk of keys) {
  506. if (fallbackValue && typeof fallbackValue === "object" && fk in fallbackValue) {
  507. fallbackValue = fallbackValue[fk];
  508. } else {
  509. fallbackValue = key;
  510. break;
  511. }
  512. }
  513. value = fallbackValue;
  514. } else {
  515. value = key;
  516. }
  517. break;
  518. }
  519. }
  520. let result = typeof value === "string" ? value : key;
  521. if (params) {
  522. Object.entries(params).forEach(([paramKey, paramValue]) => {
  523. result = result.replace(new RegExp(`\\{${paramKey}\\}`, "g"), String(paramValue));
  524. });
  525. }
  526. return result;
  527. }
  528. function detectLanguage() {
  529. const locale = import_obsidian.moment.locale();
  530. if (locale.startsWith("zh")) {
  531. return "zh";
  532. }
  533. if (locale.startsWith("ja")) {
  534. return "ja";
  535. }
  536. return "en";
  537. }
  538. function initI18n(language) {
  539. loadAllTranslations();
  540. const initialLanguage = language || detectLanguage();
  541. setLanguage(initialLanguage);
  542. }
  543. // node_modules/.pnpm/ts-md5@1.3.1/node_modules/ts-md5/dist/esm/md5.js
  544. var Md5 = class _Md5 {
  545. constructor() {
  546. this._dataLength = 0;
  547. this._bufferLength = 0;
  548. this._state = new Int32Array(4);
  549. this._buffer = new ArrayBuffer(68);
  550. this._buffer8 = new Uint8Array(this._buffer, 0, 68);
  551. this._buffer32 = new Uint32Array(this._buffer, 0, 17);
  552. this.start();
  553. }
  554. static hashStr(str, raw = false) {
  555. return this.onePassHasher.start().appendStr(str).end(raw);
  556. }
  557. static hashAsciiStr(str, raw = false) {
  558. return this.onePassHasher.start().appendAsciiStr(str).end(raw);
  559. }
  560. static _hex(x) {
  561. const hc = _Md5.hexChars;
  562. const ho = _Md5.hexOut;
  563. let n;
  564. let offset;
  565. let j;
  566. let i;
  567. for (i = 0; i < 4; i += 1) {
  568. offset = i * 8;
  569. n = x[i];
  570. for (j = 0; j < 8; j += 2) {
  571. ho[offset + 1 + j] = hc.charAt(n & 15);
  572. n >>>= 4;
  573. ho[offset + 0 + j] = hc.charAt(n & 15);
  574. n >>>= 4;
  575. }
  576. }
  577. return ho.join("");
  578. }
  579. static _md5cycle(x, k) {
  580. let a = x[0];
  581. let b = x[1];
  582. let c = x[2];
  583. let d = x[3];
  584. a += (b & c | ~b & d) + k[0] - 680876936 | 0;
  585. a = (a << 7 | a >>> 25) + b | 0;
  586. d += (a & b | ~a & c) + k[1] - 389564586 | 0;
  587. d = (d << 12 | d >>> 20) + a | 0;
  588. c += (d & a | ~d & b) + k[2] + 606105819 | 0;
  589. c = (c << 17 | c >>> 15) + d | 0;
  590. b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
  591. b = (b << 22 | b >>> 10) + c | 0;
  592. a += (b & c | ~b & d) + k[4] - 176418897 | 0;
  593. a = (a << 7 | a >>> 25) + b | 0;
  594. d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
  595. d = (d << 12 | d >>> 20) + a | 0;
  596. c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
  597. c = (c << 17 | c >>> 15) + d | 0;
  598. b += (c & d | ~c & a) + k[7] - 45705983 | 0;
  599. b = (b << 22 | b >>> 10) + c | 0;
  600. a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
  601. a = (a << 7 | a >>> 25) + b | 0;
  602. d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
  603. d = (d << 12 | d >>> 20) + a | 0;
  604. c += (d & a | ~d & b) + k[10] - 42063 | 0;
  605. c = (c << 17 | c >>> 15) + d | 0;
  606. b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
  607. b = (b << 22 | b >>> 10) + c | 0;
  608. a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
  609. a = (a << 7 | a >>> 25) + b | 0;
  610. d += (a & b | ~a & c) + k[13] - 40341101 | 0;
  611. d = (d << 12 | d >>> 20) + a | 0;
  612. c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
  613. c = (c << 17 | c >>> 15) + d | 0;
  614. b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
  615. b = (b << 22 | b >>> 10) + c | 0;
  616. a += (b & d | c & ~d) + k[1] - 165796510 | 0;
  617. a = (a << 5 | a >>> 27) + b | 0;
  618. d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
  619. d = (d << 9 | d >>> 23) + a | 0;
  620. c += (d & b | a & ~b) + k[11] + 643717713 | 0;
  621. c = (c << 14 | c >>> 18) + d | 0;
  622. b += (c & a | d & ~a) + k[0] - 373897302 | 0;
  623. b = (b << 20 | b >>> 12) + c | 0;
  624. a += (b & d | c & ~d) + k[5] - 701558691 | 0;
  625. a = (a << 5 | a >>> 27) + b | 0;
  626. d += (a & c | b & ~c) + k[10] + 38016083 | 0;
  627. d = (d << 9 | d >>> 23) + a | 0;
  628. c += (d & b | a & ~b) + k[15] - 660478335 | 0;
  629. c = (c << 14 | c >>> 18) + d | 0;
  630. b += (c & a | d & ~a) + k[4] - 405537848 | 0;
  631. b = (b << 20 | b >>> 12) + c | 0;
  632. a += (b & d | c & ~d) + k[9] + 568446438 | 0;
  633. a = (a << 5 | a >>> 27) + b | 0;
  634. d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
  635. d = (d << 9 | d >>> 23) + a | 0;
  636. c += (d & b | a & ~b) + k[3] - 187363961 | 0;
  637. c = (c << 14 | c >>> 18) + d | 0;
  638. b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
  639. b = (b << 20 | b >>> 12) + c | 0;
  640. a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
  641. a = (a << 5 | a >>> 27) + b | 0;
  642. d += (a & c | b & ~c) + k[2] - 51403784 | 0;
  643. d = (d << 9 | d >>> 23) + a | 0;
  644. c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
  645. c = (c << 14 | c >>> 18) + d | 0;
  646. b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
  647. b = (b << 20 | b >>> 12) + c | 0;
  648. a += (b ^ c ^ d) + k[5] - 378558 | 0;
  649. a = (a << 4 | a >>> 28) + b | 0;
  650. d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
  651. d = (d << 11 | d >>> 21) + a | 0;
  652. c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
  653. c = (c << 16 | c >>> 16) + d | 0;
  654. b += (c ^ d ^ a) + k[14] - 35309556 | 0;
  655. b = (b << 23 | b >>> 9) + c | 0;
  656. a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
  657. a = (a << 4 | a >>> 28) + b | 0;
  658. d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
  659. d = (d << 11 | d >>> 21) + a | 0;
  660. c += (d ^ a ^ b) + k[7] - 155497632 | 0;
  661. c = (c << 16 | c >>> 16) + d | 0;
  662. b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
  663. b = (b << 23 | b >>> 9) + c | 0;
  664. a += (b ^ c ^ d) + k[13] + 681279174 | 0;
  665. a = (a << 4 | a >>> 28) + b | 0;
  666. d += (a ^ b ^ c) + k[0] - 358537222 | 0;
  667. d = (d << 11 | d >>> 21) + a | 0;
  668. c += (d ^ a ^ b) + k[3] - 722521979 | 0;
  669. c = (c << 16 | c >>> 16) + d | 0;
  670. b += (c ^ d ^ a) + k[6] + 76029189 | 0;
  671. b = (b << 23 | b >>> 9) + c | 0;
  672. a += (b ^ c ^ d) + k[9] - 640364487 | 0;
  673. a = (a << 4 | a >>> 28) + b | 0;
  674. d += (a ^ b ^ c) + k[12] - 421815835 | 0;
  675. d = (d << 11 | d >>> 21) + a | 0;
  676. c += (d ^ a ^ b) + k[15] + 530742520 | 0;
  677. c = (c << 16 | c >>> 16) + d | 0;
  678. b += (c ^ d ^ a) + k[2] - 995338651 | 0;
  679. b = (b << 23 | b >>> 9) + c | 0;
  680. a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
  681. a = (a << 6 | a >>> 26) + b | 0;
  682. d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
  683. d = (d << 10 | d >>> 22) + a | 0;
  684. c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
  685. c = (c << 15 | c >>> 17) + d | 0;
  686. b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
  687. b = (b << 21 | b >>> 11) + c | 0;
  688. a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
  689. a = (a << 6 | a >>> 26) + b | 0;
  690. d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
  691. d = (d << 10 | d >>> 22) + a | 0;
  692. c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
  693. c = (c << 15 | c >>> 17) + d | 0;
  694. b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
  695. b = (b << 21 | b >>> 11) + c | 0;
  696. a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
  697. a = (a << 6 | a >>> 26) + b | 0;
  698. d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
  699. d = (d << 10 | d >>> 22) + a | 0;
  700. c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
  701. c = (c << 15 | c >>> 17) + d | 0;
  702. b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
  703. b = (b << 21 | b >>> 11) + c | 0;
  704. a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
  705. a = (a << 6 | a >>> 26) + b | 0;
  706. d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
  707. d = (d << 10 | d >>> 22) + a | 0;
  708. c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
  709. c = (c << 15 | c >>> 17) + d | 0;
  710. b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
  711. b = (b << 21 | b >>> 11) + c | 0;
  712. x[0] = a + x[0] | 0;
  713. x[1] = b + x[1] | 0;
  714. x[2] = c + x[2] | 0;
  715. x[3] = d + x[3] | 0;
  716. }
  717. /**
  718. * Initialise buffer to be hashed
  719. */
  720. start() {
  721. this._dataLength = 0;
  722. this._bufferLength = 0;
  723. this._state.set(_Md5.stateIdentity);
  724. return this;
  725. }
  726. // Char to code point to to array conversion:
  727. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt
  728. // #Example.3A_Fixing_charCodeAt_to_handle_non-Basic-Multilingual-Plane_characters_if_their_presence_earlier_in_the_string_is_unknown
  729. /**
  730. * Append a UTF-8 string to the hash buffer
  731. * @param str String to append
  732. */
  733. appendStr(str) {
  734. const buf8 = this._buffer8;
  735. const buf32 = this._buffer32;
  736. let bufLen = this._bufferLength;
  737. let code;
  738. let i;
  739. for (i = 0; i < str.length; i += 1) {
  740. code = str.charCodeAt(i);
  741. if (code < 128) {
  742. buf8[bufLen++] = code;
  743. } else if (code < 2048) {
  744. buf8[bufLen++] = (code >>> 6) + 192;
  745. buf8[bufLen++] = code & 63 | 128;
  746. } else if (code < 55296 || code > 56319) {
  747. buf8[bufLen++] = (code >>> 12) + 224;
  748. buf8[bufLen++] = code >>> 6 & 63 | 128;
  749. buf8[bufLen++] = code & 63 | 128;
  750. } else {
  751. code = (code - 55296) * 1024 + (str.charCodeAt(++i) - 56320) + 65536;
  752. if (code > 1114111) {
  753. throw new Error("Unicode standard supports code points up to U+10FFFF");
  754. }
  755. buf8[bufLen++] = (code >>> 18) + 240;
  756. buf8[bufLen++] = code >>> 12 & 63 | 128;
  757. buf8[bufLen++] = code >>> 6 & 63 | 128;
  758. buf8[bufLen++] = code & 63 | 128;
  759. }
  760. if (bufLen >= 64) {
  761. this._dataLength += 64;
  762. _Md5._md5cycle(this._state, buf32);
  763. bufLen -= 64;
  764. buf32[0] = buf32[16];
  765. }
  766. }
  767. this._bufferLength = bufLen;
  768. return this;
  769. }
  770. /**
  771. * Append an ASCII string to the hash buffer
  772. * @param str String to append
  773. */
  774. appendAsciiStr(str) {
  775. const buf8 = this._buffer8;
  776. const buf32 = this._buffer32;
  777. let bufLen = this._bufferLength;
  778. let i;
  779. let j = 0;
  780. for (; ; ) {
  781. i = Math.min(str.length - j, 64 - bufLen);
  782. while (i--) {
  783. buf8[bufLen++] = str.charCodeAt(j++);
  784. }
  785. if (bufLen < 64) {
  786. break;
  787. }
  788. this._dataLength += 64;
  789. _Md5._md5cycle(this._state, buf32);
  790. bufLen = 0;
  791. }
  792. this._bufferLength = bufLen;
  793. return this;
  794. }
  795. /**
  796. * Append a byte array to the hash buffer
  797. * @param input array to append
  798. */
  799. appendByteArray(input) {
  800. const buf8 = this._buffer8;
  801. const buf32 = this._buffer32;
  802. let bufLen = this._bufferLength;
  803. let i;
  804. let j = 0;
  805. for (; ; ) {
  806. i = Math.min(input.length - j, 64 - bufLen);
  807. while (i--) {
  808. buf8[bufLen++] = input[j++];
  809. }
  810. if (bufLen < 64) {
  811. break;
  812. }
  813. this._dataLength += 64;
  814. _Md5._md5cycle(this._state, buf32);
  815. bufLen = 0;
  816. }
  817. this._bufferLength = bufLen;
  818. return this;
  819. }
  820. /**
  821. * Get the state of the hash buffer
  822. */
  823. getState() {
  824. const s = this._state;
  825. return {
  826. buffer: String.fromCharCode.apply(null, Array.from(this._buffer8)),
  827. buflen: this._bufferLength,
  828. length: this._dataLength,
  829. state: [s[0], s[1], s[2], s[3]]
  830. };
  831. }
  832. /**
  833. * Override the current state of the hash buffer
  834. * @param state New hash buffer state
  835. */
  836. setState(state) {
  837. const buf = state.buffer;
  838. const x = state.state;
  839. const s = this._state;
  840. let i;
  841. this._dataLength = state.length;
  842. this._bufferLength = state.buflen;
  843. s[0] = x[0];
  844. s[1] = x[1];
  845. s[2] = x[2];
  846. s[3] = x[3];
  847. for (i = 0; i < buf.length; i += 1) {
  848. this._buffer8[i] = buf.charCodeAt(i);
  849. }
  850. }
  851. /**
  852. * Hash the current state of the hash buffer and return the result
  853. * @param raw Whether to return the value as an `Int32Array`
  854. */
  855. end(raw = false) {
  856. const bufLen = this._bufferLength;
  857. const buf8 = this._buffer8;
  858. const buf32 = this._buffer32;
  859. const i = (bufLen >> 2) + 1;
  860. this._dataLength += bufLen;
  861. const dataBitsLen = this._dataLength * 8;
  862. buf8[bufLen] = 128;
  863. buf8[bufLen + 1] = buf8[bufLen + 2] = buf8[bufLen + 3] = 0;
  864. buf32.set(_Md5.buffer32Identity.subarray(i), i);
  865. if (bufLen > 55) {
  866. _Md5._md5cycle(this._state, buf32);
  867. buf32.set(_Md5.buffer32Identity);
  868. }
  869. if (dataBitsLen <= 4294967295) {
  870. buf32[14] = dataBitsLen;
  871. } else {
  872. const matches = dataBitsLen.toString(16).match(/(.*?)(.{0,8})$/);
  873. if (matches === null) {
  874. return;
  875. }
  876. const lo = parseInt(matches[2], 16);
  877. const hi = parseInt(matches[1], 16) || 0;
  878. buf32[14] = lo;
  879. buf32[15] = hi;
  880. }
  881. _Md5._md5cycle(this._state, buf32);
  882. return raw ? this._state : _Md5._hex(this._state);
  883. }
  884. };
  885. Md5.stateIdentity = new Int32Array([1732584193, -271733879, -1732584194, 271733878]);
  886. Md5.buffer32Identity = new Int32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
  887. Md5.hexChars = "0123456789abcdef";
  888. Md5.hexOut = [];
  889. Md5.onePassHasher = new Md5();
  890. if (Md5.hashStr("hello") !== "5d41402abc4b2a76b9719d911017c592") {
  891. throw new Error("Md5 self test failed.");
  892. }
  893. // src/utils.ts
  894. var PASTED_IMAGE_PREFIX = "Pasted image ";
  895. var ImageExtensionRegex = /^(jpe?g|png|gif|svg|bmp|eps|webp)$/i;
  896. function isMarkdownFile(extension) {
  897. return extension === "md";
  898. }
  899. function isCanvasFile(extension) {
  900. return extension === "canvas";
  901. }
  902. function isPastedImage(file) {
  903. if (file instanceof import_obsidian2.TFile) {
  904. if (file.name.startsWith(PASTED_IMAGE_PREFIX)) {
  905. return true;
  906. }
  907. }
  908. return false;
  909. }
  910. function isImage(extension) {
  911. const match = extension.match(ImageExtensionRegex);
  912. if (match !== null) {
  913. return true;
  914. }
  915. return false;
  916. }
  917. function stripPaths(src, dst) {
  918. if (src === dst) {
  919. return { stripedSrc: src, stripedDst: dst };
  920. }
  921. const srcParts = src.split("/");
  922. const dstParts = dst.split("/");
  923. if (srcParts.length !== dstParts.length) {
  924. return { stripedSrc: src, stripedDst: dst };
  925. }
  926. for (let i = 0; i < srcParts.length; i++) {
  927. const srcPart = srcParts[i];
  928. const dstPart = dstParts[i];
  929. if (srcPart !== dstPart) {
  930. return {
  931. stripedSrc: srcParts.slice(0, i + 1).join("/"),
  932. stripedDst: dstParts.slice(0, i + 1).join("/")
  933. };
  934. }
  935. }
  936. return { stripedSrc: "", stripedDst: "" };
  937. }
  938. function matchExtension(extension, pattern) {
  939. if (!pattern || pattern === "") return false;
  940. return new RegExp(pattern).test(extension);
  941. }
  942. function isAttachment(app2, settings, filePath) {
  943. let file = null;
  944. if (filePath instanceof import_obsidian2.TAbstractFile) {
  945. file = filePath;
  946. } else {
  947. file = app2.vault.getAbstractFileByPath(filePath);
  948. }
  949. if (file === null || !(file instanceof import_obsidian2.TFile)) {
  950. return false;
  951. }
  952. if (isMarkdownFile(file.extension) || isCanvasFile(file.extension)) {
  953. return false;
  954. }
  955. return !matchExtension(file.extension, settings.excludeExtensionPattern);
  956. }
  957. async function md5sum(adapter, file) {
  958. const md5 = new Md5();
  959. if (!adapter.exists(file.path, true)) {
  960. return "";
  961. }
  962. const content = await adapter.readBinary(file.path);
  963. md5.appendByteArray(new Uint8Array(content));
  964. const ret = md5.end();
  965. return ret.toUpperCase();
  966. }
  967. function validateExtensionEntry(setting, plugin) {
  968. const wrongIndex = [];
  969. if (setting.extensionOverride !== void 0) {
  970. const extOverride = setting.extensionOverride;
  971. if (extOverride.some((ext) => ext.extension === "")) {
  972. wrongIndex.push({ type: "empty", index: extOverride.findIndex((ext) => ext.extension === "") });
  973. }
  974. const duplicate = extOverride.map((ext) => ext.extension).filter((value, index, self) => self.indexOf(value) !== index);
  975. if (duplicate.length > 0) {
  976. duplicate.forEach((dupli) => {
  977. wrongIndex.push({ type: "duplicate", index: extOverride.findIndex((ext) => dupli === ext.extension) });
  978. });
  979. }
  980. const markdown = extOverride.filter((ext) => ext.extension === "md");
  981. if (markdown.length > 0) {
  982. wrongIndex.push({ type: "md", index: extOverride.findIndex((ext) => ext.extension === "md") });
  983. }
  984. const canvas = extOverride.filter((ext) => ext.extension === "canvas");
  985. if (canvas.length > 0) {
  986. wrongIndex.push({ type: "canvas", index: extOverride.findIndex((ext) => ext.extension === "canvas") });
  987. }
  988. const excludedFromSettings = plugin.excludeExtensionPattern.split("|");
  989. const excluded = extOverride.filter((ext) => excludedFromSettings.includes(ext.extension));
  990. if (excluded.length > 0) {
  991. wrongIndex.push({
  992. type: "excluded",
  993. index: extOverride.findIndex((ext) => excludedFromSettings.includes(ext.extension))
  994. });
  995. }
  996. }
  997. return wrongIndex;
  998. }
  999. function generateErrorExtensionMessage(type) {
  1000. if (type === "canvas") {
  1001. new import_obsidian2.Notice(t("errors.canvasNotSupported"));
  1002. } else if (type === "md") {
  1003. new import_obsidian2.Notice(t("errors.markdownNotSupported"));
  1004. } else if (type === "empty") {
  1005. new import_obsidian2.Notice(t("errors.extensionEmpty"));
  1006. } else if (type === "duplicate") {
  1007. new import_obsidian2.Notice(t("errors.duplicateExtension"));
  1008. } else if (type === "excluded") {
  1009. new import_obsidian2.Notice(t("errors.excludedExtension"));
  1010. }
  1011. }
  1012. var ALLOWED_FORMAT_VARS = [
  1013. SETTINGS_VARIABLES_DATES,
  1014. SETTINGS_VARIABLES_NOTENAME,
  1015. SETTINGS_VARIABLES_MD5,
  1016. SETTINGS_VARIABLES_ORIGINALNAME
  1017. ];
  1018. var ILLEGAL_FILENAME_CHARS = /[\\/:*?"<>|]/;
  1019. var VAR_TOKEN_RE = /\$\{[^}]+\}/g;
  1020. function validateAttachFormat(value) {
  1021. var _a;
  1022. const trimmed = value.trim();
  1023. if (trimmed.length === 0) return { type: "empty" };
  1024. const stripped = trimmed.replace(VAR_TOKEN_RE, "");
  1025. const bad = stripped.match(ILLEGAL_FILENAME_CHARS);
  1026. if (bad) return { type: "illegalChar", char: bad[0] };
  1027. const vars = (_a = trimmed.match(VAR_TOKEN_RE)) != null ? _a : [];
  1028. for (const v of vars) {
  1029. if (!ALLOWED_FORMAT_VARS.includes(v)) {
  1030. return { type: "unknownVariable", name: v };
  1031. }
  1032. }
  1033. return null;
  1034. }
  1035. function attachFormatErrorMessage(err) {
  1036. switch (err.type) {
  1037. case "empty":
  1038. return t("errors.attachFormatEmpty");
  1039. case "illegalChar":
  1040. return t("errors.attachFormatIllegalChar", { char: err.char });
  1041. case "unknownVariable":
  1042. return t("errors.attachFormatUnknownVariable", { name: err.name });
  1043. }
  1044. }
  1045. var ALLOWED_PATH_VARS = [SETTINGS_VARIABLES_NOTEPATH, SETTINGS_VARIABLES_NOTENAME, SETTINGS_VARIABLES_NOTEPARENT];
  1046. var ILLEGAL_PATH_CHARS = /[\\:*?"<>|]/;
  1047. function validateAttachmentPath(value) {
  1048. var _a;
  1049. const trimmed = value.trim();
  1050. if (trimmed.length === 0) return { type: "empty" };
  1051. const stripped = trimmed.replace(VAR_TOKEN_RE, "");
  1052. const bad = stripped.match(ILLEGAL_PATH_CHARS);
  1053. if (bad) return { type: "illegalChar", char: bad[0] };
  1054. const vars = (_a = trimmed.match(VAR_TOKEN_RE)) != null ? _a : [];
  1055. for (const v of vars) {
  1056. if (!ALLOWED_PATH_VARS.includes(v)) {
  1057. return { type: "unknownVariable", name: v };
  1058. }
  1059. }
  1060. return null;
  1061. }
  1062. function attachmentPathErrorMessage(err) {
  1063. switch (err.type) {
  1064. case "empty":
  1065. return t("errors.attachmentPathEmpty");
  1066. case "illegalChar":
  1067. return t("errors.attachmentPathIllegalChar", { char: err.char });
  1068. case "unknownVariable":
  1069. return t("errors.attachmentPathUnknownVariable", { name: err.name });
  1070. }
  1071. }
  1072. // src/lib/log.ts
  1073. var DEBUG = false;
  1074. if (DEBUG) console.log("DEBUG is enabled");
  1075. function debugLog(...args) {
  1076. if (DEBUG) {
  1077. console.log((/* @__PURE__ */ new Date()).toISOString().slice(11, 23), ...args);
  1078. }
  1079. }
  1080. // src/model/extensionOverride.ts
  1081. function getExtensionOverrideSetting(extension, settings) {
  1082. if (settings.extensionOverride === void 0 || settings.extensionOverride.length === 0) {
  1083. return { extSetting: void 0 };
  1084. }
  1085. for (let i = 0; i < settings.extensionOverride.length; i++) {
  1086. if (matchExtension(extension, settings.extensionOverride[i].extension)) {
  1087. debugLog(
  1088. "getExtensionOverrideSetting - ",
  1089. settings.extensionOverride[i].extension,
  1090. settings.extensionOverride[i]
  1091. );
  1092. return { extSetting: settings.extensionOverride[i] };
  1093. }
  1094. }
  1095. return { extSetting: void 0 };
  1096. }
  1097. var OverrideExtensionModal = class extends import_obsidian3.Modal {
  1098. constructor(plugin, settings, onSubmit) {
  1099. super(plugin.app);
  1100. this.plugin = plugin;
  1101. this.settings = settings;
  1102. this.onSubmit = onSubmit;
  1103. }
  1104. displaySw(cont) {
  1105. cont.findAll(".setting-item").forEach((el) => {
  1106. var _a;
  1107. if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("override_root_folder_set")) {
  1108. if (this.settings.saveAttE === "obsFolder") {
  1109. el.hide();
  1110. } else {
  1111. el.show();
  1112. }
  1113. }
  1114. });
  1115. }
  1116. onOpen() {
  1117. const { contentEl } = this;
  1118. contentEl.empty();
  1119. contentEl.createEl("h3", {
  1120. text: t("extensionOverride.title")
  1121. });
  1122. new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.rootPath.name")).setDesc(t("extensionOverride.rootPath.desc")).addDropdown(
  1123. (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.settings.saveAttE).onChange(async (value) => {
  1124. this.settings.saveAttE = value;
  1125. this.displaySw(contentEl);
  1126. this.onOpen();
  1127. })
  1128. );
  1129. if (this.settings.saveAttE !== "obsFolder") {
  1130. new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.rootFolder.name")).setDesc(t("extensionOverride.rootFolder.desc")).setClass("override_root_folder_set").addText(
  1131. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.settings.attachmentRoot).onChange(async (value) => {
  1132. this.settings.attachmentRoot = value;
  1133. })
  1134. );
  1135. }
  1136. new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.attachmentPath.name")).setDesc(t("extensionOverride.attachmentPath.desc")).addText(
  1137. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.settings.attachmentPath).onChange(async (value) => {
  1138. this.settings.attachmentPath = value;
  1139. })
  1140. );
  1141. new import_obsidian3.Setting(contentEl).setName(t("extensionOverride.attachmentFormat.name")).setDesc(t("extensionOverride.attachmentFormat.desc")).addText(
  1142. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.settings.attachFormat).onChange(async (value) => {
  1143. this.settings.attachFormat = value;
  1144. })
  1145. );
  1146. new import_obsidian3.Setting(contentEl).addButton(
  1147. (button) => button.setButtonText(t("extensionOverride.buttons.save")).onClick(async () => {
  1148. this.onSubmit(this.settings);
  1149. this.close();
  1150. })
  1151. );
  1152. }
  1153. onClose() {
  1154. const { contentEl } = this;
  1155. contentEl.empty();
  1156. }
  1157. };
  1158. // src/settings/settings.ts
  1159. var DEFAULT_SETTINGS = {
  1160. attachPath: {
  1161. attachmentRoot: "",
  1162. saveAttE: `${SETTINGS_ROOT_OBSFOLDER}`,
  1163. attachmentPath: `${SETTINGS_VARIABLES_NOTEPATH}/${SETTINGS_VARIABLES_NOTENAME}`,
  1164. attachFormat: `IMG-${SETTINGS_VARIABLES_DATES}`,
  1165. type: "GLOBAL" /* GLOBAL */
  1166. },
  1167. dateFormat: "YYYYMMDDHHmmssSSS",
  1168. excludeExtensionPattern: "",
  1169. autoRenameAttachment: true,
  1170. excludedPaths: "",
  1171. excludePathsArray: [],
  1172. excludeSubpaths: false,
  1173. originalNameStorage: [],
  1174. overridePath: {},
  1175. disableNotification: false
  1176. };
  1177. var AttachmentManagementSettingTab = class extends import_obsidian4.PluginSettingTab {
  1178. constructor(app2, plugin) {
  1179. super(app2, plugin);
  1180. this.plugin = plugin;
  1181. }
  1182. displaySw(cont) {
  1183. cont.findAll(".setting-item").forEach((el) => {
  1184. var _a;
  1185. if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("root_folder_set")) {
  1186. if (this.plugin.settings.attachPath.saveAttE === "obsFolder") {
  1187. el.hide();
  1188. } else {
  1189. el.show();
  1190. }
  1191. }
  1192. });
  1193. }
  1194. splitPath(path2) {
  1195. const splitted = path2.split(";");
  1196. const rets = [];
  1197. for (const s of splitted) {
  1198. rets.push(s.trim());
  1199. }
  1200. return { splittedPaths: rets };
  1201. }
  1202. display() {
  1203. const { containerEl } = this;
  1204. containerEl.empty();
  1205. containerEl.createEl("h2", { text: t("settings.title") });
  1206. new import_obsidian4.Setting(containerEl).setName(t("settings.rootPath.name")).setDesc(t("settings.rootPath.desc")).addDropdown(
  1207. (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.plugin.settings.attachPath.saveAttE).onChange(async (value) => {
  1208. this.plugin.settings.attachPath.saveAttE = value;
  1209. this.displaySw(containerEl);
  1210. await this.plugin.saveSettings();
  1211. })
  1212. );
  1213. new import_obsidian4.Setting(containerEl).setName(t("settings.rootFolder.name")).setDesc(t("settings.rootFolder.desc")).setClass("root_folder_set").addText(
  1214. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.plugin.settings.attachPath.attachmentRoot).onChange(async (value) => {
  1215. debugLog("setting - attachment root:" + value);
  1216. this.plugin.settings.attachPath.attachmentRoot = value;
  1217. await this.plugin.saveSettings();
  1218. })
  1219. );
  1220. new import_obsidian4.Setting(containerEl).setName(t("settings.attachmentPath.name")).setDesc(t("settings.attachmentPath.desc")).addText((text) => {
  1221. const controlEl = text.inputEl.parentElement;
  1222. const errEl = controlEl.createDiv({ cls: "setting-item-description" });
  1223. controlEl.insertBefore(errEl, text.inputEl);
  1224. errEl.style.color = "var(--color-red)";
  1225. errEl.style.marginRight = "8px";
  1226. errEl.style.textAlign = "right";
  1227. errEl.hide();
  1228. const applyValidation = (value) => {
  1229. const err = validateAttachmentPath(value);
  1230. if (err) {
  1231. text.inputEl.style.border = "1px solid var(--color-red)";
  1232. errEl.setText(attachmentPathErrorMessage(err));
  1233. errEl.show();
  1234. return false;
  1235. }
  1236. text.inputEl.style.border = "";
  1237. errEl.hide();
  1238. return true;
  1239. };
  1240. text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.plugin.settings.attachPath.attachmentPath).onChange(async (value) => {
  1241. debugLog("setting - attachment path:" + value);
  1242. if (!applyValidation(value)) return;
  1243. this.plugin.settings.attachPath.attachmentPath = value;
  1244. await this.plugin.saveSettings();
  1245. });
  1246. applyValidation(this.plugin.settings.attachPath.attachmentPath);
  1247. });
  1248. new import_obsidian4.Setting(containerEl).setName(t("settings.attachmentFormat.name")).setDesc(t("settings.attachmentFormat.desc")).addText((text) => {
  1249. const controlEl = text.inputEl.parentElement;
  1250. const errEl = controlEl.createDiv({ cls: "setting-item-description" });
  1251. controlEl.insertBefore(errEl, text.inputEl);
  1252. errEl.style.color = "var(--color-red)";
  1253. errEl.style.marginRight = "8px";
  1254. errEl.style.textAlign = "right";
  1255. errEl.hide();
  1256. const applyValidation = (value) => {
  1257. const err = validateAttachFormat(value);
  1258. if (err) {
  1259. text.inputEl.style.border = "1px solid var(--color-red)";
  1260. errEl.setText(attachFormatErrorMessage(err));
  1261. errEl.show();
  1262. return false;
  1263. }
  1264. text.inputEl.style.border = "";
  1265. errEl.hide();
  1266. return true;
  1267. };
  1268. text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.plugin.settings.attachPath.attachFormat).onChange(async (value) => {
  1269. debugLog("setting - attachment format:" + value);
  1270. if (!applyValidation(value)) return;
  1271. this.plugin.settings.attachPath.attachFormat = value;
  1272. await this.plugin.saveSettings();
  1273. });
  1274. applyValidation(this.plugin.settings.attachPath.attachFormat);
  1275. });
  1276. new import_obsidian4.Setting(containerEl).setName(t("settings.dateFormat.name")).setDesc(
  1277. createFragment((frag) => {
  1278. frag.appendText(t("settings.dateFormat.desc") + " ");
  1279. frag.createEl("a", {
  1280. href: "https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format",
  1281. text: t("settings.dateFormat.linkText")
  1282. });
  1283. })
  1284. ).addMomentFormat((component) => {
  1285. component.setPlaceholder(DEFAULT_SETTINGS.dateFormat).setValue(this.plugin.settings.dateFormat).onChange(async (value) => {
  1286. debugLog("setting - date format:" + value);
  1287. this.plugin.settings.dateFormat = value;
  1288. await this.plugin.saveSettings();
  1289. });
  1290. });
  1291. new import_obsidian4.Setting(containerEl).setName(t("settings.autoRename.name")).setDesc(t("settings.autoRename.desc")).addToggle(
  1292. (toggle) => toggle.setValue(this.plugin.settings.autoRenameAttachment).onChange(async (value) => {
  1293. debugLog("setting - automatically rename attachment folder:" + value);
  1294. this.plugin.settings.autoRenameAttachment = value;
  1295. await this.plugin.saveSettings();
  1296. })
  1297. );
  1298. new import_obsidian4.Setting(containerEl).setName(t("settings.extensionOverride.name")).setDesc(t("settings.extensionOverride.desc")).addButton((btn) => {
  1299. btn.setButtonText(t("settings.extensionOverride.addButton")).onClick(async () => {
  1300. if (this.plugin.settings.attachPath.extensionOverride === void 0) {
  1301. this.plugin.settings.attachPath.extensionOverride = [];
  1302. }
  1303. this.plugin.settings.attachPath.extensionOverride.push({
  1304. extension: "",
  1305. attachmentRoot: this.plugin.settings.attachPath.attachmentRoot,
  1306. saveAttE: this.plugin.settings.attachPath.saveAttE,
  1307. attachmentPath: this.plugin.settings.attachPath.attachmentPath,
  1308. attachFormat: this.plugin.settings.attachPath.attachFormat
  1309. });
  1310. await this.plugin.saveSettings();
  1311. this.display();
  1312. });
  1313. });
  1314. if (this.plugin.settings.attachPath.extensionOverride !== void 0) {
  1315. this.plugin.settings.attachPath.extensionOverride.forEach((ext) => {
  1316. new import_obsidian4.Setting(containerEl).setName(t("settings.extensionOverride.extension.name")).setDesc(t("settings.extensionOverride.extension.desc")).setClass("override_extension_set").addText(
  1317. (text) => text.setPlaceholder(t("settings.extensionOverride.extension.placeholder")).setValue(ext.extension).onChange(async (value) => {
  1318. ext.extension = value;
  1319. })
  1320. ).addButton((btn) => {
  1321. btn.setIcon("trash").setTooltip(t("settings.extensionOverride.tooltips.remove")).onClick(async () => {
  1322. var _a, _b, _c;
  1323. const index = (_b = (_a = this.plugin.settings.attachPath.extensionOverride) == null ? void 0 : _a.indexOf(ext)) != null ? _b : -1;
  1324. (_c = this.plugin.settings.attachPath.extensionOverride) == null ? void 0 : _c.splice(index, 1);
  1325. await this.plugin.saveSettings();
  1326. this.display();
  1327. });
  1328. }).addButton((btn) => {
  1329. btn.setIcon("pencil").setTooltip(t("settings.extensionOverride.tooltips.edit")).onClick(async () => {
  1330. new OverrideExtensionModal(this.plugin, ext, (result) => {
  1331. ext = result;
  1332. }).open();
  1333. });
  1334. }).addButton((btn) => {
  1335. btn.setIcon("check").setTooltip(t("settings.extensionOverride.tooltips.save")).onClick(async () => {
  1336. const wrongIndex = validateExtensionEntry(this.plugin.settings.attachPath, this.plugin.settings);
  1337. if (wrongIndex.length > 0) {
  1338. for (const i of wrongIndex) {
  1339. const resIndex = i.index < 0 ? 0 : i.index;
  1340. const wrongSetting = containerEl.getElementsByClassName("override_extension_set")[resIndex];
  1341. wrongSetting.getElementsByTagName("input")[0].style.border = "1px solid var(--color-red)";
  1342. generateErrorExtensionMessage(i.type);
  1343. }
  1344. return;
  1345. }
  1346. await this.plugin.saveSettings();
  1347. this.display();
  1348. new import_obsidian4.Notice(t("settings.extensionOverride.saveNotice"));
  1349. });
  1350. });
  1351. });
  1352. }
  1353. new import_obsidian4.Setting(containerEl).setName(t("settings.excludeExtension.name")).setDesc(t("settings.excludeExtension.desc")).addText(
  1354. (text) => text.setPlaceholder(t("settings.excludeExtension.placeholder")).setValue(this.plugin.settings.excludeExtensionPattern).onChange(async (value) => {
  1355. this.plugin.settings.excludeExtensionPattern = value;
  1356. await this.plugin.saveSettings();
  1357. })
  1358. );
  1359. new import_obsidian4.Setting(containerEl).setName(t("settings.excludedPaths.name")).setDesc(t("settings.excludedPaths.desc")).addTextArea((component) => {
  1360. component.setValue(this.plugin.settings.excludedPaths).onChange(async (value) => {
  1361. this.plugin.settings.excludedPaths = value;
  1362. const { splittedPaths } = this.splitPath(value);
  1363. this.plugin.settings.excludePathsArray = splittedPaths;
  1364. debugLog("setting - excluded paths:" + value, splittedPaths);
  1365. await this.plugin.saveSettings();
  1366. });
  1367. });
  1368. new import_obsidian4.Setting(containerEl).setName(t("settings.excludeSubpaths.name")).setDesc(t("settings.excludeSubpaths.desc")).addToggle(
  1369. (toggle) => toggle.setValue(this.plugin.settings.excludeSubpaths).onChange(async (value) => {
  1370. debugLog("setting - excluded subpaths:" + value);
  1371. this.plugin.settings.excludeSubpaths = value;
  1372. await this.plugin.saveSettings();
  1373. })
  1374. );
  1375. this.displaySw(containerEl);
  1376. }
  1377. };
  1378. // src/model/override.ts
  1379. var import_obsidian5 = require("obsidian");
  1380. var OverrideModal = class extends import_obsidian5.Modal {
  1381. constructor(plugin, file, setting) {
  1382. super(plugin.app);
  1383. this.plugin = plugin;
  1384. this.file = file;
  1385. this.setting = setting;
  1386. }
  1387. displaySw(cont) {
  1388. cont.findAll(".setting-item").forEach((el) => {
  1389. var _a;
  1390. if ((_a = el.getAttr("class")) == null ? void 0 : _a.includes("override_root_folder_set")) {
  1391. if (this.setting.saveAttE === "obsFolder") {
  1392. el.hide();
  1393. } else {
  1394. el.show();
  1395. }
  1396. }
  1397. });
  1398. }
  1399. onOpen() {
  1400. const { contentEl } = this;
  1401. contentEl.empty();
  1402. contentEl.createEl("h3", {
  1403. text: t("override.title")
  1404. });
  1405. new import_obsidian5.Setting(contentEl).setName(t("settings.rootPath.name")).setDesc(t("settings.rootPath.desc")).addDropdown(
  1406. (text) => text.addOption(`${SETTINGS_ROOT_OBSFOLDER}`, t("settings.rootPath.options.obsidian")).addOption(`${SETTINGS_ROOT_INFOLDER}`, t("settings.rootPath.options.inFolder")).addOption(`${SETTINGS_ROOT_NEXTTONOTE}`, t("settings.rootPath.options.nextToNote")).setValue(this.setting.saveAttE).onChange(async (value) => {
  1407. this.setting.saveAttE = value;
  1408. this.displaySw(contentEl);
  1409. })
  1410. );
  1411. new import_obsidian5.Setting(contentEl).setName(t("settings.rootFolder.name")).setDesc(t("settings.rootFolder.desc")).setClass("override_root_folder_set").addText(
  1412. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentRoot).setValue(this.setting.attachmentRoot).onChange(async (value) => {
  1413. debugLog("override - attachment root:" + value);
  1414. this.setting.attachmentRoot = value;
  1415. })
  1416. );
  1417. new import_obsidian5.Setting(contentEl).setName(t("settings.attachmentPath.name")).setDesc(t("settings.attachmentPath.desc")).addText(
  1418. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachmentPath).setValue(this.setting.attachmentPath).onChange(async (value) => {
  1419. debugLog("override - attachment path:" + value);
  1420. this.setting.attachmentPath = value;
  1421. })
  1422. );
  1423. new import_obsidian5.Setting(contentEl).setName(t("settings.attachmentFormat.name")).setDesc(t("settings.attachmentFormat.desc")).addText(
  1424. (text) => text.setPlaceholder(DEFAULT_SETTINGS.attachPath.attachFormat).setValue(this.setting.attachFormat).onChange(async (value) => {
  1425. debugLog("override - attachment format:" + value);
  1426. this.setting.attachFormat = value;
  1427. })
  1428. );
  1429. new import_obsidian5.Setting(contentEl).addButton((btn) => {
  1430. btn.setButtonText(t("override.addExtensionOverrides")).onClick(async () => {
  1431. if (this.setting.extensionOverride === void 0) {
  1432. this.setting.extensionOverride = [];
  1433. }
  1434. this.setting.extensionOverride.push({
  1435. extension: "",
  1436. saveAttE: this.setting.saveAttE,
  1437. attachmentRoot: this.setting.attachmentRoot,
  1438. attachmentPath: this.setting.attachmentPath,
  1439. attachFormat: this.setting.attachFormat
  1440. });
  1441. this.onOpen();
  1442. });
  1443. });
  1444. if (this.setting.extensionOverride !== void 0) {
  1445. this.setting.extensionOverride.forEach((ext) => {
  1446. new import_obsidian5.Setting(contentEl).setName(t("override.extension.name")).setDesc(t("override.extension.desc")).setClass("override_extension_set").addText(
  1447. (text) => text.setPlaceholder(t("override.extension.placeholder")).setValue(ext.extension).onChange(async (value) => {
  1448. ext.extension = value;
  1449. })
  1450. ).addButton((btn) => {
  1451. btn.setIcon("trash").onClick(async () => {
  1452. var _a, _b, _c;
  1453. const index = (_b = (_a = this.setting.extensionOverride) == null ? void 0 : _a.indexOf(ext)) != null ? _b : -1;
  1454. (_c = this.setting.extensionOverride) == null ? void 0 : _c.splice(index, 1);
  1455. this.onOpen();
  1456. });
  1457. }).addButton((btn) => {
  1458. btn.setIcon("pencil").onClick(async () => {
  1459. new OverrideExtensionModal(this.plugin, ext, (result) => {
  1460. ext = result;
  1461. }).open();
  1462. });
  1463. });
  1464. });
  1465. }
  1466. new import_obsidian5.Setting(contentEl).addButton((btn) => {
  1467. btn.setButtonText(t("override.buttons.reset")).onClick(async () => {
  1468. this.setting = this.plugin.settings.attachPath;
  1469. delete this.plugin.settings.overridePath[this.file.path];
  1470. await this.plugin.saveSettings();
  1471. await this.plugin.loadSettings();
  1472. new import_obsidian5.Notice(t("override.notifications.reset", { path: this.file.path }));
  1473. this.close();
  1474. });
  1475. }).addButton(
  1476. (btn) => btn.setButtonText(t("override.buttons.submit")).setCta().onClick(async () => {
  1477. if (this.file instanceof import_obsidian5.TFile) {
  1478. this.setting.type = "FILE" /* FILE */;
  1479. } else if (this.file instanceof import_obsidian5.TFolder) {
  1480. this.setting.type = "FOLDER" /* FOLDER */;
  1481. }
  1482. this.plugin.settings.overridePath[this.file.path] = this.setting;
  1483. await this.plugin.saveSettings();
  1484. debugLog("override - overriding settings:", this.file.path, this.setting);
  1485. new import_obsidian5.Notice(t("override.notifications.overridden", { path: this.file.path }));
  1486. this.close();
  1487. })
  1488. );
  1489. this.displaySw(contentEl);
  1490. }
  1491. onClose() {
  1492. const { contentEl } = this;
  1493. contentEl.empty();
  1494. }
  1495. };
  1496. // src/model/confirm.ts
  1497. var import_obsidian10 = require("obsidian");
  1498. // src/arrange.ts
  1499. var import_obsidian9 = require("obsidian");
  1500. // src/lib/path.ts
  1501. var path = {
  1502. // Credit: [@creationix/path.js](https://gist.github.com/creationix/7435851)
  1503. join(...partSegments) {
  1504. let parts = [];
  1505. for (let i = 0, l = partSegments.length; i < l; i++) {
  1506. parts = parts.concat(partSegments[i].split("/"));
  1507. }
  1508. const newParts = [];
  1509. for (let i = 0, l = parts.length; i < l; i++) {
  1510. const part = parts[i];
  1511. if (!part || part === ".") continue;
  1512. if (part === "..") newParts.pop();
  1513. else newParts.push(part);
  1514. }
  1515. if (parts[0] === "") newParts.unshift("");
  1516. return newParts.join("/");
  1517. },
  1518. // A simple function to get the dirname of a path
  1519. // Trailing slashes are ignored. Leading slash is preserved.
  1520. dirname(filepath) {
  1521. return this.join(filepath, "..");
  1522. },
  1523. // returns the last part of a path, e.g. 'foo.jpg'
  1524. basename(filepath, extension = "") {
  1525. const sp = filepath.split("/");
  1526. const filename = sp[sp.length - 1];
  1527. if (extension !== "") {
  1528. return filename.slice(0, filename.length - extension.length - 1);
  1529. }
  1530. return sp[sp.length - 1];
  1531. },
  1532. // return extension without dot, e.g. 'jpg'
  1533. extname(filepath) {
  1534. const positions = [...filepath.matchAll(new RegExp("\\.", "gi"))].map((a) => a.index);
  1535. const idx = positions[positions.length - 1];
  1536. if (idx === void 0) {
  1537. return "";
  1538. }
  1539. return filepath.slice(idx + 1);
  1540. }
  1541. };
  1542. // src/override.ts
  1543. var import_obsidian6 = require("obsidian");
  1544. function getOverrideSetting(settings, file, oldPath = "") {
  1545. if (Object.keys(settings.overridePath).length === 0) {
  1546. return { settingPath: "", setting: settings.attachPath };
  1547. }
  1548. const candidates = {};
  1549. let fileType;
  1550. let filePath;
  1551. fileType = file instanceof import_obsidian6.TFile;
  1552. fileType = !(file instanceof import_obsidian6.TFolder);
  1553. if (oldPath === "") {
  1554. filePath = file.path;
  1555. } else {
  1556. filePath = oldPath;
  1557. }
  1558. for (const overridePath of Object.keys(settings.overridePath)) {
  1559. const overrideSetting = settings.overridePath[overridePath];
  1560. if (fileType) {
  1561. if (overridePath === filePath && overrideSetting.type === "FILE" /* FILE */) {
  1562. return { settingPath: overridePath, setting: overrideSetting };
  1563. } else if (filePath.startsWith(overridePath) && filePath.charAt(overridePath.length) === "/" && overrideSetting.type === "FOLDER" /* FOLDER */) {
  1564. candidates[overridePath] = overrideSetting;
  1565. }
  1566. } else {
  1567. if (overridePath === filePath && overrideSetting.type === "FOLDER" /* FOLDER */) {
  1568. return { settingPath: overridePath, setting: overrideSetting };
  1569. } else if (filePath.startsWith(overridePath) && filePath.charAt(overridePath.length) === "/" && overrideSetting.type === "FOLDER" /* FOLDER */) {
  1570. candidates[overridePath] = overrideSetting;
  1571. }
  1572. }
  1573. }
  1574. if (Object.keys(candidates).length === 0) {
  1575. return { settingPath: "", setting: settings.attachPath };
  1576. }
  1577. const sortedK = Object.keys(candidates).sort(
  1578. (a, b) => a.split("/").length > b.split("/").length ? -1 : a.split("/").length < b.split("/").length ? 1 : 0
  1579. );
  1580. debugLog("getOverrideSetting - sortedK:", sortedK);
  1581. for (const k of sortedK) {
  1582. if (filePath.startsWith(k)) {
  1583. return { settingPath: k, setting: candidates[k] };
  1584. }
  1585. }
  1586. return { settingPath: "", setting: settings.attachPath };
  1587. }
  1588. function getRenameOverrideSetting(settings, file, oldPath) {
  1589. if (Object.keys(settings.overridePath).length === 0) {
  1590. return { settingPath: "", setting: settings.attachPath };
  1591. }
  1592. const { settingPath: np, setting: ns } = getOverrideSetting(settings, file);
  1593. const { settingPath: op, setting: os } = getOverrideSetting(settings, file, oldPath);
  1594. if (ns.type === "GLOBAL" /* GLOBAL */) {
  1595. return { settingPath: op, setting: os };
  1596. }
  1597. if (os.type === "GLOBAL" /* GLOBAL */) {
  1598. return { settingPath: np, setting: ns };
  1599. }
  1600. if (ns.type === "FILE" /* FILE */ && os.type === "FILE" /* FILE */) {
  1601. debugLog("getRenameOverrideSetting - both file type setting", np, op);
  1602. return { settingPath: "", setting: settings.attachPath };
  1603. }
  1604. if (ns.type === "FILE" /* FILE */ && os.type === "FOLDER" /* FOLDER */) {
  1605. return { settingPath: np, setting: ns };
  1606. } else if (ns.type === "FOLDER" /* FOLDER */ && os.type === "FILE" /* FILE */) {
  1607. return { settingPath: op, setting: os };
  1608. }
  1609. if (ns.type === "FOLDER" /* FOLDER */ && os.type === "FOLDER" /* FOLDER */) {
  1610. const l = np.split("/").length;
  1611. const r = op.split("/").length;
  1612. if (l > r) {
  1613. return { settingPath: np, setting: ns };
  1614. } else if (l < r) {
  1615. return { settingPath: op, setting: os };
  1616. } else if (l === r) {
  1617. return { settingPath: "", setting: os };
  1618. }
  1619. }
  1620. return { settingPath: "", setting: settings.attachPath };
  1621. }
  1622. function updateOverrideSetting(settings, file, oldPath) {
  1623. const keys = Object.keys(settings.overridePath);
  1624. if (keys.length === 0 || file.path === oldPath) {
  1625. return;
  1626. }
  1627. const { settingPath, setting } = getOverrideSetting(settings, file, oldPath);
  1628. const copySetting = Object.assign({}, setting);
  1629. if (file.path === settingPath) {
  1630. return;
  1631. }
  1632. if (oldPath === settingPath) {
  1633. settings.overridePath[file.path] = copySetting;
  1634. delete settings.overridePath[settingPath];
  1635. return;
  1636. } else {
  1637. const { stripedSrc, stripedDst } = stripPaths(oldPath, file.path);
  1638. if (stripedSrc === settingPath) {
  1639. settings.overridePath[stripedDst] = copySetting;
  1640. delete settings.overridePath[settingPath];
  1641. return;
  1642. }
  1643. }
  1644. }
  1645. function deleteOverrideSetting(settings, file) {
  1646. const keys = Object.keys(settings.overridePath);
  1647. for (const key of keys) {
  1648. if (file.path === key) {
  1649. delete settings.overridePath[key];
  1650. return true;
  1651. }
  1652. }
  1653. return false;
  1654. }
  1655. // src/lib/deduplicate.ts
  1656. function escapeRegExp(s) {
  1657. return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  1658. }
  1659. async function deduplicateNewName(newName, file) {
  1660. const dir = file.path;
  1661. const listed = await file.vault.adapter.list(dir);
  1662. debugLog("deduplicateNewName - sibling files", listed);
  1663. const newNameExt = path.extname(newName), newNameStem = newName.slice(0, newName.length - newNameExt.length - 1), newNameStemEscaped = escapeRegExp(newNameStem), delimiter = "-", delimiterEscaped = escapeRegExp(delimiter);
  1664. const dupNameRegex = new RegExp(
  1665. `^(?<name>${newNameStemEscaped})${delimiterEscaped}(?<number>\\d{1,3})\\.${newNameExt}$`
  1666. );
  1667. debugLog("dupNameRegex", dupNameRegex);
  1668. const dupNameNumbers = [];
  1669. let isNewNameExist = false;
  1670. for (let sibling of listed.files) {
  1671. sibling = path.basename(sibling);
  1672. if (sibling == newName) {
  1673. isNewNameExist = true;
  1674. continue;
  1675. }
  1676. const m = dupNameRegex.exec(sibling);
  1677. if (!m || m.groups === void 0) continue;
  1678. dupNameNumbers.push(parseInt(m.groups.number));
  1679. }
  1680. if (isNewNameExist) {
  1681. const newNumber = dupNameNumbers.length > 0 ? Math.max(...dupNameNumbers) + 1 : 1;
  1682. newName = `${newNameStem}${delimiter}${newNumber}.${newNameExt}`;
  1683. }
  1684. return {
  1685. name: newName,
  1686. basename: newName.slice(0, newName.length - newNameExt.length - 1),
  1687. extension: newNameExt
  1688. };
  1689. }
  1690. // src/settings/metadata.ts
  1691. var import_obsidian8 = require("obsidian");
  1692. // src/commons.ts
  1693. var import_obsidian7 = require("obsidian");
  1694. function getActiveFile(app2) {
  1695. const view = getActiveView(app2);
  1696. if (view == null) {
  1697. return void 0;
  1698. } else if (view.file == null) {
  1699. return void 0;
  1700. } else {
  1701. return view.file;
  1702. }
  1703. }
  1704. function getActiveView(app2) {
  1705. return app2.workspace.getActiveViewOfType(import_obsidian7.TextFileView);
  1706. }
  1707. function getRootPath(notePath, setting) {
  1708. let root;
  1709. const obsmediadir = app.vault.getConfig("attachmentFolderPath");
  1710. switch (setting.saveAttE) {
  1711. case `${SETTINGS_ROOT_INFOLDER}`:
  1712. root = path.join(setting.attachmentRoot);
  1713. break;
  1714. case `${SETTINGS_ROOT_NEXTTONOTE}`:
  1715. root = path.join(notePath, setting.attachmentRoot.replace("./", ""));
  1716. break;
  1717. default:
  1718. if (obsmediadir === "/") {
  1719. root = obsmediadir;
  1720. } else if (obsmediadir === "./") {
  1721. root = path.join(notePath);
  1722. } else if (obsmediadir.match(/\.\/.+/g) !== null) {
  1723. root = path.join(notePath, obsmediadir.replace("./", ""));
  1724. } else {
  1725. root = obsmediadir;
  1726. }
  1727. }
  1728. return root === "/" ? root : (0, import_obsidian7.normalizePath)(root);
  1729. }
  1730. async function checkEmptyFolder(adapter, path2) {
  1731. const exist = await adapter.exists(path2, true);
  1732. if (!exist) {
  1733. return true;
  1734. }
  1735. const data = await adapter.list(path2);
  1736. if (data.files.length > 0) {
  1737. return false;
  1738. }
  1739. if (data.folders.length > 0) {
  1740. for (let i = 0; i < data.folders.length; i++) {
  1741. return checkEmptyFolder(adapter, data.folders[i]);
  1742. }
  1743. }
  1744. return true;
  1745. }
  1746. // src/lib/originalStorage.ts
  1747. function containsOriginalNameVariable(setting, ext) {
  1748. const { extSetting } = getExtensionOverrideSetting(ext, setting);
  1749. if (extSetting !== void 0) {
  1750. return extSetting.attachFormat.includes(SETTINGS_VARIABLES_ORIGINALNAME);
  1751. }
  1752. return setting.attachFormat.includes(SETTINGS_VARIABLES_ORIGINALNAME);
  1753. }
  1754. function saveOriginalName(settings, setting, ext, data) {
  1755. if (settings.originalNameStorage === void 0) {
  1756. settings.originalNameStorage = [];
  1757. }
  1758. if (!containsOriginalNameVariable(setting, ext)) {
  1759. return;
  1760. }
  1761. settings.originalNameStorage.filter((n) => n.md5 === data.md5).forEach((n) => settings.originalNameStorage.remove(n));
  1762. settings.originalNameStorage.push(data);
  1763. }
  1764. function loadOriginalName(settings, setting, ext, md5) {
  1765. if (!containsOriginalNameVariable(setting, ext)) {
  1766. return void 0;
  1767. }
  1768. return settings.originalNameStorage.find((data) => data.md5 === md5);
  1769. }
  1770. // src/settings/metadata.ts
  1771. var Metadata = class {
  1772. constructor(path2, name, basename, extension, parentPath, parentName, attachmentFile) {
  1773. /** parent path of file */
  1774. this.parentPath = "";
  1775. /** parent path basename of file */
  1776. this.parentName = "";
  1777. this.path = path2;
  1778. this.name = name;
  1779. this.basename = basename;
  1780. this.extension = extension;
  1781. this.parentPath = parentPath;
  1782. this.parentName = parentName;
  1783. this.attachmentFile = attachmentFile;
  1784. }
  1785. /**
  1786. * Returns a formatted attachment file name according to the provided settings.
  1787. *
  1788. * @param {AttachmentPathSettings} setting - attachment path settings object
  1789. * @param {string} dateFormat - format string for date and time
  1790. * @param {TFile} originalAttach - the original attachment file
  1791. * @param {DataAdapter} adapter - vault adapter (used for md5 hashing)
  1792. * @param {AttachmentManagementPluginSettings} [pluginSettings] - plugin settings; when provided
  1793. * enables ${originalname} lookup from the persisted storage so the original
  1794. * name survives subsequent renames (e.g. rearrange).
  1795. * @return {string} the formatted attachment file name
  1796. */
  1797. async getAttachFileName(setting, dateFormat, originalAttach, adapter, pluginSettings) {
  1798. const dateTime = window.moment(originalAttach.stat.ctime).format(dateFormat);
  1799. let md5 = "";
  1800. let attachFormat = DEFAULT_SETTINGS.attachPath.attachFormat;
  1801. if (this.attachmentFile !== void 0) {
  1802. md5 = await md5sum(adapter, this.attachmentFile);
  1803. const { extSetting } = getExtensionOverrideSetting(this.attachmentFile.extension, setting);
  1804. if (extSetting !== void 0) {
  1805. attachFormat = extSetting.attachFormat;
  1806. } else {
  1807. attachFormat = setting.attachFormat;
  1808. }
  1809. }
  1810. let originalName = originalAttach.basename;
  1811. if (pluginSettings !== void 0 && this.attachmentFile !== void 0) {
  1812. const stored = loadOriginalName(pluginSettings, setting, this.attachmentFile.extension, md5);
  1813. if (stored !== void 0) {
  1814. originalName = stored.n;
  1815. }
  1816. }
  1817. return attachFormat.replace(`${SETTINGS_VARIABLES_DATES}`, dateTime).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_MD5}`, md5).replace(`${SETTINGS_VARIABLES_ORIGINALNAME}`, originalName);
  1818. }
  1819. /**
  1820. * Returns the attachment path based on the given AttachmentPathSettings object.
  1821. *
  1822. * @param {AttachmentPathSettings} setting - An object containing the attachment path settings.
  1823. * @return {string} The normalized attachment path.
  1824. */
  1825. getAttachmentPath(setting) {
  1826. let root = "";
  1827. let attachPath = "";
  1828. if (this.attachmentFile !== void 0) {
  1829. const { extSetting } = getExtensionOverrideSetting(this.attachmentFile.extension, setting);
  1830. if (extSetting !== void 0) {
  1831. root = getRootPath(this.parentPath, extSetting);
  1832. attachPath = path.join(
  1833. root,
  1834. extSetting.attachmentPath.replace(`${SETTINGS_VARIABLES_NOTEPATH}`, this.parentPath).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_NOTEPARENT}`, this.parentName)
  1835. );
  1836. return (0, import_obsidian8.normalizePath)(attachPath);
  1837. }
  1838. }
  1839. root = getRootPath(this.parentPath, setting);
  1840. debugLog("getAttachmentPath - root", root);
  1841. attachPath = path.join(
  1842. root,
  1843. setting.attachmentPath.replace(`${SETTINGS_VARIABLES_NOTEPATH}`, this.parentPath).replace(`${SETTINGS_VARIABLES_NOTENAME}`, this.basename).replace(`${SETTINGS_VARIABLES_NOTEPARENT}`, this.parentName)
  1844. );
  1845. return (0, import_obsidian8.normalizePath)(attachPath);
  1846. }
  1847. };
  1848. function getMetadata(file, attach) {
  1849. const parentPath = path.dirname(file);
  1850. const parentName = path.basename(parentPath);
  1851. const name = path.basename(file);
  1852. const extension = path.extname(file);
  1853. const basename = path.basename(file, extension);
  1854. return new Metadata(file, name, basename, extension, parentPath, parentName, attach);
  1855. }
  1856. // src/exclude.ts
  1857. function isExcluded(path2, settings) {
  1858. debugLog("excludePathsArray: ", settings.excludePathsArray);
  1859. for (const excludedPath of settings.excludePathsArray) {
  1860. if (excludedPath.length === 0) {
  1861. continue;
  1862. }
  1863. if (settings.excludeSubpaths && path2.startsWith(excludedPath)) {
  1864. debugLog("isExcluded: ", path2);
  1865. return true;
  1866. } else {
  1867. if (path2 === excludedPath) {
  1868. return true;
  1869. }
  1870. }
  1871. }
  1872. return false;
  1873. }
  1874. // src/arrange.ts
  1875. var ArrangeHandler = class {
  1876. constructor(settings, app2) {
  1877. this.pluginSettings = settings;
  1878. this.app = app2;
  1879. }
  1880. /**
  1881. * Rearranges attachments that are linked by markdown or canvas.
  1882. * Only rearranges attachments if autoRenameAttachment is enabled in settings.
  1883. *
  1884. * @param {RearrangeType} type - The type of attachments to rearrange.
  1885. * @param {TFile} file - The file to which the attachments are linked (optional), if the type was "file", thi should be provided.
  1886. * @param {string} oldPath - The old path of the file (optional), used for rename event.
  1887. */
  1888. async rearrangeAttachment(type, file, oldPath) {
  1889. if (!this.pluginSettings.autoRenameAttachment) {
  1890. debugLog("rearrangeAttachment - autoRenameAttachment not enable");
  1891. return;
  1892. }
  1893. const attachments = await this.getAttachmentsInVault(this.pluginSettings, type, file, oldPath);
  1894. debugLog("rearrangeAttachment - attachments:", Object.keys(attachments).length, Object.entries(attachments));
  1895. for (const obNote of Object.keys(attachments)) {
  1896. const innerFile = this.app.vault.getAbstractFileByPath(obNote);
  1897. if (!(innerFile instanceof import_obsidian9.TFile) || isAttachment(this.app, this.pluginSettings, innerFile)) {
  1898. debugLog(`rearrangeAttachment - ${obNote} not exists or is attachment, skipped`);
  1899. continue;
  1900. }
  1901. const { setting } = getOverrideSetting(this.pluginSettings, innerFile);
  1902. if (attachments[obNote].size == 0) {
  1903. continue;
  1904. }
  1905. const md = getMetadata(obNote);
  1906. const attachPath = md.getAttachmentPath(setting);
  1907. if (!await this.app.vault.adapter.exists(attachPath, true)) {
  1908. if (oldPath != void 0 && await this.app.vault.adapter.exists(attachPath, false)) {
  1909. const mdOld = getMetadata(oldPath);
  1910. const attachPathOld = mdOld.getAttachmentPath(setting);
  1911. this.app.vault.adapter.rename(attachPathOld, attachPath);
  1912. } else {
  1913. await this.app.vault.adapter.mkdir(attachPath);
  1914. }
  1915. }
  1916. for (let link of attachments[obNote]) {
  1917. try {
  1918. link = decodeURI(link);
  1919. } catch (err) {
  1920. console.log(`Invalid link: ${link}, err: ${err}`);
  1921. continue;
  1922. }
  1923. debugLog(`rearrangeAttachment - article: ${obNote} links: ${link}`);
  1924. const linkFile = this.app.vault.getAbstractFileByPath(link);
  1925. if (linkFile === null || !(linkFile instanceof import_obsidian9.TFile)) {
  1926. debugLog(`${link} not exists, skipped`);
  1927. continue;
  1928. }
  1929. const metadata = getMetadata(obNote, linkFile);
  1930. const attachName = await metadata.getAttachFileName(
  1931. setting,
  1932. this.pluginSettings.dateFormat,
  1933. linkFile,
  1934. this.app.vault.adapter,
  1935. this.pluginSettings
  1936. );
  1937. if (attachPath == path.dirname(link) && attachName === path.basename(link, path.extname(link))) {
  1938. continue;
  1939. }
  1940. const attachPathFolder = this.app.vault.getAbstractFileByPath(attachPath);
  1941. if (attachPathFolder === null || !(attachPathFolder instanceof import_obsidian9.TFolder)) {
  1942. debugLog(`${attachPath} not exists, skipped`);
  1943. continue;
  1944. }
  1945. const { name } = await deduplicateNewName(attachName + "." + path.extname(link), attachPathFolder);
  1946. debugLog("rearrangeAttachment - deduplicated name:", name);
  1947. await this.app.fileManager.renameFile(linkFile, path.join(attachPath, name));
  1948. }
  1949. }
  1950. }
  1951. /**
  1952. * Retrieves the attachments in the vault based on the specified settings and type.
  1953. * If a file is provided, only attachments related to that file will be returned.
  1954. *
  1955. * @param {AttachmentManagementPluginSettings} settings - The settings for the attachment management plugin.
  1956. * @param {RearrangeType} type - The type of attachments to retrieve.
  1957. * @param {TFile} [file] - The file to filter attachments by. Optional.
  1958. * @return {Promise<Record<string, Set<string>>>} - A promise that resolves to a record of attachments, where each key is a file name and each value is a set of associated attachment names.
  1959. */
  1960. async getAttachmentsInVault(settings, type, file, oldPath) {
  1961. let attachmentsRecord = {};
  1962. attachmentsRecord = await this.getAttachmentsInVaultByLinks(settings, type, file, oldPath);
  1963. return attachmentsRecord;
  1964. }
  1965. /**
  1966. * Modified from https://github.com/ozntel/oz-clear-unused-images-obsidian/blob/master/src/util.ts#LL48C21-L48C21
  1967. * Retrieves a record of attachments in the vault based on the given settings and type.
  1968. *
  1969. * @param {AttachmentManagementPluginSettings} settings - The settings for the attachment management plugin.
  1970. * @param {RearrangeType} type - The type of attachments to retrieve.
  1971. * @param {TFile} file - The file to retrieve attachments for (optional).
  1972. * @return {Promise<Record<string, Set<string>>>} - A promise that resolves to a record of attachments.
  1973. */
  1974. async getAttachmentsInVaultByLinks(settings, type, file, oldPath) {
  1975. const attachmentsRecord = {};
  1976. let resolvedLinks = {};
  1977. let allFiles = [];
  1978. if (type == 1 /* LINKS */) {
  1979. resolvedLinks = this.app.metadataCache.resolvedLinks;
  1980. allFiles = this.app.vault.getFiles();
  1981. } else if (type == 0 /* ACTIVE */) {
  1982. const file2 = getActiveFile(this.app);
  1983. if (file2) {
  1984. if (file2.parent && isExcluded(file2.parent.path, this.pluginSettings) || isAttachment(this.app, this.pluginSettings, file2)) {
  1985. allFiles = [];
  1986. } else {
  1987. debugLog("getAttachmentsInVaultByLinks - active:", file2.path);
  1988. allFiles = [file2];
  1989. if (this.app.metadataCache.resolvedLinks[file2.path]) {
  1990. resolvedLinks[file2.path] = this.app.metadataCache.resolvedLinks[file2.path];
  1991. }
  1992. debugLog("getAttachmentsInVaultByLinks - resolvedLinks:", resolvedLinks);
  1993. }
  1994. }
  1995. } else if (type == 2 /* FILE */ && file != void 0) {
  1996. if (file.parent && isExcluded(file.parent.path, this.pluginSettings) || isAttachment(this.app, this.pluginSettings, file)) {
  1997. allFiles = [];
  1998. } else {
  1999. debugLog("getAttachmentsInVaultByLinks - file:", file.path);
  2000. allFiles = [file];
  2001. const rlinks = this.app.metadataCache.resolvedLinks[file.path];
  2002. if (rlinks) {
  2003. debugLog("getAttachmentsInVaultByLinks - rlinks:", rlinks);
  2004. resolvedLinks[file.path] = rlinks;
  2005. } else if (oldPath) {
  2006. debugLog("getAttachmentsInVaultByLinks - oldPath:", oldPath);
  2007. resolvedLinks[file.path] = this.app.metadataCache.resolvedLinks[oldPath];
  2008. }
  2009. debugLog("getAttachmentsInVaultByLinks - resolvedLinks:", resolvedLinks);
  2010. }
  2011. }
  2012. debugLog("getAttachmentsInVaultByLinks - allFiles:", allFiles.length, allFiles);
  2013. if (resolvedLinks) {
  2014. for (const [mdFile, links] of Object.entries(resolvedLinks)) {
  2015. const attachmentsSet = /* @__PURE__ */ new Set();
  2016. if (links) {
  2017. for (const [filePath] of Object.entries(links)) {
  2018. if (isAttachment(this.app, settings, filePath)) {
  2019. this.addToSet(attachmentsSet, filePath);
  2020. }
  2021. }
  2022. this.addToRecord(attachmentsRecord, mdFile, attachmentsSet);
  2023. }
  2024. }
  2025. }
  2026. return attachmentsRecord;
  2027. }
  2028. addToRecord(record, key, value) {
  2029. if (record[key] === void 0) {
  2030. record[key] = value;
  2031. return;
  2032. }
  2033. const valueSet = record[key];
  2034. for (const val of value) {
  2035. this.addToSet(valueSet, val);
  2036. }
  2037. record[key] = valueSet;
  2038. }
  2039. addToSet(setObj, value) {
  2040. if (!setObj.has(value)) {
  2041. setObj.add(value);
  2042. }
  2043. }
  2044. needToRename(settings, attachPath, attachName, noteName, link) {
  2045. const linkPath = path.dirname(link);
  2046. const linkName = path.basename(link, path.extname(link));
  2047. if (linkName.length !== attachName.length) {
  2048. return true;
  2049. }
  2050. if (attachPath !== linkPath) {
  2051. return true;
  2052. } else {
  2053. if (settings.attachFormat.includes(SETTINGS_VARIABLES_NOTENAME) && !linkName.includes(noteName)) {
  2054. return true;
  2055. }
  2056. const noNoteNameAttachFormat = settings.attachFormat.split(SETTINGS_VARIABLES_NOTENAME);
  2057. if (settings.attachFormat.includes(SETTINGS_VARIABLES_DATES)) {
  2058. for (const formatPart in noNoteNameAttachFormat) {
  2059. const splited = formatPart.split(SETTINGS_VARIABLES_DATES);
  2060. for (const part in splited) {
  2061. if (!linkName.includes(part)) {
  2062. return true;
  2063. }
  2064. }
  2065. }
  2066. }
  2067. }
  2068. return false;
  2069. }
  2070. };
  2071. // src/model/confirm.ts
  2072. var ConfirmModal = class extends import_obsidian10.Modal {
  2073. constructor(plugin) {
  2074. super(plugin.app);
  2075. this.plugin = plugin;
  2076. }
  2077. onOpen() {
  2078. const { contentEl } = this;
  2079. contentEl.empty();
  2080. const header = contentEl.createDiv({ cls: "amg-confirm-header" });
  2081. header.style.display = "flex";
  2082. header.style.alignItems = "center";
  2083. header.style.gap = "8px";
  2084. header.style.marginBottom = "12px";
  2085. const iconEl = header.createSpan({ cls: "amg-confirm-icon" });
  2086. iconEl.style.color = "var(--color-orange)";
  2087. iconEl.style.display = "inline-flex";
  2088. (0, import_obsidian10.setIcon)(iconEl, "alert-triangle");
  2089. header.createEl("h3", {
  2090. text: t("confirm.title"),
  2091. cls: "amg-confirm-title"
  2092. }).style.margin = "0";
  2093. const message = contentEl.createEl("p", {
  2094. text: t("confirm.message"),
  2095. cls: "amg-confirm-message"
  2096. });
  2097. message.style.margin = "0 0 16px 0";
  2098. message.style.lineHeight = "1.5";
  2099. new import_obsidian10.Setting(contentEl).addButton((btn) => {
  2100. btn.setButtonText(t("common.cancel")).onClick(() => {
  2101. this.close();
  2102. });
  2103. }).addButton(
  2104. (btn) => btn.setButtonText(t("confirm.continue")).setWarning().onClick(() => {
  2105. new ArrangeHandler(this.plugin.settings, this.plugin.app).rearrangeAttachment(1 /* LINKS */).then(() => new import_obsidian10.Notice(t("notices.arrangeCompleted"))).catch((err) => {
  2106. var _a;
  2107. return new import_obsidian10.Notice(`${t("notices.error.unknownError")}: ${(_a = err == null ? void 0 : err.message) != null ? _a : err}`);
  2108. }).finally(() => this.close());
  2109. })
  2110. );
  2111. }
  2112. onClose() {
  2113. const { contentEl } = this;
  2114. contentEl.empty();
  2115. }
  2116. };
  2117. // src/create.ts
  2118. var import_obsidian11 = require("obsidian");
  2119. var pendingRenameNotices = [];
  2120. var flushRenameNotices = (0, import_obsidian11.debounce)(
  2121. () => {
  2122. if (pendingRenameNotices.length === 0) {
  2123. return;
  2124. }
  2125. if (pendingRenameNotices.length === 1) {
  2126. const { from, to } = pendingRenameNotices[0];
  2127. new import_obsidian11.Notice(t("notices.fileRenamed", { from, to }));
  2128. } else {
  2129. new import_obsidian11.Notice(t("notices.filesRenamedBatch", { count: pendingRenameNotices.length }));
  2130. }
  2131. pendingRenameNotices.length = 0;
  2132. },
  2133. 500,
  2134. true
  2135. );
  2136. function queueRenameNotice(from, to) {
  2137. pendingRenameNotices.push({ from, to });
  2138. flushRenameNotices();
  2139. }
  2140. var CreateHandler = class {
  2141. constructor(plugin, settings) {
  2142. this.plugin = plugin;
  2143. this.app = this.plugin.app;
  2144. this.settings = settings;
  2145. }
  2146. /**
  2147. * Post-processing of created attachment file (for paste and drop event).
  2148. * @param attach - the attachment file to process
  2149. * @param source - the notes file that linked to attach
  2150. * @returns - none
  2151. */
  2152. processAttach(attach, source) {
  2153. if (source.parent && isExcluded(source.parent.path, this.settings)) {
  2154. debugLog("processAttach - not a file or exclude path:", source.path);
  2155. return;
  2156. }
  2157. const { setting } = getOverrideSetting(this.settings, source);
  2158. const { extSetting } = getExtensionOverrideSetting(attach.extension, setting);
  2159. debugLog("processAttach - file.extension:", attach.extension);
  2160. if (extSetting === void 0 && !isImage(attach.extension) && !isPastedImage(attach)) {
  2161. debugLog("renameFiles - no handle extension:", attach.extension);
  2162. return;
  2163. }
  2164. const metadata = getMetadata(source.path, attach);
  2165. debugLog("processAttach - metadata:", metadata);
  2166. const attachPath = metadata.getAttachmentPath(setting);
  2167. metadata.getAttachFileName(setting, this.settings.dateFormat, attach, this.app.vault.adapter).then((attachName) => {
  2168. attachName = attachName + "." + attach.extension;
  2169. this.app.vault.adapter.exists(attachPath, true).then(async (exists) => {
  2170. if (!exists) {
  2171. await this.app.vault.adapter.mkdir(attachPath);
  2172. debugLog("processAttach - create path:", attachPath);
  2173. }
  2174. }).finally(() => {
  2175. const attachPathFolder = this.app.vault.getAbstractFileByPath(attachPath);
  2176. deduplicateNewName(attachName, attachPathFolder).then(({ name }) => {
  2177. debugLog("processAttach - new path of file:", path.join(attachPath, name));
  2178. this.renameCreateFile(attach, attachPath, name, source);
  2179. });
  2180. });
  2181. });
  2182. }
  2183. /**
  2184. * Rename the file specified by `@param file`, and update the link of the file if specified updateLink
  2185. * @param attach - file to rename
  2186. * @param attachPath - where to the renamed file will be move to
  2187. * @param attachName - name of the renamed file
  2188. * @param source - associated active file
  2189. * @returns - none
  2190. */
  2191. renameCreateFile(attach, attachPath, attachName, source) {
  2192. const dst = (0, import_obsidian11.normalizePath)(path.join(attachPath, attachName));
  2193. debugLog("renameFile - ", attach.path, " to ", dst);
  2194. const name = attach.name;
  2195. const originalBasename = attach.basename;
  2196. const oldLink = this.app.fileManager.generateMarkdownLink(attach, source.path);
  2197. this.app.vault.rename(attach, dst).then(() => {
  2198. if (name !== attachName) {
  2199. queueRenameNotice(name, attachName);
  2200. }
  2201. const newLink = this.app.fileManager.generateMarkdownLink(attach, source.path);
  2202. debugLog("renameFile - old link:", oldLink, "new link:", newLink);
  2203. this.updateLinkInSource(source, oldLink, newLink);
  2204. }).finally(() => {
  2205. const { setting } = getOverrideSetting(this.settings, source);
  2206. md5sum(this.app.vault.adapter, attach).then((md5) => {
  2207. saveOriginalName(this.settings, setting, attach.extension, {
  2208. n: originalBasename,
  2209. md5
  2210. });
  2211. this.plugin.saveData(this.settings);
  2212. });
  2213. });
  2214. }
  2215. /**
  2216. * Update the old link to new link in the source file.
  2217. * For markdown files with an active editor, use editor.replaceRange to avoid file reload and cursor jump.
  2218. * For other cases (canvas, non-active files), fall back to adapter.process.
  2219. * @param source - the source file containing the link
  2220. * @param oldLink - the old link text to replace
  2221. * @param newLink - the new link text
  2222. */
  2223. updateLinkInSource(source, oldLink, newLink) {
  2224. if (oldLink === newLink) {
  2225. return;
  2226. }
  2227. const mdView = this.app.workspace.getActiveViewOfType(import_obsidian11.MarkdownView);
  2228. if (mdView && mdView.file && mdView.file.path === source.path && mdView.editor) {
  2229. const editor = mdView.editor;
  2230. const content = editor.getValue();
  2231. const linkIndex = content.indexOf(oldLink);
  2232. if (linkIndex !== -1) {
  2233. const before = content.substring(0, linkIndex);
  2234. const lines = before.split("\n");
  2235. const fromLine = lines.length - 1;
  2236. const fromCh = lines[fromLine].length;
  2237. const oldLinkLines = oldLink.split("\n");
  2238. const toLine = fromLine + oldLinkLines.length - 1;
  2239. const toCh = oldLinkLines.length > 1 ? oldLinkLines[oldLinkLines.length - 1].length : fromCh + oldLink.length;
  2240. editor.replaceRange(newLink, { line: fromLine, ch: fromCh }, { line: toLine, ch: toCh });
  2241. debugLog("updateLinkInSource - updated via editor API");
  2242. return;
  2243. }
  2244. }
  2245. debugLog("updateLinkInSource - falling back to adapter.process");
  2246. this.app.vault.adapter.process(source.path, (data) => {
  2247. return data.replace(oldLink, newLink);
  2248. });
  2249. }
  2250. };
  2251. // src/main.ts
  2252. var AttachmentManagementPlugin = class extends import_obsidian12.Plugin {
  2253. constructor() {
  2254. super(...arguments);
  2255. this.createdQueue = [];
  2256. }
  2257. async onload() {
  2258. await this.loadSettings();
  2259. initI18n();
  2260. console.log(`Plugin loading: ${this.manifest.name} v.${this.manifest.version}`);
  2261. this.app.workspace.onLayoutReady(() => {
  2262. this.initCommands();
  2263. this.registerEvent(
  2264. this.app.workspace.on("file-menu", async (menu, file) => {
  2265. if (file.parent && isExcluded(file.parent.path, this.settings) || isAttachment(this.app, this.settings, file)) {
  2266. return;
  2267. }
  2268. menu.addItem((item) => {
  2269. item.setTitle(t("override.menuTitle")).setIcon("image-plus").onClick(async () => {
  2270. const { setting } = getOverrideSetting(this.settings, file);
  2271. const fileSetting = Object.assign({}, setting);
  2272. this.overrideConfiguration(file, fileSetting);
  2273. });
  2274. });
  2275. })
  2276. );
  2277. this.registerEvent(
  2278. this.app.vault.on("create", async (file) => {
  2279. debugLog("on create event - file:", file.path);
  2280. if (!(file instanceof import_obsidian12.TFile)) {
  2281. return;
  2282. }
  2283. const curentTime = (/* @__PURE__ */ new Date()).getTime();
  2284. const timeGapMs = curentTime - file.stat.mtime;
  2285. const timeGapCs = curentTime - file.stat.ctime;
  2286. if (timeGapMs > 1e3 || timeGapCs > 1e3 || isMarkdownFile(file.extension) || isCanvasFile(file.extension)) {
  2287. return;
  2288. }
  2289. if (matchExtension(file.extension, this.settings.excludeExtensionPattern)) {
  2290. debugLog("create - excluded file by extension", file);
  2291. return;
  2292. }
  2293. this.createdQueue.push(file);
  2294. })
  2295. );
  2296. this.registerEvent(
  2297. this.app.vault.on("modify", (file) => {
  2298. debugLog("on modify event - create queue:", this.createdQueue);
  2299. if (this.createdQueue.length < 1 || !(file instanceof import_obsidian12.TFile)) {
  2300. return;
  2301. }
  2302. debugLog("on modify event - file:", file.path);
  2303. this.app.vault.cachedRead(file).then((data) => {
  2304. const f = this.createdQueue.first();
  2305. if (f != void 0) {
  2306. this.app.vault.adapter.exists(f.path, true).then((exist) => {
  2307. if (exist) {
  2308. const processor = new CreateHandler(this, this.settings);
  2309. const link = this.app.fileManager.generateMarkdownLink(f, file.path);
  2310. if (file.extension == "md" && data.indexOf(link) != -1 || file.extension == "canvas" && data.indexOf(f.path) != -1) {
  2311. processor.processAttach(f, file);
  2312. this.createdQueue.remove(f);
  2313. }
  2314. } else {
  2315. debugLog("on modify event - file does not exist:", f.path);
  2316. this.createdQueue.remove(f);
  2317. }
  2318. });
  2319. }
  2320. });
  2321. })
  2322. );
  2323. this.registerEvent(
  2324. // when trigger a rename event on folder, for each file/folder in this renamed folder (include itself) will trigger this event
  2325. this.app.vault.on("rename", async (file, oldPath) => {
  2326. debugLog("on rename event - new path and old path:", file.path, oldPath);
  2327. if (isAttachment(this.app, this.settings, file)) {
  2328. debugLog("rename - not processing rename on attachment:", file.path);
  2329. return;
  2330. }
  2331. const { setting } = getRenameOverrideSetting(this.settings, file, oldPath);
  2332. debugLog("rename - using settings:", setting);
  2333. if (setting.type === "FOLDER" /* FOLDER */ || setting.type === "FILE" /* FILE */) {
  2334. updateOverrideSetting(this.settings, file, oldPath);
  2335. this.saveSettings();
  2336. }
  2337. debugLog("rename - updated settings:", setting);
  2338. if (!this.settings.autoRenameAttachment) {
  2339. debugLog("rename - auto rename not enabled:", this.settings.autoRenameAttachment);
  2340. return;
  2341. }
  2342. if (file instanceof import_obsidian12.TFile) {
  2343. if (file.parent && isExcluded(file.parent.path, this.settings)) {
  2344. debugLog("rename - exclude path:", file.parent.path);
  2345. new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
  2346. return;
  2347. }
  2348. await new ArrangeHandler(this.settings, this.app).rearrangeAttachment(2 /* FILE */, file, oldPath);
  2349. const oldMetadata = getMetadata(oldPath);
  2350. const oldAttachPath = oldMetadata.getAttachmentPath(setting);
  2351. this.app.vault.adapter.exists(oldAttachPath, true).then((exists) => {
  2352. if (exists) {
  2353. checkEmptyFolder(this.app.vault.adapter, oldAttachPath).then((empty) => {
  2354. if (empty) {
  2355. this.app.vault.adapter.rmdir(oldAttachPath, true);
  2356. }
  2357. });
  2358. }
  2359. });
  2360. } else if (file instanceof import_obsidian12.TFolder) {
  2361. return;
  2362. }
  2363. })
  2364. );
  2365. this.registerEvent(
  2366. this.app.vault.on("delete", async (file) => {
  2367. debugLog("on delete event - file path:", file.path);
  2368. if (file.parent && isExcluded(file.parent.path, this.settings) || isAttachment(this.app, this.settings, file)) {
  2369. debugLog("delete - exclude path or the file is an attachment:", file.path);
  2370. return;
  2371. }
  2372. if (file instanceof import_obsidian12.TFile) {
  2373. const oldMetadata = getMetadata(file.path);
  2374. const { setting } = getOverrideSetting(this.settings, file);
  2375. const oldAttachPath = oldMetadata.getAttachmentPath(setting);
  2376. this.app.vault.adapter.exists(oldAttachPath, true).then((exists) => {
  2377. if (exists) {
  2378. checkEmptyFolder(this.app.vault.adapter, oldAttachPath).then((empty) => {
  2379. if (empty) {
  2380. this.app.vault.adapter.rmdir(oldAttachPath, true);
  2381. }
  2382. });
  2383. }
  2384. });
  2385. }
  2386. if (deleteOverrideSetting(this.settings, file)) {
  2387. await this.saveSettings();
  2388. new import_obsidian12.Notice(t("notices.overrideRemoved", { path: file.path }));
  2389. }
  2390. })
  2391. );
  2392. this.addSettingTab(new AttachmentManagementSettingTab(this.app, this));
  2393. });
  2394. }
  2395. async overrideConfiguration(file, setting) {
  2396. new OverrideModal(this, file, setting).open();
  2397. }
  2398. /**
  2399. * Initializes and registers the plugin's commands
  2400. * This method is responsible for setting up the user interface by adding various commands.
  2401. * These commands include settings overrides, resetting settings, clearing unused original name storage,
  2402. * and rearranging attachments.
  2403. *
  2404. * Note: The actual implementation of each command is not included in this method and needs to be
  2405. * defined separately asynchronously.
  2406. *
  2407. * Warning: Make sure you have checked for errors while implementing the functionality of each command.
  2408. */
  2409. initCommands() {
  2410. this.addCommand({
  2411. id: "attachment-management-rearrange-all-links",
  2412. name: t("commands.rearrangeAllLinks"),
  2413. callback: async () => {
  2414. new ConfirmModal(this).open();
  2415. }
  2416. });
  2417. this.addCommand({
  2418. id: "attachment-management-rearrange-active-links",
  2419. name: t("commands.rearrangeActiveLinks"),
  2420. callback: async () => {
  2421. new ArrangeHandler(this.settings, this.app).rearrangeAttachment(0 /* ACTIVE */).finally(() => {
  2422. new import_obsidian12.Notice(t("notices.arrangeCompleted"));
  2423. });
  2424. }
  2425. });
  2426. this.addCommand({
  2427. id: "attachment-management-override-setting",
  2428. name: "Overriding setting",
  2429. checkCallback: (checking) => {
  2430. const file = getActiveFile(this.app);
  2431. if (file) {
  2432. if (isAttachment(this.app, this.settings, file)) {
  2433. return true;
  2434. }
  2435. if (!checking) {
  2436. if (file.parent && isExcluded(file.parent.path, this.settings)) {
  2437. new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
  2438. return true;
  2439. }
  2440. const { setting } = getOverrideSetting(this.settings, file);
  2441. const fileSetting = Object.assign({}, setting);
  2442. this.overrideConfiguration(file, fileSetting);
  2443. }
  2444. return true;
  2445. }
  2446. return false;
  2447. }
  2448. });
  2449. this.addCommand({
  2450. id: "attachment-management-reset-override-setting",
  2451. name: t("commands.resetOverrideSetting"),
  2452. checkCallback: (checking) => {
  2453. const file = getActiveFile(this.app);
  2454. if (file) {
  2455. if (isAttachment(this.app, this.settings, file)) {
  2456. return true;
  2457. }
  2458. if (!checking) {
  2459. if (file.parent && isExcluded(file.parent.path, this.settings)) {
  2460. new import_obsidian12.Notice(t("notices.fileExcluded", { path: file.path }));
  2461. return true;
  2462. }
  2463. delete this.settings.overridePath[file.path];
  2464. this.saveSettings().finally(() => {
  2465. new import_obsidian12.Notice(t("notices.resetAttachmentSetting", { path: file.path }));
  2466. });
  2467. }
  2468. return true;
  2469. }
  2470. return false;
  2471. }
  2472. });
  2473. this.addCommand({
  2474. id: "attachment-management-clear-unused-originalname-storage",
  2475. name: t("commands.clearUnusedStorage"),
  2476. callback: async () => {
  2477. const attachments = await new ArrangeHandler(this.settings, this.app).getAttachmentsInVault(
  2478. this.settings,
  2479. 1 /* LINKS */
  2480. );
  2481. const validMd5s = /* @__PURE__ */ new Set();
  2482. for (const attachs of Object.values(attachments)) {
  2483. for (const attach of attachs) {
  2484. const link = decodeURI(attach);
  2485. const linkFile = this.app.vault.getAbstractFileByPath(link);
  2486. if (linkFile instanceof import_obsidian12.TFile) {
  2487. validMd5s.add(await md5sum(this.app.vault.adapter, linkFile));
  2488. }
  2489. }
  2490. }
  2491. this.settings.originalNameStorage = this.settings.originalNameStorage.filter((s) => validMd5s.has(s.md5));
  2492. debugLog("clearUnusedOriginalNameStorage - storage:", this.settings.originalNameStorage);
  2493. await this.saveSettings();
  2494. }
  2495. });
  2496. }
  2497. async loadSettings() {
  2498. this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
  2499. }
  2500. async saveSettings() {
  2501. await this.saveData(this.settings);
  2502. }
  2503. async onunload() {
  2504. console.log("unloading attachment management.");
  2505. this.createdQueue = [];
  2506. }
  2507. };
  2508. /* nosourcemap */