@anvilkit/plugin-asset-manager 0.1.7 → 0.1.9

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 (141) hide show
  1. package/README.md +4 -4
  2. package/dist/adapters/data-url.d.cts +13 -0
  3. package/dist/adapters/data-url.d.cts.map +1 -1
  4. package/dist/adapters/data-url.d.ts +13 -0
  5. package/dist/adapters/data-url.d.ts.map +1 -1
  6. package/dist/adapters/in-memory.d.cts +8 -1
  7. package/dist/adapters/in-memory.d.cts.map +1 -1
  8. package/dist/adapters/in-memory.d.ts +8 -1
  9. package/dist/adapters/in-memory.d.ts.map +1 -1
  10. package/dist/i18n/entry.cjs +75 -0
  11. package/dist/i18n/entry.d.cts +15 -0
  12. package/dist/i18n/entry.d.cts.map +1 -0
  13. package/dist/i18n/entry.d.ts +15 -0
  14. package/dist/i18n/entry.d.ts.map +1 -0
  15. package/dist/i18n/entry.js +29 -0
  16. package/dist/i18n/provider.cjs +49 -0
  17. package/dist/i18n/provider.d.cts +20 -0
  18. package/dist/i18n/provider.d.cts.map +1 -0
  19. package/dist/i18n/provider.d.ts +20 -0
  20. package/dist/i18n/provider.d.ts.map +1 -0
  21. package/dist/i18n/provider.js +11 -0
  22. package/dist/plugin.cjs +3 -1
  23. package/dist/plugin.d.cts.map +1 -1
  24. package/dist/plugin.d.ts.map +1 -1
  25. package/dist/plugin.js +3 -1
  26. package/dist/sources/composite-source.cjs +4 -3
  27. package/dist/sources/composite-source.d.cts.map +1 -1
  28. package/dist/sources/composite-source.d.ts.map +1 -1
  29. package/dist/sources/composite-source.js +4 -3
  30. package/dist/sources/federated-search.cjs +16 -6
  31. package/dist/sources/federated-search.d.cts.map +1 -1
  32. package/dist/sources/federated-search.d.ts.map +1 -1
  33. package/dist/sources/federated-search.js +16 -6
  34. package/dist/sources/unsplash/index.cjs +6 -4
  35. package/dist/sources/unsplash/index.d.cts.map +1 -1
  36. package/dist/sources/unsplash/index.d.ts.map +1 -1
  37. package/dist/sources/unsplash/index.js +6 -4
  38. package/dist/types/types.d.cts +7 -1
  39. package/dist/types/types.d.cts.map +1 -1
  40. package/dist/types/types.d.ts +7 -1
  41. package/dist/types/types.d.ts.map +1 -1
  42. package/dist/ui/AssetBrowser.cjs +175 -134
  43. package/dist/ui/AssetBrowser.d.cts.map +1 -1
  44. package/dist/ui/AssetBrowser.d.ts.map +1 -1
  45. package/dist/ui/AssetBrowser.js +175 -134
  46. package/dist/ui/AssetCommandPalette.cjs +20 -18
  47. package/dist/ui/AssetCommandPalette.d.cts.map +1 -1
  48. package/dist/ui/AssetCommandPalette.d.ts.map +1 -1
  49. package/dist/ui/AssetCommandPalette.js +20 -18
  50. package/dist/ui/AssetManagerUI.cjs +23 -15
  51. package/dist/ui/AssetManagerUI.d.cts.map +1 -1
  52. package/dist/ui/AssetManagerUI.d.ts.map +1 -1
  53. package/dist/ui/AssetManagerUI.js +23 -15
  54. package/dist/ui/DeleteAssetDialog.cjs +5 -3
  55. package/dist/ui/DeleteAssetDialog.d.cts.map +1 -1
  56. package/dist/ui/DeleteAssetDialog.d.ts.map +1 -1
  57. package/dist/ui/DeleteAssetDialog.js +5 -3
  58. package/dist/ui/DeleteFolderDialog.cjs +6 -4
  59. package/dist/ui/DeleteFolderDialog.d.cts.map +1 -1
  60. package/dist/ui/DeleteFolderDialog.d.ts.map +1 -1
  61. package/dist/ui/DeleteFolderDialog.js +6 -4
  62. package/dist/ui/EmptyFolderState.cjs +6 -3
  63. package/dist/ui/EmptyFolderState.d.cts +1 -1
  64. package/dist/ui/EmptyFolderState.d.cts.map +1 -1
  65. package/dist/ui/EmptyFolderState.d.ts +1 -1
  66. package/dist/ui/EmptyFolderState.d.ts.map +1 -1
  67. package/dist/ui/EmptyFolderState.js +6 -3
  68. package/dist/ui/FolderBreadcrumb.cjs +7 -4
  69. package/dist/ui/FolderBreadcrumb.d.cts.map +1 -1
  70. package/dist/ui/FolderBreadcrumb.d.ts.map +1 -1
  71. package/dist/ui/FolderBreadcrumb.js +7 -4
  72. package/dist/ui/FolderNameDialog.cjs +19 -12
  73. package/dist/ui/FolderNameDialog.d.cts.map +1 -1
  74. package/dist/ui/FolderNameDialog.d.ts.map +1 -1
  75. package/dist/ui/FolderNameDialog.js +19 -12
  76. package/dist/ui/FolderTree.cjs +4 -2
  77. package/dist/ui/FolderTree.d.cts.map +1 -1
  78. package/dist/ui/FolderTree.d.ts.map +1 -1
  79. package/dist/ui/FolderTree.js +4 -2
  80. package/dist/ui/MetadataPanel.cjs +16 -13
  81. package/dist/ui/MetadataPanel.d.cts.map +1 -1
  82. package/dist/ui/MetadataPanel.d.ts.map +1 -1
  83. package/dist/ui/MetadataPanel.js +16 -13
  84. package/dist/ui/MoveTargetPicker.cjs +7 -4
  85. package/dist/ui/MoveTargetPicker.d.cts.map +1 -1
  86. package/dist/ui/MoveTargetPicker.d.ts.map +1 -1
  87. package/dist/ui/MoveTargetPicker.js +7 -4
  88. package/dist/ui/ReplaceAssetDialog.cjs +19 -17
  89. package/dist/ui/ReplaceAssetDialog.d.cts.map +1 -1
  90. package/dist/ui/ReplaceAssetDialog.d.ts.map +1 -1
  91. package/dist/ui/ReplaceAssetDialog.js +19 -17
  92. package/dist/ui/UnsplashPanel.cjs +15 -12
  93. package/dist/ui/UnsplashPanel.d.cts.map +1 -1
  94. package/dist/ui/UnsplashPanel.d.ts.map +1 -1
  95. package/dist/ui/UnsplashPanel.js +15 -12
  96. package/dist/ui/UploadButton.cjs +11 -8
  97. package/dist/ui/UploadButton.d.cts.map +1 -1
  98. package/dist/ui/UploadButton.d.ts.map +1 -1
  99. package/dist/ui/UploadButton.js +11 -8
  100. package/dist/ui/index.cjs +4 -0
  101. package/dist/ui/index.d.cts +1 -0
  102. package/dist/ui/index.d.cts.map +1 -1
  103. package/dist/ui/index.d.ts +1 -0
  104. package/dist/ui/index.d.ts.map +1 -1
  105. package/dist/ui/index.js +1 -0
  106. package/dist/utils/data-source.cjs +18 -5
  107. package/dist/utils/data-source.d.cts.map +1 -1
  108. package/dist/utils/data-source.d.ts.map +1 -1
  109. package/dist/utils/data-source.js +19 -6
  110. package/dist/utils/folders.cjs +107 -33
  111. package/dist/utils/folders.d.cts +7 -2
  112. package/dist/utils/folders.d.cts.map +1 -1
  113. package/dist/utils/folders.d.ts +7 -2
  114. package/dist/utils/folders.d.ts.map +1 -1
  115. package/dist/utils/folders.js +107 -33
  116. package/dist/utils/header-action.cjs +1 -1
  117. package/dist/utils/header-action.d.cts.map +1 -1
  118. package/dist/utils/header-action.d.ts.map +1 -1
  119. package/dist/utils/header-action.js +1 -1
  120. package/dist/utils/registry.cjs +23 -12
  121. package/dist/utils/registry.d.cts +16 -8
  122. package/dist/utils/registry.d.cts.map +1 -1
  123. package/dist/utils/registry.d.ts +16 -8
  124. package/dist/utils/registry.d.ts.map +1 -1
  125. package/dist/utils/registry.js +19 -8
  126. package/dist/utils/resolver.cjs +5 -4
  127. package/dist/utils/resolver.d.cts.map +1 -1
  128. package/dist/utils/resolver.d.ts.map +1 -1
  129. package/dist/utils/resolver.js +5 -4
  130. package/dist/utils/studio-asset-source.cjs +8 -2
  131. package/dist/utils/studio-asset-source.js +8 -2
  132. package/dist/version.cjs +1 -1
  133. package/dist/version.d.cts +1 -1
  134. package/dist/version.d.ts +1 -1
  135. package/dist/version.js +1 -1
  136. package/i18n/messages/en.json +99 -0
  137. package/i18n/messages/ja.json +99 -0
  138. package/i18n/messages/ko.json +99 -0
  139. package/i18n/messages/zh.json +99 -0
  140. package/meta/config.json +1 -1
  141. package/package.json +11 -10
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.cts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,SAAS,EACT,aAAa,EAGb,eAAe,EACf,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAK3B,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD;AAmDD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE;IACR,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,GACC,OAAO,CAiBT;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D,eAAe,CAejB"}
1
+ {"version":3,"file":"registry.d.cts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,SAAS,EACT,aAAa,EAGb,eAAe,EACf,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAK3B,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD;AAmDD,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,gBAAgB,GACvB,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAclC;AAaD;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D,eAAe,CAejB"}
@@ -1,16 +1,24 @@
1
1
  import type { AssetKind, AssetRegistry, AssetSearchPage, UploadResult } from "../types/types.js";
2
2
  export declare function createAssetRegistry(): AssetRegistry;
3
- /**
4
- * Pure predicate: does `entry` satisfy the query / kind / tag filters? Exported
5
- * so the in-memory data-source compose layer applies the EXACT same matching
6
- * before adding its folder clause (PRD 0002 §9.2 — single source of truth for
7
- * search semantics).
8
- */
9
- export declare function assetMatchesSearch(entry: UploadResult, options: {
3
+ /** Query / kind / tag filter shared by the registry and the data-source path. */
4
+ export interface AssetMatchFilter {
10
5
  readonly query?: string;
11
6
  readonly kinds?: readonly AssetKind[];
12
7
  readonly tags?: readonly string[];
13
- }): boolean;
8
+ }
9
+ /**
10
+ * Compile a search filter into a reusable predicate. The query string and tag
11
+ * filter are trimmed + lowercased ONCE here, not once per candidate, so a scan
12
+ * over N assets normalizes the filter a single time instead of N times. This is
13
+ * the registry's search hot path — `AssetCommandPalette` re-runs a free-text
14
+ * query on every keystroke — so build the matcher once, then apply it across the
15
+ * list (see `runSearch`).
16
+ *
17
+ * Exported so the in-memory data-source compose layer applies the EXACT same
18
+ * matching before adding its folder clause (PRD 0002 §9.2 — single source of
19
+ * truth for search semantics).
20
+ */
21
+ export declare function prepareAssetMatcher(options: AssetMatchFilter): (entry: UploadResult) => boolean;
14
22
  /**
15
23
  * Pure offset-cursor pagination over a pre-filtered match list. Shared by
16
24
  * `runSearch` and the folder-scoped data-source path so the cursor contract is
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,SAAS,EACT,aAAa,EAGb,eAAe,EACf,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAK3B,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD;AAmDD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE;IACR,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,GACC,OAAO,CAiBT;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D,eAAe,CAejB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/utils/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,SAAS,EACT,aAAa,EAGb,eAAe,EACf,YAAY,EACZ,MAAM,mBAAmB,CAAC;AAK3B,wBAAgB,mBAAmB,IAAI,aAAa,CA6EnD;AAmDD,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,gBAAgB,GACvB,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAclC;AAaD;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5D,eAAe,CAejB"}
@@ -122,15 +122,25 @@ function normalizeTags(tags) {
122
122
  }
123
123
  return out;
124
124
  }
125
- function assetMatchesSearch(entry, options) {
125
+ function prepareAssetMatcher(options) {
126
126
  const query = options.query?.trim().toLowerCase() ?? "";
127
- if (!matchesQuery(entry, query)) return false;
128
- if (options.kinds && options.kinds.length > 0 && !options.kinds.includes(inferAssetKind(entry))) return false;
129
- if (options.tags && options.tags.length > 0) {
130
- const tagFilter = options.tags.map((t)=>t.trim().toLowerCase()).filter((t)=>"" !== t);
127
+ const kindSet = options.kinds && options.kinds.length > 0 ? new Set(options.kinds) : null;
128
+ const tagFilter = normalizeTagFilter(options.tags);
129
+ return (entry)=>{
130
+ if (!matchesQuery(entry, query)) return false;
131
+ if (null !== kindSet && !kindSet.has(inferAssetKind(entry))) return false;
131
132
  if (tagFilter.length > 0 && !matchesAllTags(entry, tagFilter)) return false;
133
+ return true;
134
+ };
135
+ }
136
+ function normalizeTagFilter(tags) {
137
+ if (void 0 === tags || 0 === tags.length) return [];
138
+ const out = [];
139
+ for (const raw of tags){
140
+ const tag = raw.trim().toLowerCase();
141
+ if ("" !== tag) out.push(tag);
132
142
  }
133
- return true;
143
+ return out;
134
144
  }
135
145
  function paginateMatches(matches, options) {
136
146
  const total = matches.length;
@@ -147,7 +157,8 @@ function paginateMatches(matches, options) {
147
157
  }
148
158
  function runSearch(assetsById, options) {
149
159
  const matches = [];
150
- for (const entry of assetsById.values())if (assetMatchesSearch(entry, options)) matches.push(entry);
160
+ const matcher = prepareAssetMatcher(options);
161
+ for (const entry of assetsById.values())if (matcher(entry)) matches.push(entry);
151
162
  return paginateMatches(matches, options);
152
163
  }
153
164
  function matchesQuery(entry, query) {
@@ -170,4 +181,4 @@ function parseCursor(cursor) {
170
181
  if (!Number.isFinite(value) || value < 0) return 0;
171
182
  return value;
172
183
  }
173
- export { assetMatchesSearch, createAssetRegistry, paginateMatches };
184
+ export { createAssetRegistry, paginateMatches, prepareAssetMatcher };
@@ -93,10 +93,11 @@ function createIRAssetResolver(options) {
93
93
  async function resolveAssets(ir, resolver) {
94
94
  const rewriteMap = new Map();
95
95
  const assetUrls = collectAssetUrls(ir);
96
- for (const url of assetUrls){
97
- const resolution = await resolver(url);
98
- if (null !== resolution) rewriteMap.set(url, resolution);
99
- }
96
+ const resolutions = await Promise.all(Array.from(assetUrls, async (url)=>[
97
+ url,
98
+ await resolver(url)
99
+ ]));
100
+ for (const [url, resolution] of resolutions)if (null !== resolution) rewriteMap.set(url, resolution);
100
101
  const nextIr = {
101
102
  version: ir.version,
102
103
  root: cloneNode(ir.root, rewriteMap),
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.cts","sourceRoot":"","sources":["../../src/utils/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,eAAe,EACf,MAAM,EAGN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8BvD,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,4BAA4B,GACnC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
1
+ {"version":3,"file":"resolver.d.cts","sourceRoot":"","sources":["../../src/utils/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,eAAe,EACf,MAAM,EAGN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8BvD,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,4BAA4B,GACnC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/utils/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,eAAe,EACf,MAAM,EAGN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8BvD,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,4BAA4B,GACnC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/utils/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,eAAe,EACf,MAAM,EAGN,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA8BvD,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC;CAC7C;AAED,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,4BAA4B,GACnC,eAAe,CAgDjB;AAED,wBAAsB,aAAa,CAClC,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,eAAe,GACvB,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -60,10 +60,11 @@ function createIRAssetResolver(options) {
60
60
  async function resolveAssets(ir, resolver) {
61
61
  const rewriteMap = new Map();
62
62
  const assetUrls = collectAssetUrls(ir);
63
- for (const url of assetUrls){
64
- const resolution = await resolver(url);
65
- if (null !== resolution) rewriteMap.set(url, resolution);
66
- }
63
+ const resolutions = await Promise.all(Array.from(assetUrls, async (url)=>[
64
+ url,
65
+ await resolver(url)
66
+ ]));
67
+ for (const [url, resolution] of resolutions)if (null !== resolution) rewriteMap.set(url, resolution);
67
68
  const nextIr = {
68
69
  version: ir.version,
69
70
  root: cloneNode(ir.root, rewriteMap),
@@ -42,7 +42,7 @@ function createStudioAssetSource(options) {
42
42
  const project = (entry)=>toStudioAsset(entry, getThumbnail);
43
43
  const uploadListeners = new Set();
44
44
  const fanOut = (event)=>{
45
- for (const listener of uploadListeners)listener(event);
45
+ for (const subscriber of uploadListeners)safeNotify(subscriber, event);
46
46
  };
47
47
  return {
48
48
  list () {
@@ -82,7 +82,7 @@ function createStudioAssetSource(options) {
82
82
  let nextIndex = 0;
83
83
  let abortError;
84
84
  const emit = (event)=>{
85
- listener?.(event);
85
+ safeNotify(listener, event);
86
86
  fanOut(event);
87
87
  };
88
88
  const abortFromSignal = ()=>{
@@ -213,6 +213,12 @@ function deriveFallbackName(entry) {
213
213
  const idTail = entry.id.length > 12 ? `${entry.id.slice(0, 8)}…` : entry.id;
214
214
  return `Asset ${idTail}`;
215
215
  }
216
+ function safeNotify(listener, event) {
217
+ if (void 0 === listener) return;
218
+ try {
219
+ listener(event);
220
+ } catch {}
221
+ }
216
222
  function isAbortError(error) {
217
223
  if (null === error || "object" != typeof error) return false;
218
224
  const name = error.name;
@@ -7,7 +7,7 @@ function createStudioAssetSource(options) {
7
7
  const project = (entry)=>toStudioAsset(entry, getThumbnail);
8
8
  const uploadListeners = new Set();
9
9
  const fanOut = (event)=>{
10
- for (const listener of uploadListeners)listener(event);
10
+ for (const subscriber of uploadListeners)safeNotify(subscriber, event);
11
11
  };
12
12
  return {
13
13
  list () {
@@ -47,7 +47,7 @@ function createStudioAssetSource(options) {
47
47
  let nextIndex = 0;
48
48
  let abortError;
49
49
  const emit = (event)=>{
50
- listener?.(event);
50
+ safeNotify(listener, event);
51
51
  fanOut(event);
52
52
  };
53
53
  const abortFromSignal = ()=>{
@@ -178,6 +178,12 @@ function deriveFallbackName(entry) {
178
178
  const idTail = entry.id.length > 12 ? `${entry.id.slice(0, 8)}…` : entry.id;
179
179
  return `Asset ${idTail}`;
180
180
  }
181
+ function safeNotify(listener, event) {
182
+ if (void 0 === listener) return;
183
+ try {
184
+ listener(event);
185
+ } catch {}
186
+ }
181
187
  function isAbortError(error) {
182
188
  if (null === error || "object" != typeof error) return false;
183
189
  const name = error.name;
package/dist/version.cjs CHANGED
@@ -27,7 +27,7 @@ var __webpack_require__ = {};
27
27
  })();
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
- const ASSET_MANAGER_VERSION = "0.1.7";
30
+ const ASSET_MANAGER_VERSION = "0.1.9";
31
31
  __webpack_require__.d(__webpack_exports__, {}, {
32
32
  ASSET_MANAGER_VERSION: ASSET_MANAGER_VERSION
33
33
  });
@@ -16,5 +16,5 @@
16
16
  * constant ships only the version. Mirrors `@anvilkit/core`'s
17
17
  * `runtime/version.ts`, which makes the same call.
18
18
  */
19
- export declare const ASSET_MANAGER_VERSION = "0.1.7";
19
+ export declare const ASSET_MANAGER_VERSION = "0.1.9";
20
20
  //# sourceMappingURL=version.d.cts.map
package/dist/version.d.ts CHANGED
@@ -16,5 +16,5 @@
16
16
  * constant ships only the version. Mirrors `@anvilkit/core`'s
17
17
  * `runtime/version.ts`, which makes the same call.
18
18
  */
19
- export declare const ASSET_MANAGER_VERSION = "0.1.7";
19
+ export declare const ASSET_MANAGER_VERSION = "0.1.9";
20
20
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- const ASSET_MANAGER_VERSION = "0.1.7";
1
+ const ASSET_MANAGER_VERSION = "0.1.9";
2
2
  export { ASSET_MANAGER_VERSION };
@@ -0,0 +1,99 @@
1
+ {
2
+ "assetManager.action.upload": "Upload asset",
3
+ "assetManager.button.cancel": "Cancel",
4
+ "assetManager.button.delete": "Delete",
5
+ "assetManager.button.replace": "Replace",
6
+ "assetManager.button.create": "Create",
7
+ "assetManager.button.edit": "Edit",
8
+ "assetManager.button.save": "Save",
9
+ "assetManager.button.loadMore": "Load more",
10
+ "assetManager.button.deleteContents": "Delete contents",
11
+ "assetManager.dialog.deleteTitle": "Delete asset?",
12
+ "assetManager.dialog.deleteDescription": "will be removed from the registry. References to it in the page will fail to resolve.",
13
+ "assetManager.dialog.deleteReferenced": "This asset is referenced in {count} {nodes}.",
14
+ "assetManager.dialog.deleteProgress": "Deleting…",
15
+ "assetManager.dialog.replaceTitle": "Replace asset?",
16
+ "assetManager.dialog.replaceDescription": "Pick a file to replace {label} with. Existing asset:// references will resolve to the new bytes.",
17
+ "assetManager.dialog.replaceDescriptionGeneric": "Pick a file to replace this asset with.",
18
+ "assetManager.dialog.replaceFileLabel": "Replacement file",
19
+ "assetManager.dialog.chooseFile": "Choose file",
20
+ "assetManager.dialog.chooseFileDifferent": "Choose a different file",
21
+ "assetManager.dialog.fileSelected": "Selected: {name}",
22
+ "assetManager.dialog.noFileSelected": "No file selected.",
23
+ "assetManager.dialog.replaceProgress": "Replacing…",
24
+ "assetManager.dialog.newFolderTitle": "New folder",
25
+ "assetManager.dialog.folderSaveError": "Could not save the folder.",
26
+ "assetManager.dialog.folderNamePlaceholder": "Folder name",
27
+ "assetManager.dialog.saveProgress": "Saving…",
28
+ "assetManager.dialog.deleteFolderTitle": "Delete folder?",
29
+ "assetManager.dialog.deleteFolderDescription": "\"{name}\" will be removed. By default its contents move up to the parent folder, so nothing is deleted. Choose \"Delete contents\" to remove its {count} {assets} too.",
30
+ "assetManager.dialog.removeFolder": "Remove folder",
31
+ "assetManager.dialog.removeProgress": "Removing…",
32
+ "assetManager.dialog.editTitle": "Edit asset",
33
+ "assetManager.dialog.moveTitle": "Move to folder",
34
+ "assetManager.form.nameLabel": "Name",
35
+ "assetManager.form.tagsLabel": "Tags",
36
+ "assetManager.form.tagsListLabel": "Current tags",
37
+ "assetManager.form.removeTag": "Remove tag {tag}",
38
+ "assetManager.form.addTagPlaceholder": "Add a tag and press Enter",
39
+ "assetManager.browser.title": "Asset browser",
40
+ "assetManager.browser.subtitle": "Validated assets currently registered in memory.",
41
+ "assetManager.browser.searchLabel": "Search assets",
42
+ "assetManager.browser.searchPlaceholder": "Search by name, tag, or MIME",
43
+ "assetManager.browser.filterLabel": "Asset kind filters",
44
+ "assetManager.browser.filterByKind": "Filter {kind} assets",
45
+ "assetManager.browser.assetsLabel": "Assets",
46
+ "assetManager.browser.insert": "Insert asset {id}",
47
+ "assetManager.browser.edit": "Edit asset {id}",
48
+ "assetManager.browser.replace": "Replace asset {id}",
49
+ "assetManager.browser.delete": "Delete asset {id}",
50
+ "assetManager.browser.unknownMime": "unknown type",
51
+ "assetManager.browser.empty": "No assets uploaded yet.",
52
+ "assetManager.browser.emptyFiltered": "No assets match the current filters.",
53
+ "assetManager.palette.title": "Find an asset",
54
+ "assetManager.palette.subtitle": "Search by name, id, MIME type, or tag.",
55
+ "assetManager.palette.searchLabel": "Asset search query",
56
+ "assetManager.palette.searchPlaceholder": "Type to search…",
57
+ "assetManager.palette.resultsLabel": "Asset results",
58
+ "assetManager.palette.noMatches": "No matches.",
59
+ "assetManager.kind.image": "image",
60
+ "assetManager.kind.video": "video",
61
+ "assetManager.kind.audio": "audio",
62
+ "assetManager.kind.font": "font",
63
+ "assetManager.kind.document": "document",
64
+ "assetManager.ui.title": "Asset manager",
65
+ "assetManager.ui.subtitle": "Upload via the configured adapter, then insert a validated asset reference.",
66
+ "assetManager.upload.buttonLabel": "Upload asset file",
67
+ "assetManager.upload.button": "Upload asset",
68
+ "assetManager.upload.chooseLabel": "Choose files to upload",
69
+ "assetManager.upload.progress": "Uploading…",
70
+ "assetManager.upload.progressLabel": "Batch upload progress",
71
+ "assetManager.upload.status": "Uploading {completed} of {total}",
72
+ "assetManager.upload.statusProgress": "Uploading {completed} of {total}…",
73
+ "assetManager.upload.statusIdle": "Accepted files upload through the configured adapter.",
74
+ "assetManager.upload.toFolder": "Drop files here or upload",
75
+ "assetManager.folder.root": "All assets",
76
+ "assetManager.folder.empty": "This folder is empty.",
77
+ "assetManager.breadcrumb.label": "Folders",
78
+ "assetManager.tree.label": "Folders",
79
+ "assetManager.tree.dropHint": "Open {name} — or drop assets here to move them in",
80
+ "assetManager.unsplash.disabled": "Connect Unsplash by adding an access key via a server proxy.",
81
+ "assetManager.unsplash.loading": "Loading photos…",
82
+ "assetManager.unsplash.searchPlaceholder": "Search Unsplash…",
83
+ "assetManager.unsplash.themesLabel": "Unsplash themes",
84
+ "assetManager.unsplash.rateLimited": "Unsplash rate limit reached. Try again shortly.",
85
+ "assetManager.unsplash.error": "Couldn't reach Unsplash. Retry.",
86
+ "assetManager.unsplash.empty": "Search Unsplash to browse photos.",
87
+ "assetManager.unsplash.insert": "Insert photo by {photographer}",
88
+ "assetManager.source.library": "Library",
89
+ "assetManager.source.unsplash": "Unsplash",
90
+ "assetManager.unsplash.theme.all": "All",
91
+ "assetManager.unsplash.theme.nature": "Nature",
92
+ "assetManager.unsplash.theme.architecture": "Architecture",
93
+ "assetManager.unsplash.theme.business": "Business",
94
+ "assetManager.unsplash.theme.food": "Food",
95
+ "assetManager.unsplash.theme.technology": "Technology",
96
+ "assetManager.unsplash.theme.travel": "Travel",
97
+ "assetManager.unsplash.theme.texture": "Texture",
98
+ "assetManager.unsplash.theme.people": "People"
99
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "assetManager.action.upload": "アセットをアップロード",
3
+ "assetManager.button.cancel": "キャンセル",
4
+ "assetManager.button.delete": "削除",
5
+ "assetManager.button.replace": "置き換え",
6
+ "assetManager.button.create": "作成",
7
+ "assetManager.button.edit": "編集",
8
+ "assetManager.button.save": "保存",
9
+ "assetManager.button.loadMore": "さらに読み込む",
10
+ "assetManager.button.deleteContents": "内容を削除",
11
+ "assetManager.dialog.deleteTitle": "アセットを削除しますか?",
12
+ "assetManager.dialog.deleteDescription": "はレジストリから削除されます。ページ内のこのアセットへの参照は解決できなくなります。",
13
+ "assetManager.dialog.deleteReferenced": "このアセットは {count} 個の{nodes}で参照されています。",
14
+ "assetManager.dialog.deleteProgress": "削除中…",
15
+ "assetManager.dialog.replaceTitle": "アセットを置き換えますか?",
16
+ "assetManager.dialog.replaceDescription": "{label} を置き換えるファイルを選択してください。既存の asset:// 参照は新しいバイトに解決されます。",
17
+ "assetManager.dialog.replaceDescriptionGeneric": "このアセットを置き換えるファイルを選択してください。",
18
+ "assetManager.dialog.replaceFileLabel": "置き換えるファイル",
19
+ "assetManager.dialog.chooseFile": "ファイルを選択",
20
+ "assetManager.dialog.chooseFileDifferent": "別のファイルを選択",
21
+ "assetManager.dialog.fileSelected": "選択済み: {name}",
22
+ "assetManager.dialog.noFileSelected": "ファイルが選択されていません。",
23
+ "assetManager.dialog.replaceProgress": "置き換え中…",
24
+ "assetManager.dialog.newFolderTitle": "新しいフォルダー",
25
+ "assetManager.dialog.folderSaveError": "フォルダーを保存できませんでした。",
26
+ "assetManager.dialog.folderNamePlaceholder": "フォルダー名",
27
+ "assetManager.dialog.saveProgress": "保存中…",
28
+ "assetManager.dialog.deleteFolderTitle": "フォルダーを削除しますか?",
29
+ "assetManager.dialog.deleteFolderDescription": "「{name}」は削除されます。デフォルトではその内容は親フォルダーに移動するため、何も削除されません。「内容を削除」を選択すると、その {count} 個の{assets}も削除されます。",
30
+ "assetManager.dialog.removeFolder": "フォルダーを削除",
31
+ "assetManager.dialog.removeProgress": "削除中…",
32
+ "assetManager.dialog.editTitle": "アセットを編集",
33
+ "assetManager.dialog.moveTitle": "フォルダーに移動",
34
+ "assetManager.form.nameLabel": "名前",
35
+ "assetManager.form.tagsLabel": "タグ",
36
+ "assetManager.form.tagsListLabel": "現在のタグ",
37
+ "assetManager.form.removeTag": "タグ {tag} を削除",
38
+ "assetManager.form.addTagPlaceholder": "タグを追加して Enter キーを押す",
39
+ "assetManager.browser.title": "アセットブラウザー",
40
+ "assetManager.browser.subtitle": "現在メモリに登録されている検証済みアセット。",
41
+ "assetManager.browser.searchLabel": "アセットを検索",
42
+ "assetManager.browser.searchPlaceholder": "名前、タグ、または MIME で検索",
43
+ "assetManager.browser.filterLabel": "アセット種類フィルター",
44
+ "assetManager.browser.filterByKind": "{kind} アセットをフィルター",
45
+ "assetManager.browser.assetsLabel": "アセット",
46
+ "assetManager.browser.insert": "アセット {id} を挿入",
47
+ "assetManager.browser.edit": "アセット {id} を編集",
48
+ "assetManager.browser.replace": "アセット {id} を置き換え",
49
+ "assetManager.browser.delete": "アセット {id} を削除",
50
+ "assetManager.browser.unknownMime": "不明な種類",
51
+ "assetManager.browser.empty": "まだアセットがアップロードされていません。",
52
+ "assetManager.browser.emptyFiltered": "現在のフィルターに一致するアセットはありません。",
53
+ "assetManager.palette.title": "アセットを検索",
54
+ "assetManager.palette.subtitle": "名前、id、MIME タイプ、またはタグで検索します。",
55
+ "assetManager.palette.searchLabel": "アセット検索クエリ",
56
+ "assetManager.palette.searchPlaceholder": "入力して検索…",
57
+ "assetManager.palette.resultsLabel": "アセットの結果",
58
+ "assetManager.palette.noMatches": "一致するものがありません。",
59
+ "assetManager.kind.image": "画像",
60
+ "assetManager.kind.video": "動画",
61
+ "assetManager.kind.audio": "オーディオ",
62
+ "assetManager.kind.font": "フォント",
63
+ "assetManager.kind.document": "ドキュメント",
64
+ "assetManager.ui.title": "アセットマネージャー",
65
+ "assetManager.ui.subtitle": "設定済みのアダプター経由でアップロードし、検証済みのアセット参照を挿入します。",
66
+ "assetManager.upload.buttonLabel": "アセットファイルをアップロード",
67
+ "assetManager.upload.button": "アセットをアップロード",
68
+ "assetManager.upload.chooseLabel": "アップロードするファイルを選択",
69
+ "assetManager.upload.progress": "アップロード中…",
70
+ "assetManager.upload.progressLabel": "一括アップロードの進捗",
71
+ "assetManager.upload.status": "{total} 個中 {completed} 個をアップロード中",
72
+ "assetManager.upload.statusProgress": "{total} 個中 {completed} 個をアップロード中…",
73
+ "assetManager.upload.statusIdle": "受け付けたファイルは設定済みのアダプター経由でアップロードされます。",
74
+ "assetManager.upload.toFolder": "ここにファイルをドロップするかアップロード",
75
+ "assetManager.folder.root": "すべてのアセット",
76
+ "assetManager.folder.empty": "このフォルダーは空です。",
77
+ "assetManager.breadcrumb.label": "フォルダー",
78
+ "assetManager.tree.label": "フォルダー",
79
+ "assetManager.tree.dropHint": "{name} を開く — またはアセットをここにドロップして移動",
80
+ "assetManager.unsplash.disabled": "サーバープロキシ経由でアクセスキーを追加して Unsplash に接続します。",
81
+ "assetManager.unsplash.loading": "写真を読み込み中…",
82
+ "assetManager.unsplash.searchPlaceholder": "Unsplash を検索…",
83
+ "assetManager.unsplash.themesLabel": "Unsplash テーマ",
84
+ "assetManager.unsplash.rateLimited": "Unsplash のレート制限に達しました。しばらくしてからもう一度お試しください。",
85
+ "assetManager.unsplash.error": "Unsplash に接続できませんでした。再試行してください。",
86
+ "assetManager.unsplash.empty": "Unsplash を検索して写真を閲覧します。",
87
+ "assetManager.unsplash.insert": "{photographer} の写真を挿入",
88
+ "assetManager.source.library": "ライブラリ",
89
+ "assetManager.source.unsplash": "Unsplash",
90
+ "assetManager.unsplash.theme.all": "すべて",
91
+ "assetManager.unsplash.theme.nature": "自然",
92
+ "assetManager.unsplash.theme.architecture": "建築",
93
+ "assetManager.unsplash.theme.business": "ビジネス",
94
+ "assetManager.unsplash.theme.food": "食べ物",
95
+ "assetManager.unsplash.theme.technology": "テクノロジー",
96
+ "assetManager.unsplash.theme.travel": "旅行",
97
+ "assetManager.unsplash.theme.texture": "テクスチャ",
98
+ "assetManager.unsplash.theme.people": "人物"
99
+ }
@@ -0,0 +1,99 @@
1
+ {
2
+ "assetManager.action.upload": "에셋 업로드",
3
+ "assetManager.button.cancel": "취소",
4
+ "assetManager.button.delete": "삭제",
5
+ "assetManager.button.replace": "교체",
6
+ "assetManager.button.create": "만들기",
7
+ "assetManager.button.edit": "편집",
8
+ "assetManager.button.save": "저장",
9
+ "assetManager.button.loadMore": "더 보기",
10
+ "assetManager.button.deleteContents": "콘텐츠 삭제",
11
+ "assetManager.dialog.deleteTitle": "에셋을 삭제하시겠습니까?",
12
+ "assetManager.dialog.deleteDescription": "이(가) 레지스트리에서 제거됩니다. 페이지의 이 에셋에 대한 참조는 확인되지 않습니다.",
13
+ "assetManager.dialog.deleteReferenced": "이 에셋은 {count}개의 {nodes}에서 참조됩니다.",
14
+ "assetManager.dialog.deleteProgress": "삭제 중…",
15
+ "assetManager.dialog.replaceTitle": "에셋을 교체하시겠습니까?",
16
+ "assetManager.dialog.replaceDescription": "{label}을(를) 교체할 파일을 선택하세요. 기존 asset:// 참조는 새 바이트로 확인됩니다.",
17
+ "assetManager.dialog.replaceDescriptionGeneric": "이 에셋을 교체할 파일을 선택하세요.",
18
+ "assetManager.dialog.replaceFileLabel": "교체 파일",
19
+ "assetManager.dialog.chooseFile": "파일 선택",
20
+ "assetManager.dialog.chooseFileDifferent": "다른 파일 선택",
21
+ "assetManager.dialog.fileSelected": "선택됨: {name}",
22
+ "assetManager.dialog.noFileSelected": "선택된 파일이 없습니다.",
23
+ "assetManager.dialog.replaceProgress": "교체 중…",
24
+ "assetManager.dialog.newFolderTitle": "새 폴더",
25
+ "assetManager.dialog.folderSaveError": "폴더를 저장할 수 없습니다.",
26
+ "assetManager.dialog.folderNamePlaceholder": "폴더 이름",
27
+ "assetManager.dialog.saveProgress": "저장 중…",
28
+ "assetManager.dialog.deleteFolderTitle": "폴더를 삭제하시겠습니까?",
29
+ "assetManager.dialog.deleteFolderDescription": "\"{name}\"이(가) 제거됩니다. 기본적으로 그 콘텐츠는 상위 폴더로 이동하므로 아무것도 삭제되지 않습니다. \"콘텐츠 삭제\"를 선택하면 그 {count}개의 {assets}도 제거됩니다.",
30
+ "assetManager.dialog.removeFolder": "폴더 제거",
31
+ "assetManager.dialog.removeProgress": "제거 중…",
32
+ "assetManager.dialog.editTitle": "에셋 편집",
33
+ "assetManager.dialog.moveTitle": "폴더로 이동",
34
+ "assetManager.form.nameLabel": "이름",
35
+ "assetManager.form.tagsLabel": "태그",
36
+ "assetManager.form.tagsListLabel": "현재 태그",
37
+ "assetManager.form.removeTag": "태그 {tag} 제거",
38
+ "assetManager.form.addTagPlaceholder": "태그를 추가하고 Enter를 누르세요",
39
+ "assetManager.browser.title": "에셋 브라우저",
40
+ "assetManager.browser.subtitle": "현재 메모리에 등록된 검증된 에셋.",
41
+ "assetManager.browser.searchLabel": "에셋 검색",
42
+ "assetManager.browser.searchPlaceholder": "이름, 태그 또는 MIME로 검색",
43
+ "assetManager.browser.filterLabel": "에셋 종류 필터",
44
+ "assetManager.browser.filterByKind": "{kind} 에셋 필터링",
45
+ "assetManager.browser.assetsLabel": "에셋",
46
+ "assetManager.browser.insert": "에셋 {id} 삽입",
47
+ "assetManager.browser.edit": "에셋 {id} 편집",
48
+ "assetManager.browser.replace": "에셋 {id} 교체",
49
+ "assetManager.browser.delete": "에셋 {id} 삭제",
50
+ "assetManager.browser.unknownMime": "알 수 없는 유형",
51
+ "assetManager.browser.empty": "아직 업로드된 에셋이 없습니다.",
52
+ "assetManager.browser.emptyFiltered": "현재 필터와 일치하는 에셋이 없습니다.",
53
+ "assetManager.palette.title": "에셋 찾기",
54
+ "assetManager.palette.subtitle": "이름, id, MIME 유형 또는 태그로 검색하세요.",
55
+ "assetManager.palette.searchLabel": "에셋 검색 쿼리",
56
+ "assetManager.palette.searchPlaceholder": "입력하여 검색…",
57
+ "assetManager.palette.resultsLabel": "에셋 결과",
58
+ "assetManager.palette.noMatches": "일치하는 항목이 없습니다.",
59
+ "assetManager.kind.image": "이미지",
60
+ "assetManager.kind.video": "동영상",
61
+ "assetManager.kind.audio": "오디오",
62
+ "assetManager.kind.font": "글꼴",
63
+ "assetManager.kind.document": "문서",
64
+ "assetManager.ui.title": "에셋 관리자",
65
+ "assetManager.ui.subtitle": "구성된 어댑터를 통해 업로드한 다음 검증된 에셋 참조를 삽입하세요.",
66
+ "assetManager.upload.buttonLabel": "에셋 파일 업로드",
67
+ "assetManager.upload.button": "에셋 업로드",
68
+ "assetManager.upload.chooseLabel": "업로드할 파일 선택",
69
+ "assetManager.upload.progress": "업로드 중…",
70
+ "assetManager.upload.progressLabel": "일괄 업로드 진행률",
71
+ "assetManager.upload.status": "{total}개 중 {completed}개 업로드 중",
72
+ "assetManager.upload.statusProgress": "{total}개 중 {completed}개 업로드 중…",
73
+ "assetManager.upload.statusIdle": "허용된 파일은 구성된 어댑터를 통해 업로드됩니다.",
74
+ "assetManager.upload.toFolder": "여기에 파일을 끌어다 놓거나 업로드",
75
+ "assetManager.folder.root": "모든 에셋",
76
+ "assetManager.folder.empty": "이 폴더는 비어 있습니다.",
77
+ "assetManager.breadcrumb.label": "폴더",
78
+ "assetManager.tree.label": "폴더",
79
+ "assetManager.tree.dropHint": "{name} 열기 — 또는 에셋을 여기에 놓아 이동",
80
+ "assetManager.unsplash.disabled": "서버 프록시를 통해 액세스 키를 추가하여 Unsplash에 연결하세요.",
81
+ "assetManager.unsplash.loading": "사진 불러오는 중…",
82
+ "assetManager.unsplash.searchPlaceholder": "Unsplash 검색…",
83
+ "assetManager.unsplash.themesLabel": "Unsplash 테마",
84
+ "assetManager.unsplash.rateLimited": "Unsplash 속도 제한에 도달했습니다. 잠시 후 다시 시도하세요.",
85
+ "assetManager.unsplash.error": "Unsplash에 연결할 수 없습니다. 다시 시도하세요.",
86
+ "assetManager.unsplash.empty": "Unsplash를 검색하여 사진을 찾아보세요.",
87
+ "assetManager.unsplash.insert": "{photographer}의 사진 삽입",
88
+ "assetManager.source.library": "라이브러리",
89
+ "assetManager.source.unsplash": "Unsplash",
90
+ "assetManager.unsplash.theme.all": "전체",
91
+ "assetManager.unsplash.theme.nature": "자연",
92
+ "assetManager.unsplash.theme.architecture": "건축",
93
+ "assetManager.unsplash.theme.business": "비즈니스",
94
+ "assetManager.unsplash.theme.food": "음식",
95
+ "assetManager.unsplash.theme.technology": "기술",
96
+ "assetManager.unsplash.theme.travel": "여행",
97
+ "assetManager.unsplash.theme.texture": "텍스처",
98
+ "assetManager.unsplash.theme.people": "인물"
99
+ }