@mnaoumov/obsidian-lib 10.10.0 → 10.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/lib/cjs/__merged.cjs +15 -1
  2. package/dist/lib/cjs/__merged.d.cts +2 -0
  3. package/dist/lib/cjs/generated-during-build.cjs +1 -1
  4. package/dist/lib/cjs/i18n/locales/en.cjs +7 -1
  5. package/dist/lib/cjs/i18n/locales/en.d.cts +6 -0
  6. package/dist/lib/cjs/i18n/locales/translations-map.d.cts +6 -0
  7. package/dist/lib/cjs/index.cjs +7 -1
  8. package/dist/lib/cjs/index.d.cts +2 -0
  9. package/dist/lib/cjs/link.cjs +40 -1
  10. package/dist/lib/cjs/link.d.cts +37 -1
  11. package/dist/lib/cjs/reference-definition.cjs +234 -0
  12. package/dist/lib/cjs/reference-definition.d.cts +47 -0
  13. package/dist/lib/cjs/release-asset.cjs +279 -0
  14. package/dist/lib/cjs/release-asset.d.cts +190 -0
  15. package/dist/lib/cjs/workspace.cjs +3 -2
  16. package/dist/lib/cjs/workspace.d.cts +6 -0
  17. package/dist/lib/esm/__merged.d.mts +2 -0
  18. package/dist/lib/esm/__merged.mjs +15 -1
  19. package/dist/lib/esm/generated-during-build.mjs +1 -1
  20. package/dist/lib/esm/i18n/locales/en.d.mts +6 -0
  21. package/dist/lib/esm/i18n/locales/en.mjs +7 -1
  22. package/dist/lib/esm/i18n/locales/translations-map.d.mts +6 -0
  23. package/dist/lib/esm/index.d.mts +2 -0
  24. package/dist/lib/esm/index.mjs +5 -1
  25. package/dist/lib/esm/link.d.mts +37 -1
  26. package/dist/lib/esm/link.mjs +40 -1
  27. package/dist/lib/esm/reference-definition.d.mts +47 -0
  28. package/dist/lib/esm/reference-definition.mjs +146 -0
  29. package/dist/lib/esm/release-asset.d.mts +190 -0
  30. package/dist/lib/esm/release-asset.mjs +187 -0
  31. package/dist/lib/esm/workspace.d.mts +6 -0
  32. package/dist/lib/esm/workspace.mjs +3 -2
  33. package/package.json +1 -1
@@ -7,7 +7,7 @@
7
7
  * functions to split paths, update links in files, and generate markdown links with various options.
8
8
  */
9
9
  import type { MaybeReturn } from '@mnaoumov/typescript-lib/type' with { 'resolution-mode': 'import' };
10
- import type { App, Reference, TFile } from 'obsidian' with { 'resolution-mode': 'import' };
10
+ import type { App, Reference, ReferenceLinkCache, TFile } from 'obsidian' with { 'resolution-mode': 'import' };
11
11
  import type { Promisable } from 'type-fest' with { 'resolution-mode': 'import' };
12
12
  import type { PathOrFile } from './file-system.cjs';
13
13
  import type { LinkUpdateProgressReporter } from './link-update-progress.cjs';
@@ -392,6 +392,24 @@ export interface EditReferencesInContentParams {
392
392
  * The function that converts each reference.
393
393
  */
394
394
  readonly referenceConverter: (reference: Reference) => Promisable<MaybeReturn<string>>;
395
+ /**
396
+ * The function that returns the new destination of each reference-style link definition
397
+ * (`[id]: destination "title"`). Obsidian reports those in `CachedMetadata.referenceLinks`, not among the
398
+ * references {@link EditReferencesInContentParams.referenceConverter} receives, so without this function they
399
+ * are never edited.
400
+ *
401
+ * It returns the destination unescaped, in the form of `ReferenceLinkCache.link`, or `undefined` to leave the
402
+ * definition unchanged. Only the destination is rewritten: the id, the title, the angle brackets and every use
403
+ * of the definition (`[text][id]`, `[id]`) stay as written. A definition whose content no longer matches its
404
+ * metadata is left unchanged. See {@link referenceDefinitionToFileChange}.
405
+ *
406
+ * The offset range applies to the definition's whole position. The heading skip and
407
+ * {@link EditReferencesInContentParams.shouldSkipReference} do not apply, since a definition is never in a
408
+ * heading and is not a `Reference`.
409
+ *
410
+ * @default `undefined`, which leaves every definition unchanged
411
+ */
412
+ readonly referenceDefinitionConverter?: (definition: ReferenceLinkCache) => Promisable<MaybeReturn<string>>;
395
413
  /**
396
414
  * Whether to also edit external links parsed from the note body. When `true`, the converter also
397
415
  * receives references for external links.
@@ -476,6 +494,24 @@ export interface EditReferencesParams extends EditReferencesOptions {
476
494
  * The function that converts each reference.
477
495
  */
478
496
  readonly referenceConverter: (reference: Reference) => Promisable<MaybeReturn<string>>;
497
+ /**
498
+ * The function that returns the new destination of each reference-style link definition
499
+ * (`[id]: destination "title"`). Obsidian reports those in `CachedMetadata.referenceLinks`, not among the
500
+ * references {@link EditReferencesParams.referenceConverter} receives, so without this function they are never
501
+ * edited.
502
+ *
503
+ * It returns the destination unescaped, in the form of `ReferenceLinkCache.link`, or `undefined` to leave the
504
+ * definition unchanged. Only the destination is rewritten: the id, the title, the angle brackets and every use
505
+ * of the definition (`[text][id]`, `[id]`) stay as written. A definition whose content no longer matches its
506
+ * metadata is left unchanged. See {@link referenceDefinitionToFileChange}. A canvas file has no definitions.
507
+ *
508
+ * The offset range applies to the definition's whole position. The heading skip and
509
+ * {@link EditReferencesParams.shouldSkipReference} do not apply, since a definition is never in a heading and is
510
+ * not a `Reference`.
511
+ *
512
+ * @default `undefined`, which leaves every definition unchanged
513
+ */
514
+ readonly referenceDefinitionConverter?: (definition: ReferenceLinkCache) => Promisable<MaybeReturn<string>>;
479
515
  /**
480
516
  * Whether to also edit external links parsed from the note body. When `true`, the converter also
481
517
  * receives references for external links.
@@ -0,0 +1,234 @@
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
+ (function patchObsidianRequire() {
6
+ const originalRequire = require;
7
+ if (!originalRequire || originalRequire.__isPatched) {
8
+ return;
9
+ }
10
+ require = Object.assign(
11
+ (id) => requirePatched(id),
12
+ originalRequire,
13
+ {
14
+ __isPatched: true
15
+ }
16
+ );
17
+ function extractDefault($module) {
18
+ return $module && $module.__esModule && "default" in $module ? $module.default : $module;
19
+ }
20
+ const OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
21
+ "@codemirror/autocomplete",
22
+ "@codemirror/collab",
23
+ "@codemirror/commands",
24
+ "@codemirror/language",
25
+ "@codemirror/lint",
26
+ "@codemirror/search",
27
+ "@codemirror/state",
28
+ "@codemirror/text",
29
+ "@codemirror/view",
30
+ "@lezer/common",
31
+ "@lezer/highlight",
32
+ "@lezer/lr",
33
+ "obsidian"
34
+ ]);
35
+ const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
36
+ "@codemirror/closebrackets",
37
+ "@codemirror/comment",
38
+ "@codemirror/fold",
39
+ "@codemirror/gutter",
40
+ "@codemirror/highlight",
41
+ "@codemirror/history",
42
+ "@codemirror/matchbrackets",
43
+ "@codemirror/panel",
44
+ "@codemirror/rangeset",
45
+ "@codemirror/rectangular-selection",
46
+ "@codemirror/stream-parser",
47
+ "@codemirror/tooltip"
48
+ ]);
49
+ function requirePatched(id) {
50
+ if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
51
+ return originalRequire?.(id);
52
+ }
53
+ const app = globalThis.app;
54
+ if (app?.isMobile) {
55
+ if (id === "process" || id === "node:process") {
56
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
57
+ return process;
58
+ }
59
+ } else {
60
+ const $module = originalRequire?.(id);
61
+ if ($module) {
62
+ return extractDefault($module);
63
+ }
64
+ }
65
+ console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
66
+ return {};
67
+ }
68
+ })();
69
+
70
+ "use strict";
71
+ var __defProp = Object.defineProperty;
72
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
73
+ var __getOwnPropNames = Object.getOwnPropertyNames;
74
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
75
+ var __export = (target, all) => {
76
+ for (var name in all)
77
+ __defProp(target, name, { get: all[name], enumerable: true });
78
+ };
79
+ var __copyProps = (to, from, except, desc) => {
80
+ if (from && typeof from === "object" || typeof from === "function") {
81
+ for (let key of __getOwnPropNames(from))
82
+ if (!__hasOwnProp.call(to, key) && key !== except)
83
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
84
+ }
85
+ return to;
86
+ };
87
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
88
+ var reference_definition_exports = {};
89
+ __export(reference_definition_exports, {
90
+ referenceDefinitionToFileChange: () => referenceDefinitionToFileChange
91
+ });
92
+ module.exports = __toCommonJS(reference_definition_exports);
93
+ var import_debug = require('./debug.cjs');
94
+ const ASCII_PUNCTUATION_REG_EXP = /[!-/:-@[-`{-~]/;
95
+ const BARE_DESTINATION_FORBIDDEN_CHARACTER_REG_EXP = /[\s\p{Cc}]/u;
96
+ const DEFINITION_PREFIX_REG_EXP = /^[ \t]*\[(?:\\[\s\S]|[^\\\]])+\]:[ \t]*(?:\r?\n(?:[ \t]*>)*[ \t]*)?/;
97
+ const LINE_BREAK_REG_EXP = /[\r\n]/;
98
+ const WHITESPACE_REG_EXP = /\s/;
99
+ function referenceDefinitionToFileChange(params) {
100
+ const { content, definition, newDestination } = params;
101
+ const referenceDefinitionDebugger = (0, import_debug.getObsidianLibDebugger)("ReferenceDefinition:referenceDefinitionToFileChange");
102
+ const token = findDestinationToken(content, definition);
103
+ if (!token) {
104
+ referenceDefinitionDebugger("Skipping a definition whose content does not match its metadata", { definition });
105
+ return null;
106
+ }
107
+ const newRaw = encodeDestination(newDestination, token.isAngle);
108
+ if (newRaw === null) {
109
+ referenceDefinitionDebugger("Skipping a destination that holds a line break", { definition, newDestination });
110
+ return null;
111
+ }
112
+ const reference = {
113
+ link: definition.link,
114
+ original: token.raw,
115
+ position: {
116
+ end: getLoc(content, definition, token.end),
117
+ start: getLoc(content, definition, token.start)
118
+ }
119
+ };
120
+ return {
121
+ newContent: newRaw,
122
+ oldContent: token.raw,
123
+ reference
124
+ };
125
+ }
126
+ function canBeBare(destination) {
127
+ if (destination === "" || destination.startsWith("<") || BARE_DESTINATION_FORBIDDEN_CHARACTER_REG_EXP.test(destination)) {
128
+ return false;
129
+ }
130
+ let depth = 0;
131
+ for (const character of destination) {
132
+ if (character === "(") {
133
+ depth++;
134
+ } else if (character === ")") {
135
+ depth--;
136
+ if (depth < 0) {
137
+ return false;
138
+ }
139
+ }
140
+ }
141
+ return depth === 0;
142
+ }
143
+ function encodeDestination(destination, isAngle) {
144
+ if (LINE_BREAK_REG_EXP.test(destination)) {
145
+ return null;
146
+ }
147
+ const shouldUseAngle = isAngle || !canBeBare(destination);
148
+ let encoded = "";
149
+ for (let index = 0; index < destination.length; index++) {
150
+ const character = destination.charAt(index);
151
+ const nextCharacter = destination.charAt(index + 1);
152
+ const isEscapeNeeded = shouldUseAngle ? character === "<" || character === ">" || character === "\\" && (nextCharacter === "" || ASCII_PUNCTUATION_REG_EXP.test(nextCharacter)) : character === "\\" && ASCII_PUNCTUATION_REG_EXP.test(nextCharacter);
153
+ encoded += isEscapeNeeded ? `\\${character}` : character;
154
+ }
155
+ return shouldUseAngle ? `<${encoded}>` : encoded;
156
+ }
157
+ function findDestinationToken(content, definition) {
158
+ const definitionStart = definition.position.start.offset;
159
+ const definitionEnd = definition.position.end.offset;
160
+ if (definitionStart < 0 || definitionEnd > content.length || definitionEnd < definitionStart) {
161
+ return null;
162
+ }
163
+ const definitionText = content.slice(definitionStart, definitionEnd);
164
+ const prefix = DEFINITION_PREFIX_REG_EXP.exec(definitionText);
165
+ if (!prefix) {
166
+ return null;
167
+ }
168
+ const tokenStart = prefix[0].length;
169
+ const isAngle = definitionText.charAt(tokenStart) === "<";
170
+ let tokenEnd = isAngle ? tokenStart + 1 : tokenStart;
171
+ for (; tokenEnd < definitionText.length; tokenEnd++) {
172
+ const character = definitionText.charAt(tokenEnd);
173
+ if (isAngle ? character === ">" || LINE_BREAK_REG_EXP.test(character) : WHITESPACE_REG_EXP.test(character)) {
174
+ break;
175
+ }
176
+ if (character === "\\" && ASCII_PUNCTUATION_REG_EXP.test(definitionText.charAt(tokenEnd + 1))) {
177
+ tokenEnd++;
178
+ }
179
+ }
180
+ if (isAngle) {
181
+ if (definitionText.charAt(tokenEnd) !== ">") {
182
+ return null;
183
+ }
184
+ tokenEnd++;
185
+ }
186
+ const boundary = definitionText.charAt(tokenEnd);
187
+ if (boundary !== "" && !WHITESPACE_REG_EXP.test(boundary)) {
188
+ return null;
189
+ }
190
+ const raw = definitionText.slice(tokenStart, tokenEnd);
191
+ const value = isAngle ? raw.slice(1, -1) : raw;
192
+ if (tokenEnd === tokenStart || unescapeDestination(value) !== definition.link) {
193
+ return null;
194
+ }
195
+ return {
196
+ end: definitionStart + tokenEnd,
197
+ isAngle,
198
+ raw,
199
+ start: definitionStart + tokenStart
200
+ };
201
+ }
202
+ function getLoc(content, definition, offset) {
203
+ const definitionStart = definition.position.start.offset;
204
+ let line = definition.position.start.line;
205
+ for (let index = definitionStart; index < offset; index++) {
206
+ if (content.charAt(index) === "\n") {
207
+ line++;
208
+ }
209
+ }
210
+ return {
211
+ col: offset - (content.lastIndexOf("\n", offset - 1) + 1),
212
+ line,
213
+ offset
214
+ };
215
+ }
216
+ function unescapeDestination(value) {
217
+ let result = "";
218
+ for (let index = 0; index < value.length; index++) {
219
+ const character = value.charAt(index);
220
+ const nextCharacter = value.charAt(index + 1);
221
+ if (character === "\\" && ASCII_PUNCTUATION_REG_EXP.test(nextCharacter)) {
222
+ result += nextCharacter;
223
+ index++;
224
+ } else {
225
+ result += character;
226
+ }
227
+ }
228
+ return result;
229
+ }
230
+ // Annotate the CommonJS export names for ESM import in node:
231
+ 0 && (module.exports = {
232
+ referenceDefinitionToFileChange
233
+ });
234
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWZlcmVuY2UtZGVmaW5pdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBmaWxlXG4gKlxuICogRWRpdHMgdGhlIGRlc3RpbmF0aW9uIG9mIGEgcmVmZXJlbmNlLXN0eWxlIGxpbmsgZGVmaW5pdGlvbiAoYFtpZF06IGRlc3RpbmF0aW9uIFwidGl0bGVcImApIHRoYXQgT2JzaWRpYW4gcmVwb3J0c1xuICogaW4gYENhY2hlZE1ldGFkYXRhLnJlZmVyZW5jZUxpbmtzYC5cbiAqXG4gKiBSZWFkIGZyb20gT2JzaWRpYW4gYDEuMTUuMWA6IGEgZGVmaW5pdGlvbidzIGBwb3NpdGlvbmAgc3BhbnMgdGhlIHdob2xlIGRlZmluaXRpb24sIGl0cyBsZWFkaW5nIGluZGVudGF0aW9uXG4gKiBpbmNsdWRlZCBhbmQgYW55IGJsb2NrcXVvdGUgb3IgbGlzdCBtYXJrZXIgZXhjbHVkZWQsIGFuZCBpdHMgYGxpbmtgIGlzIHRoZSBkZXN0aW5hdGlvbiB3aXRoIHRoZSBhbmdsZSBicmFja2V0c1xuICogcmVtb3ZlZCBhbmQgZXZlcnkgYmFja3NsYXNoIGVzY2FwZSByZXNvbHZlZCAoYFRhcmdldFxcI0VzY2FwZWQubWRgIHJlcG9ydHMgYFRhcmdldCNFc2NhcGVkLm1kYCkuIFRoZSB1c2VzIG9mIGFcbiAqIGRlZmluaXRpb24gKGBbdGV4dF1baWRdYCwgYFtpZF1bXWAsIGBbaWRdYCkgYXJlIG5vdCByZXBvcnRlZCBpbiBgbGlua3NgIGFuZCBuYW1lIHRoZSBkZWZpbml0aW9uIGJ5IGl0cyBpZCwgc29cbiAqIHJld3JpdGluZyBvbmx5IHRoZSBkZXN0aW5hdGlvbiBrZWVwcyBldmVyeSBvbmUgb2YgdGhlbSBwb2ludGluZyBhdCB0aGUgbmV3IHRhcmdldC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIExvYyxcbiAgUmVmZXJlbmNlQ2FjaGUsXG4gIFJlZmVyZW5jZUxpbmtDYWNoZVxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB0eXBlIHsgRmlsZUNoYW5nZSB9IGZyb20gJy4vZmlsZS1jaGFuZ2UudHMnO1xuXG5pbXBvcnQgeyBnZXRPYnNpZGlhbkxpYkRlYnVnZ2VyIH0gZnJvbSAnLi9kZWJ1Zy50cyc7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlZmVyZW5jZURlZmluaXRpb25Ub0ZpbGVDaGFuZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZmVyZW5jZURlZmluaXRpb25Ub0ZpbGVDaGFuZ2VQYXJhbXMge1xuICAvKipcbiAgICogVGhlIGNvbnRlbnQgdGhlIGRlZmluaXRpb24ncyBwb3NpdGlvbiByZWZlcnMgdG8uXG4gICAqL1xuICByZWFkb25seSBjb250ZW50OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZWZpbml0aW9uLCBhcyBPYnNpZGlhbiByZXBvcnRzIGl0IGluIGBDYWNoZWRNZXRhZGF0YS5yZWZlcmVuY2VMaW5rc2AuXG4gICAqL1xuICByZWFkb25seSBkZWZpbml0aW9uOiBSZWZlcmVuY2VMaW5rQ2FjaGU7XG5cbiAgLyoqXG4gICAqIFRoZSBuZXcgZGVzdGluYXRpb24sIHVuZXNjYXBlZCwgaW4gdGhlIHNhbWUgZm9ybSBhcyB7QGxpbmsgUmVmZXJlbmNlTGlua0NhY2hlLmxpbmt9LlxuICAgKi9cbiAgcmVhZG9ubHkgbmV3RGVzdGluYXRpb246IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIERlc3RpbmF0aW9uVG9rZW4ge1xuICByZWFkb25seSBlbmQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgaXNBbmdsZTogYm9vbGVhbjtcbiAgcmVhZG9ubHkgcmF3OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHN0YXJ0OiBudW1iZXI7XG59XG5cbmNvbnN0IEFTQ0lJX1BVTkNUVUFUSU9OX1JFR19FWFAgPSAvWyEtLzotQFstYHstfl0vO1xuY29uc3QgQkFSRV9ERVNUSU5BVElPTl9GT1JCSURERU5fQ0hBUkFDVEVSX1JFR19FWFAgPSAvW1xcc1xccHtDY31dL3U7XG5jb25zdCBERUZJTklUSU9OX1BSRUZJWF9SRUdfRVhQID0gL15bIFxcdF0qXFxbKD86XFxcXFtcXHNcXFNdfFteXFxcXFxcXV0pK1xcXTpbIFxcdF0qKD86XFxyP1xcbig/OlsgXFx0XSo+KSpbIFxcdF0qKT8vO1xuY29uc3QgTElORV9CUkVBS19SRUdfRVhQID0gL1tcXHJcXG5dLztcbmNvbnN0IFdISVRFU1BBQ0VfUkVHX0VYUCA9IC9cXHMvO1xuXG4vKipcbiAqIEJ1aWxkcyB0aGUgZmlsZSBjaGFuZ2UgdGhhdCByZXBsYWNlcyB0aGUgZGVzdGluYXRpb24gb2YgYSByZWZlcmVuY2Utc3R5bGUgbGluayBkZWZpbml0aW9uLCBsZWF2aW5nIGl0cyBpZCwgaXRzXG4gKiB0aXRsZSBhbmQgdGhlIHJlc3Qgb2YgdGhlIG5vdGUgdW5jaGFuZ2VkLlxuICpcbiAqIFRoZSBkZXN0aW5hdGlvbiBrZWVwcyBpdHMgZm9ybTogb25lIHdyaXR0ZW4gaW4gYW5nbGUgYnJhY2tldHMgc3RheXMgaW4gdGhlbSwgYW5kIGEgYmFyZSBvbmUgc3RheXMgYmFyZSB1bmxlc3NcbiAqIHRoZSBuZXcgZGVzdGluYXRpb24gY2Fubm90IGJlIHdyaXR0ZW4gYmFyZSAoaXQgaXMgZW1wdHksIGhvbGRzIHdoaXRlc3BhY2Ugb3IgYSBjb250cm9sIGNoYXJhY3Rlciwgc3RhcnRzIHdpdGhcbiAqIGA8YCwgb3IgaGFzIHVuYmFsYW5jZWQgcGFyZW50aGVzZXMpLCBpbiB3aGljaCBjYXNlIGl0IGlzIHdyaXR0ZW4gaW4gYW5nbGUgYnJhY2tldHMuIENoYXJhY3RlcnMgdGhhdCB3b3VsZCBlbmRcbiAqIG9yIGNoYW5nZSB0aGUgZGVzdGluYXRpb24gYXJlIGVzY2FwZWQgd2l0aCBhIGJhY2tzbGFzaC5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIGJ1aWxkaW5nIHRoZSBmaWxlIGNoYW5nZS5cbiAqIEByZXR1cm5zIFRoZSBmaWxlIGNoYW5nZSwgb3IgYG51bGxgIHdoZW4gdGhlIGNvbnRlbnQgYXQgdGhlIGRlZmluaXRpb24ncyBwb3NpdGlvbiBubyBsb25nZXIgaG9sZHMgYSBkZWZpbml0aW9uXG4gKiB3aG9zZSBkZXN0aW5hdGlvbiByZWFkcyBhcyB7QGxpbmsgUmVmZXJlbmNlTGlua0NhY2hlLmxpbmt9LCBvciB3aGVuIHRoZSBuZXcgZGVzdGluYXRpb24gaG9sZHMgYSBsaW5lIGJyZWFrLFxuICogd2hpY2ggbm8gZGVzdGluYXRpb24gY2FuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmZXJlbmNlRGVmaW5pdGlvblRvRmlsZUNoYW5nZShwYXJhbXM6IFJlZmVyZW5jZURlZmluaXRpb25Ub0ZpbGVDaGFuZ2VQYXJhbXMpOiBGaWxlQ2hhbmdlIHwgbnVsbCB7XG4gIGNvbnN0IHsgY29udGVudCwgZGVmaW5pdGlvbiwgbmV3RGVzdGluYXRpb24gfSA9IHBhcmFtcztcbiAgY29uc3QgcmVmZXJlbmNlRGVmaW5pdGlvbkRlYnVnZ2VyID0gZ2V0T2JzaWRpYW5MaWJEZWJ1Z2dlcignUmVmZXJlbmNlRGVmaW5pdGlvbjpyZWZlcmVuY2VEZWZpbml0aW9uVG9GaWxlQ2hhbmdlJyk7XG5cbiAgY29uc3QgdG9rZW4gPSBmaW5kRGVzdGluYXRpb25Ub2tlbihjb250ZW50LCBkZWZpbml0aW9uKTtcbiAgaWYgKCF0b2tlbikge1xuICAgIHJlZmVyZW5jZURlZmluaXRpb25EZWJ1Z2dlcignU2tpcHBpbmcgYSBkZWZpbml0aW9uIHdob3NlIGNvbnRlbnQgZG9lcyBub3QgbWF0Y2ggaXRzIG1ldGFkYXRhJywgeyBkZWZpbml0aW9uIH0pO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgbmV3UmF3ID0gZW5jb2RlRGVzdGluYXRpb24obmV3RGVzdGluYXRpb24sIHRva2VuLmlzQW5nbGUpO1xuICBpZiAobmV3UmF3ID09PSBudWxsKSB7XG4gICAgcmVmZXJlbmNlRGVmaW5pdGlvbkRlYnVnZ2VyKCdTa2lwcGluZyBhIGRlc3RpbmF0aW9uIHRoYXQgaG9sZHMgYSBsaW5lIGJyZWFrJywgeyBkZWZpbml0aW9uLCBuZXdEZXN0aW5hdGlvbiB9KTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHJlZmVyZW5jZTogUmVmZXJlbmNlQ2FjaGUgPSB7XG4gICAgbGluazogZGVmaW5pdGlvbi5saW5rLFxuICAgIG9yaWdpbmFsOiB0b2tlbi5yYXcsXG4gICAgcG9zaXRpb246IHtcbiAgICAgIGVuZDogZ2V0TG9jKGNvbnRlbnQsIGRlZmluaXRpb24sIHRva2VuLmVuZCksXG4gICAgICBzdGFydDogZ2V0TG9jKGNvbnRlbnQsIGRlZmluaXRpb24sIHRva2VuLnN0YXJ0KVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4ge1xuICAgIG5ld0NvbnRlbnQ6IG5ld1JhdyxcbiAgICBvbGRDb250ZW50OiB0b2tlbi5yYXcsXG4gICAgcmVmZXJlbmNlXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNhbkJlQmFyZShkZXN0aW5hdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChkZXN0aW5hdGlvbiA9PT0gJycgfHwgZGVzdGluYXRpb24uc3RhcnRzV2l0aCgnPCcpIHx8IEJBUkVfREVTVElOQVRJT05fRk9SQklEREVOX0NIQVJBQ1RFUl9SRUdfRVhQLnRlc3QoZGVzdGluYXRpb24pKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgbGV0IGRlcHRoID0gMDtcbiAgZm9yIChjb25zdCBjaGFyYWN0ZXIgb2YgZGVzdGluYXRpb24pIHtcbiAgICBpZiAoY2hhcmFjdGVyID09PSAnKCcpIHtcbiAgICAgIGRlcHRoKys7XG4gICAgfSBlbHNlIGlmIChjaGFyYWN0ZXIgPT09ICcpJykge1xuICAgICAgZGVwdGgtLTtcbiAgICAgIGlmIChkZXB0aCA8IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXB0aCA9PT0gMDtcbn1cblxuZnVuY3Rpb24gZW5jb2RlRGVzdGluYXRpb24oZGVzdGluYXRpb246IHN0cmluZywgaXNBbmdsZTogYm9vbGVhbik6IG51bGwgfCBzdHJpbmcge1xuICBpZiAoTElORV9CUkVBS19SRUdfRVhQLnRlc3QoZGVzdGluYXRpb24pKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBzaG91bGRVc2VBbmdsZSA9IGlzQW5nbGUgfHwgIWNhbkJlQmFyZShkZXN0aW5hdGlvbik7XG4gIGxldCBlbmNvZGVkID0gJyc7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBkZXN0aW5hdGlvbi5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBjb25zdCBjaGFyYWN0ZXIgPSBkZXN0aW5hdGlvbi5jaGFyQXQoaW5kZXgpO1xuICAgIGNvbnN0IG5leHRDaGFyYWN0ZXIgPSBkZXN0aW5hdGlvbi5jaGFyQXQoaW5kZXggKyAxKTtcbiAgICBjb25zdCBpc0VzY2FwZU5lZWRlZCA9IHNob3VsZFVzZUFuZ2xlXG4gICAgICA/IGNoYXJhY3RlciA9PT0gJzwnIHx8IGNoYXJhY3RlciA9PT0gJz4nIHx8IChjaGFyYWN0ZXIgPT09ICdcXFxcJyAmJiAobmV4dENoYXJhY3RlciA9PT0gJycgfHwgQVNDSUlfUFVOQ1RVQVRJT05fUkVHX0VYUC50ZXN0KG5leHRDaGFyYWN0ZXIpKSlcbiAgICAgIDogY2hhcmFjdGVyID09PSAnXFxcXCcgJiYgQVNDSUlfUFVOQ1RVQVRJT05fUkVHX0VYUC50ZXN0KG5leHRDaGFyYWN0ZXIpO1xuICAgIGVuY29kZWQgKz0gaXNFc2NhcGVOZWVkZWQgPyBgXFxcXCR7Y2hhcmFjdGVyfWAgOiBjaGFyYWN0ZXI7XG4gIH1cblxuICByZXR1cm4gc2hvdWxkVXNlQW5nbGUgPyBgPCR7ZW5jb2RlZH0+YCA6IGVuY29kZWQ7XG59XG5cbmZ1bmN0aW9uIGZpbmREZXN0aW5hdGlvblRva2VuKGNvbnRlbnQ6IHN0cmluZywgZGVmaW5pdGlvbjogUmVmZXJlbmNlTGlua0NhY2hlKTogRGVzdGluYXRpb25Ub2tlbiB8IG51bGwge1xuICBjb25zdCBkZWZpbml0aW9uU3RhcnQgPSBkZWZpbml0aW9uLnBvc2l0aW9uLnN0YXJ0Lm9mZnNldDtcbiAgY29uc3QgZGVmaW5pdGlvbkVuZCA9IGRlZmluaXRpb24ucG9zaXRpb24uZW5kLm9mZnNldDtcbiAgaWYgKGRlZmluaXRpb25TdGFydCA8IDAgfHwgZGVmaW5pdGlvbkVuZCA+IGNvbnRlbnQubGVuZ3RoIHx8IGRlZmluaXRpb25FbmQgPCBkZWZpbml0aW9uU3RhcnQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGRlZmluaXRpb25UZXh0ID0gY29udGVudC5zbGljZShkZWZpbml0aW9uU3RhcnQsIGRlZmluaXRpb25FbmQpO1xuICBjb25zdCBwcmVmaXggPSBERUZJTklUSU9OX1BSRUZJWF9SRUdfRVhQLmV4ZWMoZGVmaW5pdGlvblRleHQpO1xuICBpZiAoIXByZWZpeCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdG9rZW5TdGFydCA9IHByZWZpeFswXS5sZW5ndGg7XG4gIGNvbnN0IGlzQW5nbGUgPSBkZWZpbml0aW9uVGV4dC5jaGFyQXQodG9rZW5TdGFydCkgPT09ICc8JztcbiAgbGV0IHRva2VuRW5kID0gaXNBbmdsZSA/IHRva2VuU3RhcnQgKyAxIDogdG9rZW5TdGFydDtcbiAgZm9yICg7IHRva2VuRW5kIDwgZGVmaW5pdGlvblRleHQubGVuZ3RoOyB0b2tlbkVuZCsrKSB7XG4gICAgY29uc3QgY2hhcmFjdGVyID0gZGVmaW5pdGlvblRleHQuY2hhckF0KHRva2VuRW5kKTtcbiAgICBpZiAoaXNBbmdsZSA/IGNoYXJhY3RlciA9PT0gJz4nIHx8IExJTkVfQlJFQUtfUkVHX0VYUC50ZXN0KGNoYXJhY3RlcikgOiBXSElURVNQQUNFX1JFR19FWFAudGVzdChjaGFyYWN0ZXIpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKGNoYXJhY3RlciA9PT0gJ1xcXFwnICYmIEFTQ0lJX1BVTkNUVUFUSU9OX1JFR19FWFAudGVzdChkZWZpbml0aW9uVGV4dC5jaGFyQXQodG9rZW5FbmQgKyAxKSkpIHtcbiAgICAgIHRva2VuRW5kKys7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzQW5nbGUpIHtcbiAgICBpZiAoZGVmaW5pdGlvblRleHQuY2hhckF0KHRva2VuRW5kKSAhPT0gJz4nKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdG9rZW5FbmQrKztcbiAgfVxuXG4gIGNvbnN0IGJvdW5kYXJ5ID0gZGVmaW5pdGlvblRleHQuY2hhckF0KHRva2VuRW5kKTtcbiAgaWYgKGJvdW5kYXJ5ICE9PSAnJyAmJiAhV0hJVEVTUEFDRV9SRUdfRVhQLnRlc3QoYm91bmRhcnkpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCByYXcgPSBkZWZpbml0aW9uVGV4dC5zbGljZSh0b2tlblN0YXJ0LCB0b2tlbkVuZCk7XG4gIGNvbnN0IHZhbHVlID0gaXNBbmdsZSA/IHJhdy5zbGljZSgxLCAtMSkgOiByYXc7XG4gIGlmICh0b2tlbkVuZCA9PT0gdG9rZW5TdGFydCB8fCB1bmVzY2FwZURlc3RpbmF0aW9uKHZhbHVlKSAhPT0gZGVmaW5pdGlvbi5saW5rKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVuZDogZGVmaW5pdGlvblN0YXJ0ICsgdG9rZW5FbmQsXG4gICAgaXNBbmdsZSxcbiAgICByYXcsXG4gICAgc3RhcnQ6IGRlZmluaXRpb25TdGFydCArIHRva2VuU3RhcnRcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0TG9jKGNvbnRlbnQ6IHN0cmluZywgZGVmaW5pdGlvbjogUmVmZXJlbmNlTGlua0NhY2hlLCBvZmZzZXQ6IG51bWJlcik6IExvYyB7XG4gIGNvbnN0IGRlZmluaXRpb25TdGFydCA9IGRlZmluaXRpb24ucG9zaXRpb24uc3RhcnQub2Zmc2V0O1xuICBsZXQgbGluZSA9IGRlZmluaXRpb24ucG9zaXRpb24uc3RhcnQubGluZTtcbiAgZm9yIChsZXQgaW5kZXggPSBkZWZpbml0aW9uU3RhcnQ7IGluZGV4IDwgb2Zmc2V0OyBpbmRleCsrKSB7XG4gICAgaWYgKGNvbnRlbnQuY2hhckF0KGluZGV4KSA9PT0gJ1xcbicpIHtcbiAgICAgIGxpbmUrKztcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNvbDogb2Zmc2V0IC0gKGNvbnRlbnQubGFzdEluZGV4T2YoJ1xcbicsIG9mZnNldCAtIDEpICsgMSksXG4gICAgbGluZSxcbiAgICBvZmZzZXRcbiAgfTtcbn1cblxuZnVuY3Rpb24gdW5lc2NhcGVEZXN0aW5hdGlvbih2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgdmFsdWUubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgY29uc3QgY2hhcmFjdGVyID0gdmFsdWUuY2hhckF0KGluZGV4KTtcbiAgICBjb25zdCBuZXh0Q2hhcmFjdGVyID0gdmFsdWUuY2hhckF0KGluZGV4ICsgMSk7XG4gICAgaWYgKGNoYXJhY3RlciA9PT0gJ1xcXFwnICYmIEFTQ0lJX1BVTkNUVUFUSU9OX1JFR19FWFAudGVzdChuZXh0Q2hhcmFjdGVyKSkge1xuICAgICAgcmVzdWx0ICs9IG5leHRDaGFyYWN0ZXI7XG4gICAgICBpbmRleCsrO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQgKz0gY2hhcmFjdGVyO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFxQkEsbUJBQXVDO0FBNkJ2QyxNQUFNLDRCQUE0QjtBQUNsQyxNQUFNLCtDQUErQztBQUNyRCxNQUFNLDRCQUE0QjtBQUNsQyxNQUFNLHFCQUFxQjtBQUMzQixNQUFNLHFCQUFxQjtBQWdCcEIsU0FBUyxnQ0FBZ0MsUUFBa0U7QUFDaEgsUUFBTSxFQUFFLFNBQVMsWUFBWSxlQUFlLElBQUk7QUFDaEQsUUFBTSxrQ0FBOEIscUNBQXVCLHFEQUFxRDtBQUVoSCxRQUFNLFFBQVEscUJBQXFCLFNBQVMsVUFBVTtBQUN0RCxNQUFJLENBQUMsT0FBTztBQUNWLGdDQUE0QixtRUFBbUUsRUFBRSxXQUFXLENBQUM7QUFDN0csV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLFNBQVMsa0JBQWtCLGdCQUFnQixNQUFNLE9BQU87QUFDOUQsTUFBSSxXQUFXLE1BQU07QUFDbkIsZ0NBQTRCLGtEQUFrRCxFQUFFLFlBQVksZUFBZSxDQUFDO0FBQzVHLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxZQUE0QjtBQUFBLElBQ2hDLE1BQU0sV0FBVztBQUFBLElBQ2pCLFVBQVUsTUFBTTtBQUFBLElBQ2hCLFVBQVU7QUFBQSxNQUNSLEtBQUssT0FBTyxTQUFTLFlBQVksTUFBTSxHQUFHO0FBQUEsTUFDMUMsT0FBTyxPQUFPLFNBQVMsWUFBWSxNQUFNLEtBQUs7QUFBQSxJQUNoRDtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQUEsSUFDTCxZQUFZO0FBQUEsSUFDWixZQUFZLE1BQU07QUFBQSxJQUNsQjtBQUFBLEVBQ0Y7QUFDRjtBQUVBLFNBQVMsVUFBVSxhQUE4QjtBQUMvQyxNQUFJLGdCQUFnQixNQUFNLFlBQVksV0FBVyxHQUFHLEtBQUssNkNBQTZDLEtBQUssV0FBVyxHQUFHO0FBQ3ZILFdBQU87QUFBQSxFQUNUO0FBRUEsTUFBSSxRQUFRO0FBQ1osYUFBVyxhQUFhLGFBQWE7QUFDbkMsUUFBSSxjQUFjLEtBQUs7QUFDckI7QUFBQSxJQUNGLFdBQVcsY0FBYyxLQUFLO0FBQzVCO0FBQ0EsVUFBSSxRQUFRLEdBQUc7QUFDYixlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsU0FBTyxVQUFVO0FBQ25CO0FBRUEsU0FBUyxrQkFBa0IsYUFBcUIsU0FBaUM7QUFDL0UsTUFBSSxtQkFBbUIsS0FBSyxXQUFXLEdBQUc7QUFDeEMsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLGlCQUFpQixXQUFXLENBQUMsVUFBVSxXQUFXO0FBQ3hELE1BQUksVUFBVTtBQUNkLFdBQVMsUUFBUSxHQUFHLFFBQVEsWUFBWSxRQUFRLFNBQVM7QUFDdkQsVUFBTSxZQUFZLFlBQVksT0FBTyxLQUFLO0FBQzFDLFVBQU0sZ0JBQWdCLFlBQVksT0FBTyxRQUFRLENBQUM7QUFDbEQsVUFBTSxpQkFBaUIsaUJBQ25CLGNBQWMsT0FBTyxjQUFjLE9BQVEsY0FBYyxTQUFTLGtCQUFrQixNQUFNLDBCQUEwQixLQUFLLGFBQWEsS0FDdEksY0FBYyxRQUFRLDBCQUEwQixLQUFLLGFBQWE7QUFDdEUsZUFBVyxpQkFBaUIsS0FBSyxTQUFTLEtBQUs7QUFBQSxFQUNqRDtBQUVBLFNBQU8saUJBQWlCLElBQUksT0FBTyxNQUFNO0FBQzNDO0FBRUEsU0FBUyxxQkFBcUIsU0FBaUIsWUFBeUQ7QUFDdEcsUUFBTSxrQkFBa0IsV0FBVyxTQUFTLE1BQU07QUFDbEQsUUFBTSxnQkFBZ0IsV0FBVyxTQUFTLElBQUk7QUFDOUMsTUFBSSxrQkFBa0IsS0FBSyxnQkFBZ0IsUUFBUSxVQUFVLGdCQUFnQixpQkFBaUI7QUFDNUYsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLGlCQUFpQixRQUFRLE1BQU0saUJBQWlCLGFBQWE7QUFDbkUsUUFBTSxTQUFTLDBCQUEwQixLQUFLLGNBQWM7QUFDNUQsTUFBSSxDQUFDLFFBQVE7QUFDWCxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sYUFBYSxPQUFPLENBQUMsRUFBRTtBQUM3QixRQUFNLFVBQVUsZUFBZSxPQUFPLFVBQVUsTUFBTTtBQUN0RCxNQUFJLFdBQVcsVUFBVSxhQUFhLElBQUk7QUFDMUMsU0FBTyxXQUFXLGVBQWUsUUFBUSxZQUFZO0FBQ25ELFVBQU0sWUFBWSxlQUFlLE9BQU8sUUFBUTtBQUNoRCxRQUFJLFVBQVUsY0FBYyxPQUFPLG1CQUFtQixLQUFLLFNBQVMsSUFBSSxtQkFBbUIsS0FBSyxTQUFTLEdBQUc7QUFDMUc7QUFBQSxJQUNGO0FBQ0EsUUFBSSxjQUFjLFFBQVEsMEJBQTBCLEtBQUssZUFBZSxPQUFPLFdBQVcsQ0FBQyxDQUFDLEdBQUc7QUFDN0Y7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLE1BQUksU0FBUztBQUNYLFFBQUksZUFBZSxPQUFPLFFBQVEsTUFBTSxLQUFLO0FBQzNDLGFBQU87QUFBQSxJQUNUO0FBQ0E7QUFBQSxFQUNGO0FBRUEsUUFBTSxXQUFXLGVBQWUsT0FBTyxRQUFRO0FBQy9DLE1BQUksYUFBYSxNQUFNLENBQUMsbUJBQW1CLEtBQUssUUFBUSxHQUFHO0FBQ3pELFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxNQUFNLGVBQWUsTUFBTSxZQUFZLFFBQVE7QUFDckQsUUFBTSxRQUFRLFVBQVUsSUFBSSxNQUFNLEdBQUcsRUFBRSxJQUFJO0FBQzNDLE1BQUksYUFBYSxjQUFjLG9CQUFvQixLQUFLLE1BQU0sV0FBVyxNQUFNO0FBQzdFLFdBQU87QUFBQSxFQUNUO0FBRUEsU0FBTztBQUFBLElBQ0wsS0FBSyxrQkFBa0I7QUFBQSxJQUN2QjtBQUFBLElBQ0E7QUFBQSxJQUNBLE9BQU8sa0JBQWtCO0FBQUEsRUFDM0I7QUFDRjtBQUVBLFNBQVMsT0FBTyxTQUFpQixZQUFnQyxRQUFxQjtBQUNwRixRQUFNLGtCQUFrQixXQUFXLFNBQVMsTUFBTTtBQUNsRCxNQUFJLE9BQU8sV0FBVyxTQUFTLE1BQU07QUFDckMsV0FBUyxRQUFRLGlCQUFpQixRQUFRLFFBQVEsU0FBUztBQUN6RCxRQUFJLFFBQVEsT0FBTyxLQUFLLE1BQU0sTUFBTTtBQUNsQztBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUFBLElBQ0wsS0FBSyxVQUFVLFFBQVEsWUFBWSxNQUFNLFNBQVMsQ0FBQyxJQUFJO0FBQUEsSUFDdkQ7QUFBQSxJQUNBO0FBQUEsRUFDRjtBQUNGO0FBRUEsU0FBUyxvQkFBb0IsT0FBdUI7QUFDbEQsTUFBSSxTQUFTO0FBQ2IsV0FBUyxRQUFRLEdBQUcsUUFBUSxNQUFNLFFBQVEsU0FBUztBQUNqRCxVQUFNLFlBQVksTUFBTSxPQUFPLEtBQUs7QUFDcEMsVUFBTSxnQkFBZ0IsTUFBTSxPQUFPLFFBQVEsQ0FBQztBQUM1QyxRQUFJLGNBQWMsUUFBUSwwQkFBMEIsS0FBSyxhQUFhLEdBQUc7QUFDdkUsZ0JBQVU7QUFDVjtBQUFBLElBQ0YsT0FBTztBQUNMLGdCQUFVO0FBQUEsSUFDWjtBQUFBLEVBQ0Y7QUFFQSxTQUFPO0FBQ1Q7IiwibmFtZXMiOltdfQ==
@@ -0,0 +1,47 @@
1
+ /// <reference path="./library-references.d.cts" />
2
+ /**
3
+ * @file
4
+ *
5
+ * Edits the destination of a reference-style link definition (`[id]: destination "title"`) that Obsidian reports
6
+ * in `CachedMetadata.referenceLinks`.
7
+ *
8
+ * Read from Obsidian `1.15.1`: a definition's `position` spans the whole definition, its leading indentation
9
+ * included and any blockquote or list marker excluded, and its `link` is the destination with the angle brackets
10
+ * removed and every backslash escape resolved (`Target\#Escaped.md` reports `Target#Escaped.md`). The uses of a
11
+ * definition (`[text][id]`, `[id][]`, `[id]`) are not reported in `links` and name the definition by its id, so
12
+ * rewriting only the destination keeps every one of them pointing at the new target.
13
+ */
14
+ import type { ReferenceLinkCache } from 'obsidian' with { 'resolution-mode': 'import' };
15
+ import type { FileChange } from './file-change.cjs';
16
+ /**
17
+ * Parameters for {@link referenceDefinitionToFileChange}.
18
+ */
19
+ export interface ReferenceDefinitionToFileChangeParams {
20
+ /**
21
+ * The content the definition's position refers to.
22
+ */
23
+ readonly content: string;
24
+ /**
25
+ * The definition, as Obsidian reports it in `CachedMetadata.referenceLinks`.
26
+ */
27
+ readonly definition: ReferenceLinkCache;
28
+ /**
29
+ * The new destination, unescaped, in the same form as {@link ReferenceLinkCache.link}.
30
+ */
31
+ readonly newDestination: string;
32
+ }
33
+ /**
34
+ * Builds the file change that replaces the destination of a reference-style link definition, leaving its id, its
35
+ * title and the rest of the note unchanged.
36
+ *
37
+ * The destination keeps its form: one written in angle brackets stays in them, and a bare one stays bare unless
38
+ * the new destination cannot be written bare (it is empty, holds whitespace or a control character, starts with
39
+ * `<`, or has unbalanced parentheses), in which case it is written in angle brackets. Characters that would end
40
+ * or change the destination are escaped with a backslash.
41
+ *
42
+ * @param params - The parameters for building the file change.
43
+ * @returns The file change, or `null` when the content at the definition's position no longer holds a definition
44
+ * whose destination reads as {@link ReferenceLinkCache.link}, or when the new destination holds a line break,
45
+ * which no destination can.
46
+ */
47
+ export declare function referenceDefinitionToFileChange(params: ReferenceDefinitionToFileChangeParams): FileChange | null;