@liiift-studio/sanity-font-manager 2.4.0 → 2.5.1

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 (36) hide show
  1. package/dist/UploadModal-ADNRGQUI.mjs +6 -0
  2. package/dist/UploadModal-WPK2CXLR.js +6 -0
  3. package/dist/chunk-JCDZ7SWZ.js +7711 -0
  4. package/dist/chunk-TMDE4A54.mjs +7711 -0
  5. package/dist/index.js +666 -1647
  6. package/dist/index.mjs +319 -1209
  7. package/package.json +5 -5
  8. package/src/components/BatchUploadFonts.jsx +57 -44
  9. package/src/components/BulkActions.jsx +99 -0
  10. package/src/components/ExistingDocumentResolver.jsx +152 -0
  11. package/src/components/FontReviewCard.jsx +455 -0
  12. package/src/components/SingleUploaderTool.jsx +3 -4
  13. package/src/components/UploadModal.jsx +304 -0
  14. package/src/components/UploadScriptsComponent.jsx +23 -21
  15. package/src/components/UploadStep1Settings.jsx +272 -0
  16. package/src/components/UploadStep2Review.jsx +474 -0
  17. package/src/components/UploadStep3Execute.jsx +234 -0
  18. package/src/components/UploadStep3bInstances.jsx +396 -0
  19. package/src/components/UploadSummary.jsx +196 -0
  20. package/src/index.js +46 -0
  21. package/src/utils/buildUploadPlan.js +326 -0
  22. package/src/utils/executeUploadPlan.js +430 -0
  23. package/src/utils/executionReducer.js +56 -0
  24. package/src/utils/fontHelpers.js +267 -0
  25. package/src/utils/generateCssFile.js +79 -77
  26. package/src/utils/generateFontData.js +47 -94
  27. package/src/utils/getEmptyFontKit.js +19 -17
  28. package/src/utils/parseFont.js +55 -0
  29. package/src/utils/parseVariableFontInstances.js +237 -147
  30. package/src/utils/planReducer.js +517 -0
  31. package/src/utils/planTypes.js +183 -0
  32. package/src/utils/processFontFiles.js +121 -78
  33. package/src/utils/regenerateFontData.js +2 -2
  34. package/src/utils/resolveExistingFont.js +87 -0
  35. package/src/utils/updateTypefaceDocument.js +15 -2
  36. package/src/utils/uploadFontFiles.js +405 -405
package/dist/index.mjs CHANGED
@@ -1,6 +1,70 @@
1
+ import {
2
+ BulkActions,
3
+ EXECUTION_STATUS,
4
+ ExistingDocumentResolver,
5
+ FONT_STATUS,
6
+ FontReviewCard_default,
7
+ PLAN_PHASE,
8
+ PLAN_VERSION,
9
+ PriceInput_default,
10
+ RECOMMENDATION,
11
+ UploadModal,
12
+ UploadStep1Settings,
13
+ UploadStep2Review,
14
+ UploadStep3Execute,
15
+ UploadStep3bInstances,
16
+ UploadSummary,
17
+ addItalicToFontTitle,
18
+ buildUploadPlan,
19
+ createEmptyPlan,
20
+ createFontDecisions,
21
+ createFontObject,
22
+ createInitialExecutionState,
23
+ determineWeight,
24
+ escapeCssFontName,
25
+ executeUploadPlan,
26
+ executionReducer,
27
+ expandAbbreviations,
28
+ extractFontMetadata,
29
+ extractWeightFromFullName,
30
+ extractWeightName,
31
+ formatFontTitle,
32
+ generateCssFile,
33
+ generateFontData,
34
+ generateStyleKeywords,
35
+ getAllFeatureTags,
36
+ getCharacterSet,
37
+ getFamilyClass,
38
+ getFontMetadata,
39
+ getFontMetrics,
40
+ getFsSelection,
41
+ getGlyphCount,
42
+ getItalicAngle,
43
+ getMacStyle,
44
+ getNameString,
45
+ getNamedInstances,
46
+ getVariationAxes,
47
+ getWeightClass,
48
+ logFontInfo,
49
+ parseFont,
50
+ parseVariableFontInstances,
51
+ parseVariableFontInstances_default,
52
+ planReducer,
53
+ processFontFiles,
54
+ processItalicKeywords,
55
+ processSubfamilyName,
56
+ readFontFile,
57
+ removeWeightNames,
58
+ resolveExistingFont,
59
+ reverseSpellingLookup,
60
+ sanitizeForSanityId,
61
+ sortFontObjects,
62
+ updateTypefaceDocument
63
+ } from "./chunk-TMDE4A54.mjs";
64
+
1
65
  // src/components/BatchUploadFonts.jsx
2
- import React4, { useCallback, useState as useState2, useMemo as useMemo2, useRef, useEffect } from "react";
3
- import { Card, Box as Box2, Flex as Flex3, Grid, Text as Text4, Label, Switch, Button as Button2, Spinner, Tooltip, Stack as Stack2 } from "@sanity/ui";
66
+ import React3, { useCallback, useState as useState2, useMemo as useMemo2, useRef, useEffect, lazy, Suspense } from "react";
67
+ import { Card, Box as Box2, Flex as Flex2, Grid, Text as Text3, Label, Switch, Button as Button2, Spinner, Tooltip, Stack as Stack2 } from "@sanity/ui";
4
68
  import { ControlsIcon, InfoOutlineIcon, TrashIcon, UploadIcon, WarningOutlineIcon } from "@sanity/icons";
5
69
  import { useFormValue as useFormValue2 } from "sanity";
6
70
 
@@ -12,908 +76,8 @@ function useSanityClient() {
12
76
  return useMemo(() => client, [client]);
13
77
  }
14
78
 
15
- // src/utils/processFontFiles.js
16
- import * as fontkit from "fontkit";
17
- import { nanoid } from "nanoid";
18
-
19
- // src/utils/generateKeywords.js
20
- var coreWeights = ["Hairline", "ExtraThin", "Thin", "Mager", "Maigre", "ExtraLight", "Light", "Chiaro", "Lite", "Leicht", "Demi", "Book", "Buch", "Regular", "Normal", "Medium", "Stark", "Thick", "Kr\xE4ftig", "Viertelfett", "Halbfett", "Dreiviertelfett", "Dark", "Bold", "Neretto", "Gras", "Fett", "Extrafett", "Black", "Nero", "Heavy", "Nerissimo", "Ultra", "Fat", "Poster"];
21
- var modifiers = ["Demi", "Semi", "Extra", "Ultra", "Super", "Plus"];
22
- var coreItalics = ["Italic", "Slant", "Oblique", "Cursive", "Rotalic", "Reverse", "Crab Claw", "Crabclaw", "South Paw", "Southpaw", "Backwards", "Backslant", "Backslanted", "Back Slant"];
23
- var alternativeSpelling = {
24
- Backslant: ["Bsl"],
25
- Backwards: ["Bck"],
26
- Black: ["Blak", "Blk"],
27
- Bold: ["Bd", "Bld"],
28
- // B omitted — too ambiguous
29
- Condensed: ["Cond", "Cnd"],
30
- Crabclaw: ["Crab", "Claw"],
31
- Cursive: ["Cur"],
32
- Dark: ["Drk"],
33
- Expanded: ["Exp"],
34
- Extra: ["Xt", "Xtra", "Xtr", "X"],
35
- // X omitted as standalone — too ambiguous
36
- ExtraBlack: ["Xblk", "XBlk", "Xblck", "XBlck"],
37
- ExtraBold: ["Xbd", "XBd", "Xbld", "XBld", "Xbold", "XBold", "ExBold", "Exbold", "Exbd", "ExBd", "Exbld", "ExBld"],
38
- ExtraCondensed: ["XCond", "Xcnd"],
39
- ExtraExpanded: ["XExp"],
40
- ExtraLight: ["Xlight", "XLight", "Xlt", "XLt", "Xlgt", "XLgt", "Xl", "XL", "Xlght", "XLght"],
41
- ExtraThin: ["Xthin", "Xthn", "Xth", "XThin", "XThn", "XTh", "XT"],
42
- Extended: ["Ext"],
43
- Hairline: ["Hl", "Hln", "Hlnn", "Hlnne", "Hlnnne"],
44
- Italic: ["Ital", "It"],
45
- Light: ["Lt", "Lght"],
46
- Medium: ["Med", "Md", "md", "med"],
47
- Oblique: ["Obl"],
48
- Plus: ["Pls"],
49
- Regular: ["Reg", "Rg"],
50
- Reverse: ["Rev"],
51
- Rotalic: ["Rot"],
52
- SemiBold: ["SmBd", "Sb", "Sbd", "Sbld", "Sbold", "Semibd", "SemiBd", "Semibld", "SemiBld", "semiBd", "semiBld"],
53
- Slant: ["Sl"],
54
- Southpaw: ["South", "Paw"],
55
- Super: ["Supr"],
56
- Thin: ["Thn"],
57
- Ultra: ["Ult", "Ultre", "Ul", "Ulta"],
58
- XX: ["XXt", "XXtra", "XXtr", "XX"],
59
- XXBlack: ["XXblk", "XXBlk", "XXblck", "XXBlck"],
60
- XXLight: ["XXlight", "XXLight", "XXlt", "XXLt", "XXlgt", "XXLgt", "XXl", "XXL", "XXlght", "XXLght"],
61
- XXX: ["XXXt", "XXXtra", "XXXtr", "XXX"],
62
- XXXLight: ["XXXlight", "XXXLight", "XXXlt", "XXXLt", "XXXlgt", "XXXLgt", "XXXl", "XXXL", "XXXlght", "XXXLght"]
63
- };
64
- function reverseSpellingLookup(str) {
65
- let exactMatch = "";
66
- Object.keys(alternativeSpelling).forEach(function(key) {
67
- alternativeSpelling[key].forEach(function(alternative) {
68
- if (str === alternative) {
69
- exactMatch = key;
70
- }
71
- });
72
- });
73
- if (exactMatch) return exactMatch;
74
- let result = "";
75
- let longestMatch = 0;
76
- Object.keys(alternativeSpelling).forEach(function(key) {
77
- alternativeSpelling[key].forEach(function(alternative) {
78
- const regex = new RegExp(`\\b${alternative}\\b`);
79
- if (regex.test(str) && alternative.length > longestMatch) {
80
- result = key;
81
- longestMatch = alternative.length;
82
- }
83
- });
84
- });
85
- return result;
86
- }
87
- function expandAbbreviations(str) {
88
- if (!str) return str;
89
- return str.split(" ").map((word) => {
90
- const expanded = reverseSpellingLookup(word);
91
- return expanded || word;
92
- }).join(" ");
93
- }
94
- function removeWeightNames(str) {
95
- if (!str) return str;
96
- return str.split(" ").map((word) => {
97
- coreWeights.forEach((weight) => {
98
- if (word === weight) word = "";
99
- modifiers.forEach((modifier) => {
100
- if (word === modifier || modifier + weight === word) word = "";
101
- });
102
- });
103
- const expanded = reverseSpellingLookup(word);
104
- if (expanded) return "";
105
- return word;
106
- }).join(" ").trim();
107
- }
108
- function generateStyleKeywords() {
109
- let weightKeywordList = [];
110
- let italicKeywordList = [];
111
- weightKeywordList = [...coreWeights];
112
- modifiers.forEach((modifier) => {
113
- coreWeights.forEach((weight) => {
114
- weightKeywordList.push(modifier + weight);
115
- });
116
- });
117
- weightKeywordList = [...weightKeywordList, ...modifiers];
118
- italicKeywordList = [...coreItalics];
119
- weightKeywordList = weightKeywordList.map(function(el) {
120
- var newEls = [];
121
- Object.keys(alternativeSpelling).forEach(function(key) {
122
- if (el.indexOf(key) !== -1) {
123
- alternativeSpelling[key].forEach(function(alternative) {
124
- let newSpelling = el.replace(key, alternative);
125
- newEls.push(newSpelling);
126
- Object.keys(alternativeSpelling).forEach(function(key2) {
127
- if (newSpelling.indexOf(key2) !== -1) {
128
- alternativeSpelling[key2].forEach(function(alternative2) {
129
- let newSpelling2 = newSpelling.replace(key2, alternative2);
130
- newEls.push(newSpelling2);
131
- Object.keys(alternativeSpelling).forEach(function(key3) {
132
- if (newSpelling2.indexOf(key3) !== -1) {
133
- alternativeSpelling[key3].forEach(function(alternative3) {
134
- newEls.push(newSpelling2.replace(key3, alternative3));
135
- });
136
- }
137
- });
138
- });
139
- }
140
- });
141
- });
142
- }
143
- });
144
- newEls.push(el);
145
- return newEls;
146
- }).reduce(function(a, b) {
147
- return a.concat(b);
148
- });
149
- italicKeywordList = italicKeywordList.map(function(el) {
150
- var newEls = [];
151
- Object.keys(alternativeSpelling).forEach(function(key) {
152
- if (el.indexOf(key) !== -1) {
153
- alternativeSpelling[key].forEach(function(alternative) {
154
- newEls.push(el.replace(key, alternative));
155
- });
156
- }
157
- });
158
- newEls.push(el);
159
- return newEls;
160
- }).reduce(function(a, b) {
161
- return a.concat(b);
162
- });
163
- weightKeywordList = weightKeywordList.sort((a, b) => b.length - a.length);
164
- italicKeywordList = italicKeywordList.sort((a, b) => b.length - a.length);
165
- weightKeywordList = weightKeywordList.filter((item, pos) => weightKeywordList.indexOf(item) === pos);
166
- italicKeywordList = italicKeywordList.filter((item, pos) => italicKeywordList.indexOf(item) === pos);
167
- return { weightKeywordList, italicKeywordList };
168
- }
169
-
170
- // src/utils/sanitizeForSanityId.js
171
- import slugify from "slugify";
172
- function sanitizeForSanityId(str) {
173
- if (!str || typeof str !== "string") {
174
- return "font-" + Date.now();
175
- }
176
- let sanitized = str.toLowerCase().trim();
177
- sanitized = sanitized.replace(/\+/g, "plus");
178
- sanitized = sanitized.replace(/&/g, "and");
179
- sanitized = sanitized.replace(/@/g, "at");
180
- sanitized = slugify(sanitized, {
181
- replacement: "-",
182
- remove: /[^\w\s-]/g,
183
- lower: true,
184
- strict: true,
185
- locale: "en",
186
- trim: true
187
- });
188
- sanitized = sanitized.replace(/[^a-z0-9\-_]/g, "-");
189
- sanitized = sanitized.replace(/-+/g, "-");
190
- sanitized = sanitized.replace(/^[-_]+|[-_]+$/g, "");
191
- if (sanitized && !/^[a-z_]/.test(sanitized)) {
192
- sanitized = "font_" + sanitized;
193
- }
194
- if (!sanitized) {
195
- sanitized = "font_" + Date.now();
196
- }
197
- if (sanitized.length > 128) {
198
- const hash = Math.random().toString(36).substring(2, 8);
199
- sanitized = sanitized.substring(0, 120) + "_" + hash;
200
- }
201
- if (!/^[a-z_][a-z0-9\-_]*$/.test(sanitized)) {
202
- console.warn(`ID sanitization produced invalid result: "${sanitized}", using fallback`);
203
- sanitized = "font_" + Date.now();
204
- }
205
- return sanitized;
206
- }
207
-
208
- // src/utils/processFontFiles.js
209
- var readFontFile = (file) => {
210
- return new Promise((resolve, reject) => {
211
- const reader = new FileReader();
212
- reader.onload = (event) => {
213
- resolve(new Uint8Array(event.target.result));
214
- };
215
- reader.onerror = (error) => {
216
- reject(error);
217
- };
218
- reader.readAsArrayBuffer(file);
219
- });
220
- };
221
- var processFontFiles = async (files, title, weightKeywordList, italicKeywordList, setStatus, preserveShortenedNames = false, preserveFileNames = false) => {
222
- let failedFiles = [];
223
- let subfamilies = {};
224
- let fontsObjects = {};
225
- let newPreferredStyle = { weight: -100, style: "Italic", _ref: "" };
226
- for (let i = 0; i < files.length; i++) {
227
- const file = files[i];
228
- const fontBuffer = await readFontFile(file);
229
- const font = fontkit.create(fontBuffer);
230
- console.log("File name: ", file.name);
231
- if (file.name.endsWith(".woff2") || file.name.endsWith(".woff")) {
232
- await handleWebfontMetadata(file, font, files);
233
- }
234
- let { weightName, subfamilyName, fontTitle, style, italicKW, variableFont } = extractFontMetadata(
235
- font,
236
- title,
237
- weightKeywordList,
238
- italicKeywordList,
239
- preserveShortenedNames
240
- );
241
- let id;
242
- let originalFilename = null;
243
- if (preserveFileNames) {
244
- originalFilename = file.name.replace(/\.(ttf|otf|woff2?|eot|svg)$/i, "");
245
- const normalizedName = originalFilename.replace(/-/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").trim();
246
- fontTitle = normalizedName;
247
- id = sanitizeForSanityId(normalizedName);
248
- } else {
249
- id = sanitizeForSanityId(fontTitle);
250
- }
251
- logFontInfo(id, fontTitle, font, file.name, subfamilyName, style, weightName, variableFont, italicKW);
252
- subfamilies[id] = subfamilyName;
253
- if (fontsObjects[id]) {
254
- fontsObjects[id].files = [...fontsObjects[id].files, file];
255
- if (preserveFileNames && originalFilename) {
256
- fontsObjects[id].originalFilename = originalFilename;
257
- }
258
- } else {
259
- fontsObjects[id] = createFontObject(
260
- id,
261
- fontTitle,
262
- title,
263
- font,
264
- variableFont,
265
- weightName,
266
- subfamilyName,
267
- file,
268
- preserveFileNames ? originalFilename : null
269
- );
270
- }
271
- }
272
- fontsObjects = sortFontObjects(fontsObjects);
273
- const uniqueSubfamilies = [...new Set(Object.values(subfamilies))];
274
- console.log("Subfamilies:", subfamilies);
275
- console.log("Unique subfamilies:", uniqueSubfamilies, uniqueSubfamilies.length);
276
- console.log("Font objects:", fontsObjects);
277
- return { fontsObjects, subfamilies, uniqueSubfamilies, newPreferredStyle, failedFiles };
278
- };
279
- var handleWebfontMetadata = async (file, font, files) => {
280
- var _a, _b, _c, _d, _e, _f, _g;
281
- if (!((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName) || ((_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fullName) === "" || !/^[A-Z0-9]+$/.test((_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fullName)) {
282
- const ttfFile = files.find((f) => f.name === file.name.replace(".woff2", ".ttf").replace(".woff", ".ttf"));
283
- if (ttfFile) {
284
- const ttfFileBuffer = await readFontFile(ttfFile);
285
- const ttfFileData = fontkit.create(ttfFileBuffer);
286
- if (ttfFileData) font.name.records = (_g = ttfFileData == null ? void 0 : ttfFileData.name) == null ? void 0 : _g.records;
287
- }
288
- }
289
- };
290
- var extractFontMetadata = (font, title, weightKeywordList, italicKeywordList, preserveShortenedNames = false) => {
291
- var _a, _b, _c, _d, _e, _f;
292
- let weightName = extractWeightName(font, italicKeywordList);
293
- if (!preserveShortenedNames) {
294
- weightName = expandAbbreviations(weightName);
295
- }
296
- if ((weightName === "" || weightName.toLowerCase() === "roman") && ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName)) {
297
- weightName = extractWeightFromFullName(font, title);
298
- if (!preserveShortenedNames) {
299
- weightName = expandAbbreviations(weightName);
300
- }
301
- }
302
- const variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0;
303
- let subfamilyName = ((_f = (_e = (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fullName) == null ? void 0 : _e.en) == null ? void 0 : _f.replace(title.trim(), "").trim()) || font.subfamilyName.trim().replace(title.trim(), "").trim();
304
- if (!preserveShortenedNames) {
305
- subfamilyName = expandAbbreviations(subfamilyName);
306
- }
307
- let fontTitle = font == null ? void 0 : font.fullName.trim();
308
- let style = (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular";
309
- const italicKW = processItalicKeywords(font, fontTitle, italicKeywordList);
310
- subfamilyName = processSubfamilyName(subfamilyName, weightKeywordList, italicKW, preserveShortenedNames);
311
- fontTitle = formatFontTitle(fontTitle, preserveShortenedNames);
312
- subfamilyName = subfamilyName === "" ? "Regular" : subfamilyName.replace(/\s+/g, " ").trim();
313
- if (subfamilyName !== "") {
314
- weightName = weightName.replace(`${subfamilyName} `, "").replace(` ${subfamilyName}`, "").trim();
315
- }
316
- if (variableFont) {
317
- if (!fontTitle.toLowerCase().includes("vf")) {
318
- fontTitle = fontTitle + " VF";
319
- }
320
- subfamilyName = "";
321
- }
322
- if (!(variableFont && fontTitle.toLowerCase().includes("italic"))) {
323
- fontTitle = addItalicToFontTitle(font, fontTitle, italicKW, style, preserveShortenedNames);
324
- }
325
- return { weightName, subfamilyName, fontTitle, style, italicKW, variableFont };
326
- };
327
- var extractWeightName = (font, italicKW) => {
328
- var _a, _b, _c, _d;
329
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) || ((_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fontSubfamily);
330
- if (typeof weightName === "object") {
331
- weightName = (weightName == null ? void 0 : weightName.en) || (weightName.constructor === Object ? weightName[Object.keys(weightName)[0]] : null);
332
- }
333
- if ((font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0) {
334
- return "Variable";
335
- }
336
- if (italicKW) {
337
- italicKW.forEach((keyword) => {
338
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
339
- if (kwRegex.test(weightName)) {
340
- weightName = weightName.replace(kwRegex, "").trim();
341
- }
342
- });
343
- }
344
- return weightName == null ? void 0 : weightName.toString().replace("Italic", "").replace("It", "").replace("Slanted", "").replace("Slant", "").replace("Backslant", "").trim();
345
- };
346
- var extractWeightFromFullName = (font, title) => {
347
- var _a, _b;
348
- let weightName = (_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName;
349
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : (weightName == null ? void 0 : weightName.constructor) === Object ? weightName[Object.keys(weightName)[0]] : weightName;
350
- weightName = weightName == null ? void 0 : weightName.replace(title + " ", "").replace(title, "").trim();
351
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").replace("Slanted", "").replace("Slant", "").trim();
352
- return weightName;
353
- };
354
- var processSubfamilyName = (subfamilyName, weightKeywordList, italicKeywordList, preserveShortenedNames = false) => {
355
- weightKeywordList.forEach((keyword) => {
356
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
357
- if (kwRegex.test(subfamilyName)) {
358
- subfamilyName = subfamilyName.replace(kwRegex, "").trim();
359
- }
360
- subfamilyName = removeWeightNames(subfamilyName) || subfamilyName;
361
- if (!preserveShortenedNames) {
362
- subfamilyName = expandAbbreviations(subfamilyName);
363
- }
364
- });
365
- italicKeywordList.forEach((keyword) => {
366
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
367
- if (kwRegex.test(subfamilyName)) {
368
- subfamilyName = subfamilyName.replace(kwRegex, "").trim();
369
- }
370
- });
371
- return subfamilyName;
372
- };
373
- var processItalicKeywords = (font, fontTitle, italicKeywordList) => {
374
- let italicKW = [];
375
- italicKeywordList.forEach((keyword) => {
376
- const kw = keyword.trim();
377
- const kwRegex = new RegExp(`\\b${kw}\\b`, "i");
378
- if (kwRegex.test(fontTitle)) {
379
- fontTitle = fontTitle.replace(kwRegex, "").trim();
380
- italicKW.push(kw);
381
- }
382
- if ((font == null ? void 0 : font.fullName) && typeof font.fullName === "string" && font.fullName.toLowerCase().includes(kw.toLowerCase())) {
383
- if (!italicKW.includes(kw)) italicKW.push(kw);
384
- }
385
- });
386
- return italicKW;
387
- };
388
- var formatFontTitle = (fontTitle, preserveShortenedNames = false) => {
389
- const hasItalic = fontTitle.toLowerCase().includes("italic");
390
- fontTitle = fontTitle.replace(/-/g, " ");
391
- return fontTitle.replace(/\s+/g, " ").trim().split(" ").map((word) => {
392
- if (hasItalic && word.toLowerCase() === "italic") return "Italic";
393
- let fullWord = word;
394
- if (!preserveShortenedNames) {
395
- fullWord = reverseSpellingLookup(word) || word;
396
- }
397
- return fullWord[0].toUpperCase() + fullWord.slice(1);
398
- }).join(" ");
399
- };
400
- var addItalicToFontTitle = (font, fontTitle, italicKW, style, preserveShortenedNames = false) => {
401
- const hasItalicAngle = (font == null ? void 0 : font.italicAngle) !== 0;
402
- const hasItalicInName = font == null ? void 0 : font.fullName.toLowerCase().includes("italic");
403
- if (italicKW.length > 0 || hasItalicAngle || hasItalicInName) {
404
- italicKW = [...new Set(italicKW)];
405
- if (italicKW.length === 0 && (hasItalicAngle || hasItalicInName)) {
406
- italicKW = ["Italic"];
407
- }
408
- if (!preserveShortenedNames) {
409
- italicKW = italicKW.map((item) => reverseSpellingLookup(item) || item);
410
- }
411
- italicKW = [...new Set(italicKW)];
412
- if (italicKW.length > 1 && italicKW.includes("Italic")) {
413
- italicKW = ["Italic"];
414
- }
415
- const fontTitleLower = fontTitle.toLowerCase();
416
- italicKW = italicKW.filter((keyword) => {
417
- const keywordLower = keyword.toLowerCase();
418
- const kwRegex = new RegExp(`\\b${keywordLower}\\b`);
419
- const isSubstring = fontTitleLower.split(" ").some(
420
- (word) => word.includes(keywordLower) || keywordLower.includes(word)
421
- );
422
- return !kwRegex.test(fontTitleLower) && !isSubstring;
423
- });
424
- if (italicKW.length > 0) {
425
- fontTitle = fontTitle.trim() + " " + italicKW.join(" ");
426
- }
427
- }
428
- return fontTitle;
429
- };
430
- var createFontObject = (id, fontTitle, title, font, variableFont, weightName, subfamilyName, file, originalFilename = null) => {
431
- const fontObject = {
432
- _key: nanoid(),
433
- _id: id,
434
- title: fontTitle,
435
- slug: { _type: "slug", current: id },
436
- typefaceName: title,
437
- style: (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular",
438
- variableFont,
439
- weightName,
440
- subfamily: subfamilyName,
441
- normalWeight: true,
442
- weight: Number(determineWeight(font, weightName)),
443
- fileInput: {},
444
- files: [file],
445
- fontKit: font
446
- };
447
- if (originalFilename) {
448
- fontObject.originalFilename = originalFilename;
449
- }
450
- return fontObject;
451
- };
452
- var determineWeight = (font, weightName) => {
453
- var _a;
454
- if ((_a = font["OS/2"]) == null ? void 0 : _a.usWeightClass) {
455
- return Number(font["OS/2"].usWeightClass);
456
- }
457
- const wn = (weightName == null ? void 0 : weightName.toLowerCase()) || "";
458
- if (/hairline|extra thin|extrathin/.test(wn)) return 100;
459
- if (/thin|extra light|extralight/.test(wn)) return 200;
460
- if (/light|book/.test(wn)) return 300;
461
- if (/regular|normal/.test(wn)) return 400;
462
- if (/medium/.test(wn)) return 500;
463
- if (/semi bold|semibold/.test(wn)) return 600;
464
- if (/extra bold|extrabold/.test(wn)) return 800;
465
- if (/bold/.test(wn)) return 700;
466
- if (/black|ultra/.test(wn)) return 900;
467
- return 400;
468
- };
469
- var sortFontObjects = (fontsObjects) => {
470
- return Object.fromEntries(
471
- Object.entries(fontsObjects).sort((a, b) => {
472
- const weightA = Number(a[1].weight);
473
- const weightB = Number(b[1].weight);
474
- if (weightA === weightB) {
475
- if (a[1].style === "Regular" && b[1].style === "Italic") return -1;
476
- if (a[1].style === "Italic" && b[1].style === "Regular") return 1;
477
- return 0;
478
- }
479
- return weightA - weightB;
480
- })
481
- );
482
- };
483
- var logFontInfo = (id, fontTitle, font, fileName, subfamilyName, style, weightName, variableFont, italicKW) => {
484
- console.log("=== Font Info ====");
485
- console.log("Font id: ", id);
486
- console.log("Font title: ", fontTitle);
487
- console.log("Fontkit fullName: ", font.fullName);
488
- console.log("Fontkit family name: ", font.familyName);
489
- console.log("File name: ", fileName);
490
- console.log("Subfamily: ", subfamilyName);
491
- console.log("Style: ", style);
492
- console.log("Weight: ", weightName);
493
- console.log("Variable: ", variableFont);
494
- console.log("italicKW: ", italicKW);
495
- console.log("Font italic angle: ", (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular");
496
- console.log("=======");
497
- };
498
-
499
- // src/utils/uploadFontFiles.js
500
- import { nanoid as nanoid3 } from "nanoid";
501
-
502
- // src/utils/generateCssFile.js
503
- import base64 from "base-64";
504
- import { Buffer } from "buffer";
505
- import * as fontkit2 from "fontkit";
506
- function _arrayBufferToBase64(buffer) {
507
- var binary = "";
508
- var bytes = new Uint8Array(buffer);
509
- var len = bytes.byteLength;
510
- for (var i = 0; i < len; i++) {
511
- binary += String.fromCharCode(bytes[i]);
512
- }
513
- return base64.encode(binary);
514
- }
515
- function buildVFDescriptors(font) {
516
- const cssAxes = {};
517
- const skipped = [];
518
- try {
519
- const va = font.variationAxes;
520
- if (!va) return { descriptors: "", skipped: [] };
521
- for (const [tag, axis] of Object.entries(va)) {
522
- const lo = Math.min(axis.min, axis.max);
523
- const hi = Math.max(axis.min, axis.max);
524
- if (lo === hi) {
525
- skipped.push(tag);
526
- continue;
527
- }
528
- if (tag === "wght") {
529
- cssAxes["font-weight"] = `${lo} ${hi}`;
530
- } else if (tag === "wdth") {
531
- cssAxes["font-stretch"] = `${lo}% ${hi}%`;
532
- } else if (tag === "slnt") {
533
- cssAxes["font-style"] = `oblique ${lo}deg ${hi}deg`;
534
- } else if (tag === "ital" && !cssAxes["font-style"]) {
535
- if (hi > 0) cssAxes["font-style"] = "italic";
536
- else skipped.push(tag);
537
- } else {
538
- skipped.push(tag);
539
- }
540
- }
541
- } catch (_) {
542
- }
543
- const descriptors = Object.entries(cssAxes).map(([k, v]) => `${k}:${v}`).join(";") + (Object.keys(cssAxes).length ? ";" : "");
544
- return { descriptors, skipped };
545
- }
546
- var FALLBACK_STACKS = {
547
- "sans-serif": "local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans')",
548
- "serif": "local('Georgia'), local('Times New Roman'), local('Times')",
549
- "monospace": "local('Courier New'), local('Courier'), local('Menlo'), local('Monaco')",
550
- // Display and script fonts have no universally suitable system fallback; default to sans-serif
551
- "default": "local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans')"
552
- };
553
- var FAMILY_CLASS_MAP = {
554
- 1: "serif",
555
- 2: "serif",
556
- 3: "serif",
557
- 4: "serif",
558
- 5: "serif",
559
- 7: "serif",
560
- 8: "sans-serif"
561
- };
562
- var SERIF_NAMES = /jubilat|corundum|dapifer|birra|daith/i;
563
- var SANS_NAMES = /halyard|gamay|omnes|kit/i;
564
- function detectFontCategory(font, fontName) {
565
- var _a;
566
- if (fontName && SERIF_NAMES.test(fontName)) return "serif";
567
- if (fontName && SANS_NAMES.test(fontName)) return "sans-serif";
568
- try {
569
- const familyClass = ((_a = font["OS/2"]) == null ? void 0 : _a.sFamilyClass) ?? 0;
570
- const highByte = familyClass >> 8 & 255;
571
- return FAMILY_CLASS_MAP[highByte] ?? "default";
572
- } catch {
573
- return "default";
574
- }
575
- }
576
- function calcFallbackData(arrayBuffer, fontName) {
577
- try {
578
- let font = fontkit2.create(Buffer.from(arrayBuffer));
579
- let upm = font.unitsPerEm;
580
- let category = detectFontCategory(font, fontName);
581
- return {
582
- fallbackSrc: FALLBACK_STACKS[category],
583
- ascentOverride: `${(font.ascent / upm * 100).toFixed(2)}%`,
584
- descentOverride: `${(Math.abs(font.descent) / upm * 100).toFixed(2)}%`,
585
- lineGapOverride: `${(font.lineGap / upm * 100).toFixed(2)}%`
586
- };
587
- } catch (err) {
588
- console.error("Failed to extract fallback font data:", err);
589
- return {
590
- fallbackSrc: FALLBACK_STACKS["default"],
591
- ascentOverride: "100%",
592
- descentOverride: "0%",
593
- lineGapOverride: "0%"
594
- };
595
- }
596
- }
597
- async function generateCssFile({
598
- woff2File,
599
- fileInput,
600
- language = null,
601
- fileName,
602
- fontName,
603
- variableFont,
604
- weight,
605
- style = "Normal",
606
- client
607
- }) {
608
- try {
609
- let arrayBuffer = await woff2File.arrayBuffer();
610
- let b64 = _arrayBufferToBase64(arrayBuffer);
611
- let fontkitFont = fontkit2.create(Buffer.from(arrayBuffer));
612
- let { fallbackSrc, ascentOverride, descentOverride, lineGapOverride } = calcFallbackData(arrayBuffer, fontName);
613
- let cssString;
614
- if (variableFont) {
615
- let { descriptors, skipped } = buildVFDescriptors(fontkitFont);
616
- let skipComment = skipped.length ? `/* axes present but have no @font-face descriptor: ${skipped.join(", ")}` + (skipped.includes("opsz") ? " \u2014 add font-optical-sizing:auto to your element CSS" : "") + " */" : "";
617
- cssString = `${skipComment}@font-face{font-family:'${fontName}';src:url(data:application/font-woff2;charset=utf-8;base64,${b64})format('woff2-variations');${descriptors}font-display:swap;}`;
618
- } else {
619
- let fontStyle = style === "Italic" ? "italic" : "normal";
620
- cssString = `@font-face{font-family:'${fontName}';src:url(data:application/font-woff2;charset=utf-8;base64,${b64})format('woff2');font-weight:${weight};font-style:${fontStyle};font-display:swap;}`;
621
- }
622
- let fallbackCssString = `@font-face{font-family:'${fontName} Fallback';src:${fallbackSrc};ascent-override:${ascentOverride};descent-override:${descentOverride};line-gap-override:${lineGapOverride};}`;
623
- let uploadBuffer = Buffer.from(cssString + fallbackCssString, "utf-8");
624
- let doc = await client.assets.upload("file", uploadBuffer, { filename: fileName + ".css" });
625
- let newFileInput = language == null ? {
626
- ...fileInput,
627
- css: {
628
- _type: "file",
629
- asset: {
630
- _type: "reference",
631
- _ref: doc._id
632
- }
633
- }
634
- } : {
635
- ...fileInput,
636
- [language]: {
637
- ...fileInput[language],
638
- css: {
639
- _type: "file",
640
- asset: {
641
- _type: "reference",
642
- _ref: doc._id
643
- }
644
- }
645
- }
646
- };
647
- return newFileInput;
648
- } catch (err) {
649
- console.error(err);
650
- throw err;
651
- }
652
- }
653
-
654
- // src/utils/generateFontData.js
655
- import { Buffer as Buffer2 } from "buffer";
656
- import * as fontkit3 from "fontkit";
657
- async function generateFontData({ fileInput, url, fontKit, fontId, client, commit = true }) {
658
- var _a;
659
- if (fontId.startsWith("drafts.")) {
660
- fontId = fontId.replace("drafts.", "");
661
- }
662
- console.log("generate-font-data ", fontId, commit);
663
- let srcUrl;
664
- if (!url || url == null) {
665
- srcUrl = await client.fetch(`*[_id == $id]{url}`, { id: fileInput.ttf.asset._ref });
666
- console.log("src url ", srcUrl);
667
- srcUrl = srcUrl[0].url;
668
- } else {
669
- srcUrl = url;
670
- }
671
- let font = fontKit;
672
- if (!fontKit || fontKit == null) {
673
- let buffer = await fetch(srcUrl);
674
- buffer = await buffer.arrayBuffer();
675
- buffer = Buffer2.from(buffer);
676
- font = fontkit3.create(buffer);
677
- }
678
- let variableAxes;
679
- try {
680
- variableAxes = font.variationAxes;
681
- } catch (err) {
682
- console.error("err: ", err);
683
- }
684
- let variableInstances;
685
- try {
686
- variableInstances = font.namedVariations;
687
- } catch (e) {
688
- console.log("variable instances 2 error : ", e.message);
689
- let fvar = (_a = font == null ? void 0 : font.fvar) == null ? void 0 : _a.instance;
690
- fvar == null ? void 0 : fvar.forEach((fv) => {
691
- var _a2, _b, _c, _d, _e, _f;
692
- if ((fv == null ? void 0 : fv.nameID) === 2) fv.name = (_c = (_b = (_a2 = font == null ? void 0 : font._tables) == null ? void 0 : _a2.name) == null ? void 0 : _b.records) == null ? void 0 : _c.fontSubfamily;
693
- if ((fv == null ? void 0 : fv.nameID) === 17) fv.name = (_f = (_e = (_d = font == null ? void 0 : font._tables) == null ? void 0 : _d.name) == null ? void 0 : _e.records) == null ? void 0 : _f.preferredSubfamily;
694
- });
695
- variableInstances = {};
696
- fvar.forEach((v) => {
697
- let key = v.name;
698
- if (typeof key === "object") {
699
- key = Object.values(key)[0];
700
- }
701
- let coordKeys = Object.keys(variableAxes);
702
- let coord = {};
703
- coordKeys.forEach((ck, ckIndex) => {
704
- coord[ck] = v.coord[ckIndex];
705
- });
706
- variableInstances[key] = coord;
707
- });
708
- }
709
- console.log("font : ", font);
710
- console.log("variable instances : ", variableInstances);
711
- console.log("variable axes : ", variableAxes);
712
- let opentypeFeatures = font.availableFeatures;
713
- let glyphCount = font.numGlyphs;
714
- let characterSet = font.characterSet;
715
- let metaData = {
716
- postscriptName: font.postscriptName,
717
- fullName: font.fullName,
718
- familyName: font.familyName,
719
- subfamilyName: font.subfamilyName,
720
- copyright: font.copyright,
721
- version: font.version.replaceAll("Version ", ""),
722
- genDate: (/* @__PURE__ */ new Date()).toISOString()
723
- };
724
- let metrics = {
725
- unitsPerEm: font.unitsPerEm,
726
- ascender: font.ascent,
727
- descender: font.descent,
728
- lineGap: font.lineGap,
729
- underlinePosition: font.underlinePosition,
730
- underlineThickness: font.underlineThickness,
731
- italicAngle: font.italicAngle,
732
- capHeight: font.capHeight,
733
- xHeight: font.xHeight,
734
- boundingBox: font.bbox
735
- };
736
- let variableFont = false;
737
- if (variableAxes && variableAxes != null && Object.keys(variableAxes).length > 0 && variableInstances && variableInstances != null && Object.keys(variableInstances).length > 0) {
738
- variableFont = true;
739
- }
740
- let patch = {
741
- metrics,
742
- metaData,
743
- variableFont,
744
- variableAxes: JSON.stringify(variableAxes),
745
- variableInstances: JSON.stringify(variableInstances),
746
- glyphCount,
747
- opentypeFeatures: { chars: opentypeFeatures },
748
- characterSet: { chars: characterSet }
749
- };
750
- console.log("data : ", patch);
751
- if (commit) patch = await client.patch(fontId).set(patch).commit({ autoGenerateArrayKeys: true });
752
- return patch;
753
- }
754
-
755
- // src/utils/parseVariableFontInstances.js
756
- import { nanoid as nanoid2 } from "nanoid";
757
- var parseVariableFontInstances = async (font, client) => {
758
- if (!font.variableFont || !font.variableInstances) return [];
759
- let variableInstances;
760
- try {
761
- variableInstances = JSON.parse(font.variableInstances);
762
- } catch (err) {
763
- console.error("Error parsing variable instances:", err);
764
- variableInstances = {};
765
- }
766
- if (Object.keys(variableInstances).length === 0) return [];
767
- let staticFonts;
768
- const typeface = await client.fetch(
769
- `*[_type == 'typeface' && title == $typefaceName][0]{
770
- 'fonts': styles.fonts[]-> {
771
- _id,
772
- title,
773
- subfamily,
774
- style,
775
- weight,
776
- weightName,
777
- metaData,
778
- variableFont
779
- }
780
- }`,
781
- { typefaceName: font.typefaceName }
782
- );
783
- if ((typeface == null ? void 0 : typeface.fonts) && typeface.fonts.length > 0) {
784
- staticFonts = typeface.fonts.filter((f) => !f.variableFont);
785
- console.log("Using curated typeface fonts list:", staticFonts.length, "fonts");
786
- } else {
787
- console.warn("Typeface not found or no fonts in curated list, falling back to all fonts query");
788
- staticFonts = await client.fetch(
789
- `*[_type == 'font' && typefaceName == $typefaceName && variableFont != true]{
790
- _id,
791
- title,
792
- subfamily,
793
- style,
794
- weight,
795
- weightName,
796
- metaData
797
- }`,
798
- { typefaceName: font.typefaceName }
799
- );
800
- }
801
- console.log("Variable font instances:", Object.keys(variableInstances));
802
- console.log("Available static fonts:", staticFonts.map((sf) => sf.title));
803
- const instanceMappings = [];
804
- Object.keys(variableInstances).forEach((instanceName) => {
805
- let matchingFont = null;
806
- matchingFont = staticFonts.find((sf) => sf.title === instanceName);
807
- if (!matchingFont && staticFonts.some((sf) => {
808
- var _a;
809
- return (_a = sf.metaData) == null ? void 0 : _a.fullName;
810
- })) {
811
- matchingFont = staticFonts.find((sf) => {
812
- var _a, _b, _c, _d;
813
- if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
814
- let fullName = sf.metaData.fullName;
815
- const WORDS_TO_REMOVE = ["VF", "var", "variable", "VAR", "vf"];
816
- const variableName = (_c = (_b = font.metaData) == null ? void 0 : _b.familyName) == null ? void 0 : _c.replace(new RegExp(`\\b(${WORDS_TO_REMOVE.join("|")})\\b`, "gi"), "").replace(/\s{2,}/g, " ").trim();
817
- if (variableName && fullName.startsWith(variableName)) {
818
- fullName = fullName.substring(variableName.length).trim();
819
- }
820
- if (variableName) {
821
- const words = variableName.split(/\s+/).map((w) => w.trim()).filter(Boolean);
822
- if (words.length > 0) {
823
- const regex = new RegExp(`\\b(${words.join("|")})\\b`, "gi");
824
- const stripped = fullName.replace(regex, "").replace(/\s{2,}/g, " ").trim();
825
- if (stripped !== "") fullName = stripped;
826
- }
827
- }
828
- if (fullName.startsWith(font.typefaceName)) {
829
- fullName = fullName.substring(font.typefaceName.length).trim();
830
- }
831
- if (((_d = sf.style) == null ? void 0 : _d.toLowerCase()) === "italic" && !fullName.toLowerCase().endsWith("italic") && !fullName.toLowerCase().endsWith("slanted")) {
832
- fullName = fullName + " Italic";
833
- }
834
- if (fullName.trim().toLowerCase().endsWith("regular")) {
835
- if (instanceName.trim().toLowerCase() + " regular" === fullName.trim().toLowerCase()) return true;
836
- }
837
- if (fullName.trim().toLowerCase().startsWith("regular")) {
838
- if ("regular " + instanceName.trim().toLowerCase() === fullName.trim().toLowerCase()) return true;
839
- }
840
- if (fullName.trim().toLowerCase().endsWith("italic")) {
841
- if (instanceName.trim().toLowerCase().endsWith("italic")) {
842
- const k = instanceName.trim().toLowerCase().slice(0, -6).trim() + " regular italic";
843
- if (k === fullName.trim().toLowerCase()) return true;
844
- }
845
- }
846
- return fullName.trim().toLowerCase() === instanceName.trim().toLowerCase();
847
- });
848
- }
849
- if (!matchingFont) {
850
- const expandedName = instanceName.split(" ").map((word) => expandAbbreviations(word)).join(" ");
851
- matchingFont = staticFonts.find((sf) => {
852
- const nameWithoutTypeface = sf.title.replace(font.typefaceName, "").trim();
853
- return nameWithoutTypeface === expandedName;
854
- });
855
- }
856
- if (!matchingFont) {
857
- const isItalic = instanceName.toLowerCase().includes("italic");
858
- const weightTerms = [
859
- { term: "thin", weight: "100" },
860
- { term: "extralight", weight: "200" },
861
- { term: "extra light", weight: "200" },
862
- { term: "light", weight: "300" },
863
- { term: "regular", weight: "400" },
864
- { term: "normal", weight: "400" },
865
- { term: "medium", weight: "500" },
866
- { term: "semibold", weight: "600" },
867
- { term: "semi bold", weight: "600" },
868
- { term: "bold", weight: "700" },
869
- { term: "extrabold", weight: "800" },
870
- { term: "extra bold", weight: "800" },
871
- { term: "black", weight: "900" },
872
- { term: "heavy", weight: "900" }
873
- ];
874
- let instanceWeight = "400";
875
- for (const { term, weight } of weightTerms) {
876
- if (instanceName.toLowerCase().includes(term)) {
877
- instanceWeight = weight;
878
- break;
879
- }
880
- }
881
- matchingFont = staticFonts.find(
882
- (sf) => sf.weight === instanceWeight && (isItalic && sf.style === "Italic" || !isItalic && sf.style === "Regular")
883
- );
884
- }
885
- if (!matchingFont) {
886
- matchingFont = staticFonts.find((sf) => {
887
- if (!sf.weightName) return false;
888
- const cleanInstance = instanceName.toLowerCase().replace(/italic/i, "").trim();
889
- const cleanWeight = sf.weightName.toLowerCase().replace(/italic/i, "").trim();
890
- return cleanInstance === cleanWeight;
891
- });
892
- }
893
- if (!matchingFont && staticFonts.some((sf) => {
894
- var _a;
895
- return (_a = sf.metaData) == null ? void 0 : _a.fullName;
896
- })) {
897
- matchingFont = staticFonts.find((sf) => {
898
- var _a;
899
- if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
900
- const typefacePattern = new RegExp(`^${font.typefaceName}\\s+`, "i");
901
- const stylePart = sf.metaData.fullName.replace(typefacePattern, "").trim();
902
- return instanceName.toLowerCase() === stylePart.toLowerCase();
903
- });
904
- }
905
- console.log(`Instance "${instanceName}" matched with:`, matchingFont ? matchingFont.title : "No match found");
906
- instanceMappings.push({
907
- key: instanceName,
908
- value: matchingFont ? { _type: "reference", _ref: matchingFont._id, _weak: true } : null,
909
- _key: nanoid2()
910
- });
911
- });
912
- return instanceMappings;
913
- };
914
- var parseVariableFontInstances_default = parseVariableFontInstances;
915
-
916
79
  // src/utils/uploadFontFiles.js
80
+ import { nanoid } from "nanoid";
917
81
  var uploadFontFiles = async (fontsObjects, subfamilies, client, inputPrice, stylesObject, setStatus, setError, preserveFileNames = false) => {
918
82
  let fontRefs = [];
919
83
  let variableRefs = [];
@@ -1010,7 +174,7 @@ var determineFileType = (file) => {
1010
174
  if (file.name.endsWith(".svg")) return "svg";
1011
175
  return "";
1012
176
  };
1013
- var resolveExistingFont = async (font, client) => {
177
+ var resolveExistingFont2 = async (font, client) => {
1014
178
  const result = { exact: null, candidates: [], recommendation: "create" };
1015
179
  try {
1016
180
  const idMatches = await client.fetch(
@@ -1071,7 +235,7 @@ var resolveExistingFont = async (font, client) => {
1071
235
  };
1072
236
  var createOrUpdateFontDocument = async (font, client, setError) => {
1073
237
  try {
1074
- const { exact, candidates, recommendation } = await resolveExistingFont(font, client);
238
+ const { exact, candidates, recommendation } = await resolveExistingFont2(font, client);
1075
239
  const { files, fontKit } = font;
1076
240
  delete font.files;
1077
241
  delete font.fontKit;
@@ -1093,7 +257,7 @@ var createOrUpdateFontDocument = async (font, client, setError) => {
1093
257
  fontResponse = await createNewFont(font, client);
1094
258
  }
1095
259
  return {
1096
- _key: nanoid3(),
260
+ _key: nanoid(),
1097
261
  _type: "reference",
1098
262
  _ref: fontResponse._id,
1099
263
  _weak: true
@@ -1136,7 +300,7 @@ var createNewFont = async (font, client) => {
1136
300
  console.log("Creating new font:", font._id, font.title);
1137
301
  if (font.metaData) cleanMetadataValues(font);
1138
302
  const newDocument = {
1139
- _key: nanoid3(),
303
+ _key: nanoid(),
1140
304
  _id: font._id,
1141
305
  _type: "font",
1142
306
  ...font
@@ -1173,89 +337,7 @@ var addToVariableRefs = (fontRef, font, variableRefs, stylesObject) => {
1173
337
  }
1174
338
  };
1175
339
 
1176
- // src/utils/updateTypefaceDocument.js
1177
- import { nanoid as nanoid4 } from "nanoid";
1178
- var updateTypefaceDocument = async (doc_id, fontRefs, variableRefs, subfamilies, uniqueSubfamilies, subfamiliesArray, preferredStyleRef, newPreferredStyle, stylesObject, client, setStatus, setError) => {
1179
- console.log("Updating typeface document with new fonts:", { fontRefs, variableRefs, subfamilies, uniqueSubfamilies });
1180
- setStatus("Updating typeface references...");
1181
- let patch = {
1182
- "styles.fonts": stylesObject.fonts ? [...stylesObject.fonts, ...fontRefs] : [...fontRefs],
1183
- "styles.variableFont": (stylesObject == null ? void 0 : stylesObject.variableFont) ? [...stylesObject.variableFont, ...variableRefs] : [...variableRefs]
1184
- };
1185
- setStatus("Organising font subfamilies...");
1186
- subfamiliesArray = subfamiliesArray || [];
1187
- uniqueSubfamilies.forEach((subfamilyName) => {
1188
- if (!subfamiliesArray.find((sf) => sf.title === subfamilyName)) {
1189
- subfamiliesArray.push({
1190
- title: subfamilyName,
1191
- _key: nanoid4(),
1192
- _type: "object",
1193
- fonts: []
1194
- });
1195
- }
1196
- });
1197
- if (subfamiliesArray.length > 0) {
1198
- Object.entries(subfamilies).forEach(([id, subfamilyName]) => {
1199
- if (id.toLowerCase().includes("vf")) return;
1200
- const subfamilyIndex = subfamiliesArray.findIndex((sf) => sf.title === subfamilyName);
1201
- if (subfamilyIndex !== -1) {
1202
- subfamiliesArray[subfamilyIndex].fonts.push({
1203
- _ref: id,
1204
- _key: nanoid4(),
1205
- _type: "reference",
1206
- _weak: true
1207
- });
1208
- }
1209
- });
1210
- subfamiliesArray = subfamiliesArray.map((subfamily) => ({
1211
- ...subfamily,
1212
- fonts: subfamily.fonts.filter(
1213
- (font, index, self) => index === self.findIndex((f) => f._ref === font._ref)
1214
- )
1215
- }));
1216
- }
1217
- patch["styles.subfamilies"] = subfamiliesArray;
1218
- await updatePreferredStyle(doc_id, preferredStyleRef, newPreferredStyle, patch, client);
1219
- console.log("doc_id: ", doc_id);
1220
- console.log("Typeface patch: ", patch);
1221
- console.log("New preferred style: ", newPreferredStyle);
1222
- console.log("SubfamiliesArray:", subfamiliesArray);
1223
- try {
1224
- await client.patch(doc_id).set(patch).commit();
1225
- console.log(`Updated document: ${doc_id}`);
1226
- if (doc_id.startsWith("drafts.")) {
1227
- await updatePublishedDocument(doc_id, patch, client);
1228
- }
1229
- } catch (err) {
1230
- console.error("Error updating document:", err.message);
1231
- setStatus("Error updating typeface");
1232
- setError(true);
1233
- }
1234
- };
1235
- var updatePreferredStyle = async (doc_id, preferredStyleRef, newPreferredStyle, patch, client) => {
1236
- const isCurrentlyEmpty = !(preferredStyleRef == null ? void 0 : preferredStyleRef._ref) || preferredStyleRef._ref === "" || preferredStyleRef._ref === null;
1237
- const hasCandidate = (newPreferredStyle == null ? void 0 : newPreferredStyle._ref) && newPreferredStyle._ref !== "";
1238
- if (isCurrentlyEmpty && hasCandidate) {
1239
- patch.preferredStyle = {
1240
- _type: "reference",
1241
- _ref: newPreferredStyle._ref,
1242
- _weak: true
1243
- };
1244
- }
1245
- };
1246
- var updatePublishedDocument = async (doc_id, patch, client) => {
1247
- const publishedId = doc_id.replace("drafts.", "");
1248
- const publishedDoc = await client.fetch(`*[_id == $publishedId]`, { publishedId }).then((res) => res[0]);
1249
- if (publishedDoc) {
1250
- await client.patch(publishedId).set(patch).commit();
1251
- console.log(`Updated published document: ${publishedId}`);
1252
- } else {
1253
- console.log(`No published document found for ${publishedId}, skipping`);
1254
- }
1255
- };
1256
-
1257
340
  // src/utils/regenerateFontData.js
1258
- import * as fontkit4 from "fontkit";
1259
341
  var renameFontDocuments = async ({
1260
342
  client,
1261
343
  typefaceName,
@@ -1325,7 +407,7 @@ var renameFontDocuments = async ({
1325
407
  file = await res.blob();
1326
408
  }
1327
409
  const fontBuffer = await readFontFile(file);
1328
- const font = fontkit4.create(fontBuffer);
410
+ const font = await parseFont(fontBuffer, `${fontDoc._id}.ttf`);
1329
411
  const { weightName, subfamilyName, fontTitle } = extractFontMetadata(
1330
412
  font,
1331
413
  typefaceName,
@@ -1443,24 +525,10 @@ var StatusDisplay = ({ status, error, action }) => {
1443
525
  };
1444
526
  var StatusDisplay_default = StatusDisplay;
1445
527
 
1446
- // src/components/PriceInput.jsx
1447
- import React2 from "react";
1448
- import { Flex as Flex2, Text as Text2 } from "@sanity/ui";
1449
- var PriceInput = ({ inputPrice, handleInputChange }) => /* @__PURE__ */ React2.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "Price:"), /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "$"), /* @__PURE__ */ React2.createElement(
1450
- "input",
1451
- {
1452
- value: inputPrice,
1453
- onChange: handleInputChange,
1454
- type: "number",
1455
- style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
1456
- }
1457
- ), /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "per style"));
1458
- var PriceInput_default = PriceInput;
1459
-
1460
528
  // src/components/RegenerateSubfamiliesComponent.jsx
1461
- import React3, { useState } from "react";
1462
- import { nanoid as nanoid5 } from "nanoid";
1463
- import { Button, Text as Text3, Stack, Box } from "@sanity/ui";
529
+ import React2, { useState } from "react";
530
+ import { nanoid as nanoid2 } from "nanoid";
531
+ import { Button, Text as Text2, Stack, Box } from "@sanity/ui";
1464
532
  import { useFormValue } from "sanity";
1465
533
  var RegenerateSubfamiliesComponent = () => {
1466
534
  const [status, setStatus] = useState("");
@@ -1474,7 +542,7 @@ var RegenerateSubfamiliesComponent = () => {
1474
542
  const handleClick = () => {
1475
543
  regenerateSubfamilies({ title, stylesObject, slug, doc_id, client, setStatus, setReady, setError });
1476
544
  };
1477
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, status && /* @__PURE__ */ React3.createElement(Box, { padding: 3, style: { borderRadius: "4px", marginBottom: "10px" } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, style: { color: error ? "red" : "green" } }, status)), /* @__PURE__ */ React3.createElement(Button, { mode: "ghost", tone: "primary", width: "fill", padding: 3, onClick: handleClick, disabled: !ready }, /* @__PURE__ */ React3.createElement(Stack, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { align: "center" }, "Regenerate Subfamilies"))));
545
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, status && /* @__PURE__ */ React2.createElement(Box, { padding: 3, style: { borderRadius: "4px", marginBottom: "10px" } }, /* @__PURE__ */ React2.createElement(Text2, { size: 1, style: { color: error ? "red" : "green" } }, status)), /* @__PURE__ */ React2.createElement(Button, { mode: "ghost", tone: "primary", width: "fill", padding: 3, onClick: handleClick, disabled: !ready }, /* @__PURE__ */ React2.createElement(Stack, { space: 2 }, /* @__PURE__ */ React2.createElement(Text2, { align: "center" }, "Regenerate Subfamilies"))));
1478
546
  };
1479
547
  var regenerateSubfamilies = async ({ title, stylesObject, slug, doc_id, client, setStatus, setReady, setError }) => {
1480
548
  try {
@@ -1530,11 +598,11 @@ var groupFontsBySubfamily = (fonts) => {
1530
598
  var createSubfamiliesArray = (subfamilies) => {
1531
599
  return Object.keys(subfamilies).map((subfamilyName) => ({
1532
600
  title: subfamilyName,
1533
- _key: nanoid5(),
601
+ _key: nanoid2(),
1534
602
  _type: "object",
1535
603
  fonts: subfamilies[subfamilyName].map((font) => ({
1536
604
  _ref: font._id,
1537
- _key: nanoid5(),
605
+ _key: nanoid2(),
1538
606
  _type: "reference",
1539
607
  _weak: true
1540
608
  }))
@@ -1568,6 +636,7 @@ var updateTypefaceSubfamilies = async (doc_id, stylesObject, newSubfamiliesArray
1568
636
  };
1569
637
 
1570
638
  // src/components/BatchUploadFonts.jsx
639
+ var UploadModal2 = lazy(() => import("./UploadModal-ADNRGQUI.mjs"));
1571
640
  var ACCEPTED_EXTENSIONS = ["ttf", "otf", "woff", "woff2", "eot", "svg"];
1572
641
  var formatElapsed = (s) => {
1573
642
  const m = Math.floor(s / 60);
@@ -1585,6 +654,7 @@ var BatchUploadFonts = () => {
1585
654
  const [pendingFiles, setPendingFiles] = useState2([]);
1586
655
  const [isDragging, setIsDragging] = useState2(false);
1587
656
  const [elapsedSeconds, setElapsedSeconds] = useState2(0);
657
+ const [showUploadModal, setShowUploadModal] = useState2(false);
1588
658
  const fileInputRef = useRef(null);
1589
659
  const elapsedTimerRef = useRef(null);
1590
660
  const wakeLockRef = useRef(null);
@@ -1877,17 +947,17 @@ var BatchUploadFonts = () => {
1877
947
  setError(false);
1878
948
  setStatus("ready");
1879
949
  };
1880
- const renderTooltipLabel = (label, description) => /* @__PURE__ */ React4.createElement(
950
+ const renderTooltipLabel = (label, description) => /* @__PURE__ */ React3.createElement(
1881
951
  Tooltip,
1882
952
  {
1883
- content: /* @__PURE__ */ React4.createElement(Box2, { padding: 2, style: { maxWidth: 260 } }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, style: { lineHeight: 1.6 } }, description)),
953
+ content: /* @__PURE__ */ React3.createElement(Box2, { padding: 2, style: { maxWidth: 260 } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, style: { lineHeight: 1.6 } }, description)),
1884
954
  placement: "top",
1885
955
  portal: true
1886
956
  },
1887
- /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 1, style: { cursor: "default" } }, /* @__PURE__ */ React4.createElement(Label, null, label), /* @__PURE__ */ React4.createElement(InfoOutlineIcon, { style: { opacity: 0.5, display: "block" } }))
957
+ /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 1, style: { cursor: "default" } }, /* @__PURE__ */ React3.createElement(Label, null, label), /* @__PURE__ */ React3.createElement(InfoOutlineIcon, { style: { opacity: 0.5, display: "block" } }))
1888
958
  );
1889
- const renderProcessing = () => /* @__PURE__ */ React4.createElement(Stack2, { space: 3, paddingY: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 3 }, /* @__PURE__ */ React4.createElement(Spinner, null), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, status)), /* @__PURE__ */ React4.createElement(Card, { tone: "caution", border: true, radius: 2, padding: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "space-between", gap: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(WarningOutlineIcon, { style: { flexShrink: 0 } }), /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold" }, "Do not close or reload this tab")), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true, style: { flexShrink: 0 } }, formatElapsed(elapsedSeconds)))));
1890
- const renderDropZone = () => /* @__PURE__ */ React4.createElement(
959
+ const renderProcessing = () => /* @__PURE__ */ React3.createElement(Stack2, { space: 3, paddingY: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 3 }, /* @__PURE__ */ React3.createElement(Spinner, null), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, status)), /* @__PURE__ */ React3.createElement(Card, { tone: "caution", border: true, radius: 2, padding: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "space-between", gap: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(WarningOutlineIcon, { style: { flexShrink: 0 } }), /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold" }, "Do not close or reload this tab")), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true, style: { flexShrink: 0 } }, formatElapsed(elapsedSeconds)))));
960
+ const renderDropZone = () => /* @__PURE__ */ React3.createElement(
1891
961
  Box2,
1892
962
  {
1893
963
  onDragEnter: handleDragEnter,
@@ -1904,7 +974,7 @@ var BatchUploadFonts = () => {
1904
974
  cursor: "default"
1905
975
  }
1906
976
  },
1907
- /* @__PURE__ */ React4.createElement(
977
+ /* @__PURE__ */ React3.createElement(
1908
978
  "input",
1909
979
  {
1910
980
  ref: fileInputRef,
@@ -1915,7 +985,7 @@ var BatchUploadFonts = () => {
1915
985
  onChange: handleFileSelect
1916
986
  }
1917
987
  ),
1918
- /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, isDragging ? "Release to add files" : "Drop font files here"), /* @__PURE__ */ React4.createElement(Flex3, { justify: "center" }, /* @__PURE__ */ React4.createElement(
988
+ /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, isDragging ? "Release to add files" : "Drop font files here"), /* @__PURE__ */ React3.createElement(Flex2, { justify: "center" }, /* @__PURE__ */ React3.createElement(
1919
989
  Button2,
1920
990
  {
1921
991
  mode: "ghost",
@@ -1932,7 +1002,7 @@ var BatchUploadFonts = () => {
1932
1002
  );
1933
1003
  const renderFileList = () => {
1934
1004
  const sorted = sortFilesByType(pendingFiles);
1935
- return /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "space-between" }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, pendingFiles.length, " file", pendingFiles.length === 1 ? "" : "s", " selected"), /* @__PURE__ */ React4.createElement(
1005
+ return /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "space-between" }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, pendingFiles.length, " file", pendingFiles.length === 1 ? "" : "s", " selected"), /* @__PURE__ */ React3.createElement(
1936
1006
  Button2,
1937
1007
  {
1938
1008
  mode: "bleed",
@@ -1942,16 +1012,16 @@ var BatchUploadFonts = () => {
1942
1012
  text: "Clear all",
1943
1013
  onClick: () => setPendingFiles([])
1944
1014
  }
1945
- )), /* @__PURE__ */ React4.createElement(Box2, { style: { maxHeight: "260px", overflowY: "auto", display: "flex", flexDirection: "column", gap: "4px" } }, sorted.map((file, i) => {
1015
+ )), /* @__PURE__ */ React3.createElement(Box2, { style: { maxHeight: "260px", overflowY: "auto", display: "flex", flexDirection: "column", gap: "4px" } }, sorted.map((file, i) => {
1946
1016
  const ext = file.name.split(".").pop().toUpperCase();
1947
- return /* @__PURE__ */ React4.createElement(Card, { key: `${file.name}-${file.size}-${i}`, border: true, radius: 1, paddingX: 2, paddingY: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React4.createElement(
1948
- Text4,
1017
+ return /* @__PURE__ */ React3.createElement(Card, { key: `${file.name}-${file.size}-${i}`, border: true, radius: 1, paddingX: 2, paddingY: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React3.createElement(
1018
+ Text3,
1949
1019
  {
1950
1020
  size: 0,
1951
1021
  style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0 }
1952
1022
  },
1953
1023
  ext
1954
- ), /* @__PURE__ */ React4.createElement(Box2, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React4.createElement(Text4, { size: 1 }, file.name))), /* @__PURE__ */ React4.createElement(
1024
+ ), /* @__PURE__ */ React3.createElement(Box2, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1 }, file.name))), /* @__PURE__ */ React3.createElement(
1955
1025
  Button2,
1956
1026
  {
1957
1027
  mode: "bleed",
@@ -1961,7 +1031,7 @@ var BatchUploadFonts = () => {
1961
1031
  onClick: () => handleRemoveFile(file)
1962
1032
  }
1963
1033
  )));
1964
- })), /* @__PURE__ */ React4.createElement(
1034
+ })), /* @__PURE__ */ React3.createElement(
1965
1035
  Box2,
1966
1036
  {
1967
1037
  onDragEnter: handleDragEnter,
@@ -1977,7 +1047,7 @@ var BatchUploadFonts = () => {
1977
1047
  transition: "border-color 0.12s, background 0.12s"
1978
1048
  }
1979
1049
  },
1980
- /* @__PURE__ */ React4.createElement(
1050
+ /* @__PURE__ */ React3.createElement(
1981
1051
  "input",
1982
1052
  {
1983
1053
  ref: fileInputRef,
@@ -1988,7 +1058,7 @@ var BatchUploadFonts = () => {
1988
1058
  onChange: handleFileSelect
1989
1059
  }
1990
1060
  ),
1991
- /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, isDragging ? "Release to add" : "Drop more files or"), /* @__PURE__ */ React4.createElement(
1061
+ /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, isDragging ? "Release to add" : "Drop more files or"), /* @__PURE__ */ React3.createElement(
1992
1062
  Button2,
1993
1063
  {
1994
1064
  mode: "bleed",
@@ -2002,7 +1072,7 @@ var BatchUploadFonts = () => {
2002
1072
  }
2003
1073
  }
2004
1074
  ))
2005
- ), /* @__PURE__ */ React4.createElement(
1075
+ ), /* @__PURE__ */ React3.createElement(
2006
1076
  Button2,
2007
1077
  {
2008
1078
  mode: "ghost",
@@ -2014,12 +1084,13 @@ var BatchUploadFonts = () => {
2014
1084
  }
2015
1085
  ));
2016
1086
  };
2017
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, title && title !== "" && slug && slug !== "" && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
1087
+ const hasRequiredFields = title && title !== "" && slug && slug !== "";
1088
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, !hasRequiredFields && /* @__PURE__ */ React3.createElement(Card, { border: true, padding: 4, radius: 2, tone: "caution" }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 2 }, /* @__PURE__ */ React3.createElement(WarningOutlineIcon, null)), /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold" }, !title || title === "" ? "Title required to use font uploader" : "Slug required to use font uploader"), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, "Add a ", !title || title === "" ? "title" : "slug", " to this typeface document, then return to the Styles tab to upload fonts.")))), hasRequiredFields && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
2018
1089
  StatusDisplay_default,
2019
1090
  {
2020
1091
  status,
2021
1092
  error,
2022
- action: /* @__PURE__ */ React4.createElement(
1093
+ action: /* @__PURE__ */ React3.createElement(
2023
1094
  Button2,
2024
1095
  {
2025
1096
  mode: showUtilities ? "default" : "ghost",
@@ -2032,16 +1103,31 @@ var BatchUploadFonts = () => {
2032
1103
  }
2033
1104
  )
2034
1105
  }
2035
- ), /* @__PURE__ */ React4.createElement(Card, { border: true, padding: 2, shadow: 1, radius: 2 }, showUtilities ? /* @__PURE__ */ React4.createElement(Stack2, { space: 4, marginTop: 2 }, /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate Subfamilies"), /* @__PURE__ */ React4.createElement(RegenerateSubfamiliesComponent, null)), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Rename Fonts (name table, Full Name)"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
2036
- Switch,
1106
+ ), /* @__PURE__ */ React3.createElement(
1107
+ Button2,
2037
1108
  {
2038
- checked: preserveShortenedNames,
2039
- onChange: (e) => setPreserveShortenedNames(e.target.checked)
1109
+ mode: "default",
1110
+ tone: "primary",
1111
+ icon: UploadIcon,
1112
+ text: "Upload Fonts",
1113
+ fontSize: 2,
1114
+ padding: 4,
1115
+ onClick: () => setShowUploadModal(true),
1116
+ style: { width: "100%" }
2040
1117
  }
2041
- ), renderTooltipLabel(
2042
- "Preserve shortened names",
2043
- 'Abbreviations in font names are kept as-is (e.g. "XNarrow" stays "XNarrow", "Bd" stays "Bd").'
2044
- )), ready === "rename" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Rename Existing Fonts", style: { width: "100%" }, onClick: handleRenameExistingFonts, disabled: ready !== true })), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Update Font Prices"), ready === "price" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(PriceInput_default, { inputPrice, handleInputChange }), /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Update All Font Prices", style: { width: "100%" }, onClick: handleChangeFontPrice, disabled: ready !== true }))), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate CSS"), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true, style: { lineHeight: 1.6 } }, "Rebuilds the CSS @font-face files for all fonts in the typeface fonts list."), ready === "css" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Regenerate CSS Files", style: { width: "100%" }, onClick: handleRegenerateCssFiles, disabled: ready !== true }))) : ready ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(Grid, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Box2, null, /* @__PURE__ */ React4.createElement(PriceInput_default, { inputPrice, handleInputChange })), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
1118
+ ), showUploadModal && /* @__PURE__ */ React3.createElement(Suspense, { fallback: /* @__PURE__ */ React3.createElement(Spinner, null) }, /* @__PURE__ */ React3.createElement(
1119
+ UploadModal2,
1120
+ {
1121
+ open: showUploadModal,
1122
+ onClose: () => setShowUploadModal(false),
1123
+ client,
1124
+ docId: doc_id,
1125
+ typefaceTitle: title,
1126
+ stylesObject,
1127
+ preferredStyleRef,
1128
+ slug
1129
+ }
1130
+ )), showUtilities && /* @__PURE__ */ React3.createElement(Card, { border: true, padding: 3, shadow: 1, radius: 2, marginTop: 3 }, /* @__PURE__ */ React3.createElement(Stack2, { space: 4 }, /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate Subfamilies"), /* @__PURE__ */ React3.createElement(RegenerateSubfamiliesComponent, null)), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Rename Fonts (name table, Full Name)"), /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(
2045
1131
  Switch,
2046
1132
  {
2047
1133
  checked: preserveShortenedNames,
@@ -2050,24 +1136,15 @@ var BatchUploadFonts = () => {
2050
1136
  ), renderTooltipLabel(
2051
1137
  "Preserve shortened names",
2052
1138
  'Abbreviations in font names are kept as-is (e.g. "XNarrow" stays "XNarrow", "Bd" stays "Bd").'
2053
- )), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
2054
- Switch,
2055
- {
2056
- checked: preserveFileNames,
2057
- onChange: (e) => setPreserveFileNames(e.target.checked)
2058
- }
2059
- ), renderTooltipLabel(
2060
- "Preserve file names",
2061
- "Original filename capitalisation is used for asset naming instead of the normalised font title."
2062
- )))), /* @__PURE__ */ React4.createElement(Box2, { marginTop: 3 }, pendingFiles.length === 0 ? renderDropZone() : renderFileList())) : renderProcessing())));
1139
+ )), ready === "rename" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Rename Existing Fonts", style: { width: "100%" }, onClick: handleRenameExistingFonts, disabled: ready !== true })), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Update Font Prices"), ready === "price" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(PriceInput_default, { inputPrice, handleInputChange }), /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Update All Font Prices", style: { width: "100%" }, onClick: handleChangeFontPrice, disabled: ready !== true }))), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate CSS"), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true, style: { lineHeight: 1.6 } }, "Rebuilds the CSS @font-face files for all fonts in the typeface fonts list."), ready === "css" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Regenerate CSS Files", style: { width: "100%" }, onClick: handleRegenerateCssFiles, disabled: ready !== true }))))));
2063
1140
  };
2064
1141
 
2065
1142
  // src/components/GenerateCollectionsPairsComponent.jsx
2066
- import React5, { useCallback as useCallback2, useState as useState3 } from "react";
2067
- import { Stack as Stack3, Grid as Grid2, Flex as Flex4, Text as Text5, Button as Button3, Card as Card2, Spinner as Spinner2 } from "@sanity/ui";
1143
+ import React4, { useCallback as useCallback2, useState as useState3 } from "react";
1144
+ import { Stack as Stack3, Grid as Grid2, Flex as Flex3, Text as Text4, Button as Button3, Card as Card2, Spinner as Spinner2 } from "@sanity/ui";
2068
1145
  import { useFormValue as useFormValue3 } from "sanity";
2069
- import slugify2 from "slugify";
2070
- import { nanoid as nanoid6 } from "nanoid";
1146
+ import slugify from "slugify";
1147
+ import { nanoid as nanoid3 } from "nanoid";
2071
1148
  var GenerateCollectionsPairsComponent = () => {
2072
1149
  const [status, setStatus] = useState3("ready");
2073
1150
  const [ready, setReady] = useState3(true);
@@ -2085,7 +1162,7 @@ var GenerateCollectionsPairsComponent = () => {
2085
1162
  const createSanityCollection = useCallback2(async (fontsList, collectionSlug, newTitle) => {
2086
1163
  const newSlug = collectionSlug.toLowerCase().trim();
2087
1164
  const fontRefs = fontsList.map((font) => ({
2088
- _key: nanoid6(),
1165
+ _key: nanoid3(),
2089
1166
  _type: "reference",
2090
1167
  _ref: font._id ?? font._ref,
2091
1168
  _weak: true
@@ -2101,7 +1178,7 @@ var GenerateCollectionsPairsComponent = () => {
2101
1178
  });
2102
1179
  const price = (collectionPrice ? Number(collectionPrice) : 0) * fontRefs.length;
2103
1180
  await client.createOrReplace({
2104
- _key: nanoid6(),
1181
+ _key: nanoid3(),
2105
1182
  _id: newSlug,
2106
1183
  _type: "collection",
2107
1184
  state: "active",
@@ -2114,18 +1191,18 @@ var GenerateCollectionsPairsComponent = () => {
2114
1191
  }).catch((err) => {
2115
1192
  console.error("Error creating collection:", err.message);
2116
1193
  });
2117
- return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid6() };
1194
+ return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid3() };
2118
1195
  }, [collectionPrice, client]);
2119
1196
  const createSanityPair = useCallback2(async (pair, pairSlug, newTitle) => {
2120
1197
  const newSlug = pairSlug.toLowerCase().trim();
2121
1198
  const fontRefs = pair.map((font) => ({
2122
- _key: nanoid6(),
1199
+ _key: nanoid3(),
2123
1200
  _type: "reference",
2124
1201
  _ref: font._id,
2125
1202
  _weak: true
2126
1203
  }));
2127
1204
  await client.createOrReplace({
2128
- _key: nanoid6(),
1205
+ _key: nanoid3(),
2129
1206
  _id: newSlug,
2130
1207
  _type: "pair",
2131
1208
  preferredStyle: { _type: "reference", _ref: fontRefs[0]._ref, _weak: true },
@@ -2136,7 +1213,7 @@ var GenerateCollectionsPairsComponent = () => {
2136
1213
  }).catch((err) => {
2137
1214
  console.error("Error creating pair:", err.message);
2138
1215
  });
2139
- return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid6() };
1216
+ return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid3() };
2140
1217
  }, [pairPrice, client]);
2141
1218
  const handleGenerateCollections = useCallback2(async () => {
2142
1219
  setStatus("Generating collections...");
@@ -2174,7 +1251,7 @@ var GenerateCollectionsPairsComponent = () => {
2174
1251
  setStatus(`[${i + 4}/${totalCollections}] Generating ${subfamilies[i].title} collection`);
2175
1252
  const ref = await createSanityCollection(
2176
1253
  subfamilies[i].fonts,
2177
- `${slug.current}-${slugify2(subfamilies[i].title)}-family`,
1254
+ `${slug.current}-${slugify(subfamilies[i].title)}-family`,
2178
1255
  `${title} ${subfamilies[i].title} Family`
2179
1256
  );
2180
1257
  if (ref) typefacePatch.push(ref);
@@ -2216,14 +1293,14 @@ var GenerateCollectionsPairsComponent = () => {
2216
1293
  let pairSlug, pairTitle;
2217
1294
  if (reg.subfamily && reg.subfamily !== "") {
2218
1295
  if (reg.subfamily === "Regular") {
2219
- pairSlug = `${slug.current}-${slugify2(reg.weightName)}s`;
1296
+ pairSlug = `${slug.current}-${slugify(reg.weightName)}s`;
2220
1297
  pairTitle = `${title} ${reg.weightName}s`;
2221
1298
  } else {
2222
- pairSlug = `${slug.current}-${slugify2(reg.subfamily)}-${slugify2(reg.weightName)}s`;
1299
+ pairSlug = `${slug.current}-${slugify(reg.subfamily)}-${slugify(reg.weightName)}s`;
2223
1300
  pairTitle = `${title} ${reg.subfamily} ${reg.weightName}s`;
2224
1301
  }
2225
1302
  } else {
2226
- pairSlug = `${slug.current}-${slugify2(reg.weightName)}s`;
1303
+ pairSlug = `${slug.current}-${slugify(reg.weightName)}s`;
2227
1304
  pairTitle = `${title} ${reg.weightName}s`;
2228
1305
  }
2229
1306
  setStatus(`[${i + 1}/${pairs.length}] Generating ${pairTitle}`);
@@ -2243,7 +1320,7 @@ var GenerateCollectionsPairsComponent = () => {
2243
1320
  setReady(true);
2244
1321
  }, [doc_id, title, slug, stylesObject, pairPrice, client, createSanityPair]);
2245
1322
  if (!title || !slug) return null;
2246
- return /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React5.createElement(Card2, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React5.createElement(Stack3, { space: 3 }, /* @__PURE__ */ React5.createElement(Grid2, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "Collection price / font"), /* @__PURE__ */ React5.createElement(Flex4, { align: "center", gap: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "$"), /* @__PURE__ */ React5.createElement(
1323
+ return /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React4.createElement(Card2, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React4.createElement(Stack3, { space: 3 }, /* @__PURE__ */ React4.createElement(Grid2, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "Collection price / font"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "$"), /* @__PURE__ */ React4.createElement(
2247
1324
  "input",
2248
1325
  {
2249
1326
  value: collectionPrice,
@@ -2251,7 +1328,7 @@ var GenerateCollectionsPairsComponent = () => {
2251
1328
  type: "number",
2252
1329
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
2253
1330
  }
2254
- ))), /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "Pair price"), /* @__PURE__ */ React5.createElement(Flex4, { align: "center", gap: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "$"), /* @__PURE__ */ React5.createElement(
1331
+ ))), /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "Pair price"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "$"), /* @__PURE__ */ React4.createElement(
2255
1332
  "input",
2256
1333
  {
2257
1334
  value: pairPrice,
@@ -2259,12 +1336,12 @@ var GenerateCollectionsPairsComponent = () => {
2259
1336
  type: "number",
2260
1337
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
2261
1338
  }
2262
- )))), /* @__PURE__ */ React5.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Collections", style: { width: "100%" }, onClick: handleGenerateCollections }), /* @__PURE__ */ React5.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Pairs", style: { width: "100%" }, onClick: handleGeneratePairs })) : /* @__PURE__ */ React5.createElement(Flex4, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React5.createElement(Spinner2, null), /* @__PURE__ */ React5.createElement(Text5, { muted: true, size: 1 }, status))));
1339
+ )))), /* @__PURE__ */ React4.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Collections", style: { width: "100%" }, onClick: handleGenerateCollections }), /* @__PURE__ */ React4.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Pairs", style: { width: "100%" }, onClick: handleGeneratePairs })) : /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React4.createElement(Spinner2, null), /* @__PURE__ */ React4.createElement(Text4, { muted: true, size: 1 }, status))));
2263
1340
  };
2264
1341
 
2265
1342
  // src/components/UpdateScriptsComponent.jsx
2266
- import React6, { useState as useState4, useCallback as useCallback3, useRef as useRef2, useEffect as useEffect2 } from "react";
2267
- import { Stack as Stack4, Text as Text6, Button as Button4 } from "@sanity/ui";
1343
+ import React5, { useState as useState4, useCallback as useCallback3, useRef as useRef2, useEffect as useEffect2 } from "react";
1344
+ import { Stack as Stack4, Text as Text5, Button as Button4 } from "@sanity/ui";
2268
1345
  import { useFormValue as useFormValue4, set } from "sanity";
2269
1346
  var UpdateScriptsComponent = (props) => {
2270
1347
  const { onChange } = props;
@@ -2306,7 +1383,7 @@ var UpdateScriptsComponent = (props) => {
2306
1383
  if (isReadyRef.current) onChange(set(newScripts));
2307
1384
  setMessage("Scripts updated");
2308
1385
  }, [onChange, fonts, client]);
2309
- return /* @__PURE__ */ React6.createElement(Stack4, { space: 3 }, /* @__PURE__ */ React6.createElement(
1386
+ return /* @__PURE__ */ React5.createElement(Stack4, { space: 3 }, /* @__PURE__ */ React5.createElement(
2310
1387
  Button4,
2311
1388
  {
2312
1389
  mode: "ghost",
@@ -2315,16 +1392,14 @@ var UpdateScriptsComponent = (props) => {
2315
1392
  text: "Update Scripts from Font Files",
2316
1393
  onClick: updateFromFonts
2317
1394
  }
2318
- ), message && /* @__PURE__ */ React6.createElement(Text6, { size: 1, style: { color: "green" } }, message), props.renderDefault(props));
1395
+ ), message && /* @__PURE__ */ React5.createElement(Text5, { size: 1, style: { color: "green" } }, message), props.renderDefault(props));
2319
1396
  };
2320
1397
 
2321
1398
  // src/components/SingleUploaderTool.jsx
2322
- import React7, { useState as useState5, useEffect as useEffect3, useCallback as useCallback4, useMemo as useMemo3 } from "react";
2323
- import { Button as Button5, Grid as Grid3, Stack as Stack5, Flex as Flex5, Box as Box3, Text as Text7, Card as Card3 } from "@sanity/ui";
1399
+ import React6, { useState as useState5, useEffect as useEffect3, useCallback as useCallback4, useMemo as useMemo3 } from "react";
1400
+ import { Button as Button5, Grid as Grid3, Stack as Stack5, Flex as Flex4, Box as Box3, Text as Text6, Card as Card3 } from "@sanity/ui";
2324
1401
  import { TrashIcon as TrashIcon2, ControlsIcon as ControlsIcon2 } from "@sanity/icons";
2325
1402
  import { useFormValue as useFormValue5, set as set2, unset } from "sanity";
2326
- import { Buffer as Buffer3 } from "buffer";
2327
- import * as fontkit5 from "fontkit";
2328
1403
 
2329
1404
  // src/utils/generateFontFile.js
2330
1405
  async function generateFontFile({
@@ -2558,7 +1633,7 @@ var SingleUploaderTool = (props) => {
2558
1633
  );
2559
1634
  if (!(ttfAsset == null ? void 0 : ttfAsset.url)) throw new Error("Could not fetch TTF file URL");
2560
1635
  const arrayBuffer = await (await fetch(ttfAsset.url)).arrayBuffer();
2561
- const font = fontkit5.create(Buffer3.from(arrayBuffer));
1636
+ const font = await parseFont(arrayBuffer, `${doc_id}.ttf`);
2562
1637
  const { weightName, subfamilyName, style, variableFont } = extractFontMetadata(
2563
1638
  font,
2564
1639
  doc_typefaceName,
@@ -2715,7 +1790,7 @@ var SingleUploaderTool = (props) => {
2715
1790
  }
2716
1791
  if (code === "ttf") {
2717
1792
  const fontBuffer = await readFontFile(file);
2718
- const font = fontkit5.create(fontBuffer);
1793
+ const font = await parseFont(fontBuffer, file.name);
2719
1794
  const { weightName, subfamilyName, style, variableFont } = extractFontMetadata(
2720
1795
  font,
2721
1796
  doc_typefaceName,
@@ -2863,26 +1938,26 @@ var SingleUploaderTool = (props) => {
2863
1938
  const formatUpper = format.toUpperCase();
2864
1939
  const hasFile = !!((_b2 = (_a2 = fileInput == null ? void 0 : fileInput[format]) == null ? void 0 : _a2.asset) == null ? void 0 : _b2._ref);
2865
1940
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${fileInput[format].asset._ref.replace("file-", "").replace("-", ".")}` : null;
2866
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, formatUpper), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames[format]) || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, buildSource && (fileInput == null ? void 0 : fileInput[buildSource]) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontFile(format, fileInput[buildSource]), text: "Build" }), /* @__PURE__ */ React7.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "Upload"), /* @__PURE__ */ React7.createElement("input", { ref, type: "file", hidden: true, onChange: (e) => handleUpload(e, format) })), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete(format) }))));
1941
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, formatUpper), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames[format]) || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, buildSource && (fileInput == null ? void 0 : fileInput[buildSource]) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontFile(format, fileInput[buildSource]), text: "Build" }), /* @__PURE__ */ React6.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "Upload"), /* @__PURE__ */ React6.createElement("input", { ref, type: "file", hidden: true, onChange: (e) => handleUpload(e, format) })), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete(format) }))));
2867
1942
  };
2868
1943
  const renderTopLevelAssetSection = (label, fieldName, assetRef, filename, onBuild) => {
2869
1944
  const hasFile = !!assetRef;
2870
1945
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${assetRef.replace("file-", "").replace("-", ".")}` : null;
2871
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, label), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, filename || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, onBuild && (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: onBuild, text: "Build" }), /* @__PURE__ */ React7.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "Upload"), /* @__PURE__ */ React7.createElement("input", { type: "file", hidden: true, onChange: (e) => handleUploadTopLevelFile(e, fieldName) })), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDeleteTopLevel(fieldName) }))));
1946
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, label), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, filename || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, onBuild && (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: onBuild, text: "Build" }), /* @__PURE__ */ React6.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "Upload"), /* @__PURE__ */ React6.createElement("input", { type: "file", hidden: true, onChange: (e) => handleUploadTopLevelFile(e, fieldName) })), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDeleteTopLevel(fieldName) }))));
2872
1947
  };
2873
1948
  const renderCssSection = () => {
2874
1949
  var _a2, _b2;
2875
1950
  const hasFile = !!((_b2 = (_a2 = fileInput == null ? void 0 : fileInput.css) == null ? void 0 : _a2.asset) == null ? void 0 : _b2._ref);
2876
1951
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${fileInput.css.asset._ref.replace("file-", "").replace("-", ".")}` : null;
2877
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, "CSS"), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames.css) || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateCssFile(), text: "Build" }), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete("css") }))));
1952
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, "CSS"), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames.css) || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateCssFile(), text: "Build" }), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete("css") }))));
2878
1953
  };
2879
- const renderDataSection = () => /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: (doc_metaData == null ? void 0 : doc_metaData.version) ? 1 : 0.5 } }, "DATA"), (doc_metaData == null ? void 0 : doc_metaData.version) ? /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "v", doc_metaData.version, " ", /* @__PURE__ */ React7.createElement(Text7, { as: "span", size: 1, muted: true }, "(", doc_metaData.genDate, ")")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontData(), text: "Build" }))));
2880
- return /* @__PURE__ */ React7.createElement(Stack5, { space: 2 }, /* @__PURE__ */ React7.createElement(
1954
+ const renderDataSection = () => /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: (doc_metaData == null ? void 0 : doc_metaData.version) ? 1 : 0.5 } }, "DATA"), (doc_metaData == null ? void 0 : doc_metaData.version) ? /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "v", doc_metaData.version, " ", /* @__PURE__ */ React6.createElement(Text6, { as: "span", size: 1, muted: true }, "(", doc_metaData.genDate, ")")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontData(), text: "Build" }))));
1955
+ return /* @__PURE__ */ React6.createElement(Stack5, { space: 2 }, /* @__PURE__ */ React6.createElement(
2881
1956
  StatusDisplay_default,
2882
1957
  {
2883
1958
  status,
2884
1959
  error,
2885
- action: /* @__PURE__ */ React7.createElement(
1960
+ action: /* @__PURE__ */ React6.createElement(
2886
1961
  Button5,
2887
1962
  {
2888
1963
  mode: "bleed",
@@ -2894,7 +1969,7 @@ var SingleUploaderTool = (props) => {
2894
1969
  }
2895
1970
  )
2896
1971
  }
2897
- ), renderFontSection("ttf"), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React7.createElement(Grid3, { columns: [1, 2], gap: 2 }, /* @__PURE__ */ React7.createElement(
1972
+ ), renderFontSection("ttf"), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React6.createElement(Grid3, { columns: [1, 2], gap: 2 }, /* @__PURE__ */ React6.createElement(
2898
1973
  Button5,
2899
1974
  {
2900
1975
  mode: "ghost",
@@ -2903,7 +1978,7 @@ var SingleUploaderTool = (props) => {
2903
1978
  text: "Rebuild All from TTF",
2904
1979
  style: { width: "100%" }
2905
1980
  }
2906
- ), /* @__PURE__ */ React7.createElement(
1981
+ ), /* @__PURE__ */ React6.createElement(
2907
1982
  Button5,
2908
1983
  {
2909
1984
  mode: "ghost",
@@ -2923,19 +1998,18 @@ var SingleUploaderTool = (props) => {
2923
1998
  text: "Build Missing",
2924
1999
  style: { width: "100%" }
2925
2000
  }
2926
- )), renderFontSection("otf", "woff"), renderFontSection("woff", "ttf"), renderFontSection("woff2", "ttf"), showAdvanced && renderTopLevelAssetSection("WEB", "woff2_web", (_b = (_a = fileInput == null ? void 0 : fileInput.woff2_web) == null ? void 0 : _a.asset) == null ? void 0 : _b._ref, filenames == null ? void 0 : filenames.woff2_web, handleGenerateSubsetAndWeb), showAdvanced && renderTopLevelAssetSection("SUBSET", "woff2_subset", (_d = (_c = fileInput == null ? void 0 : fileInput.woff2_subset) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref, filenames == null ? void 0 : filenames.woff2_subset, handleGenerateSubsetAndWeb), showAdvanced && renderFontSection("eot", "ttf"), showAdvanced && renderFontSection("svg", "ttf"), renderCssSection(), showAdvanced && renderDataSection(), status === "ready" && ((fileInput == null ? void 0 : fileInput.ttf) || (fileInput == null ? void 0 : fileInput.otf) || (fileInput == null ? void 0 : fileInput.woff) || (fileInput == null ? void 0 : fileInput.woff2)) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(), text: "Delete All", style: { width: "100%" } }));
2001
+ )), renderFontSection("otf", "woff"), renderFontSection("woff", "ttf"), renderFontSection("woff2", "ttf"), showAdvanced && renderTopLevelAssetSection("WEB", "woff2_web", (_b = (_a = fileInput == null ? void 0 : fileInput.woff2_web) == null ? void 0 : _a.asset) == null ? void 0 : _b._ref, filenames == null ? void 0 : filenames.woff2_web, handleGenerateSubsetAndWeb), showAdvanced && renderTopLevelAssetSection("SUBSET", "woff2_subset", (_d = (_c = fileInput == null ? void 0 : fileInput.woff2_subset) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref, filenames == null ? void 0 : filenames.woff2_subset, handleGenerateSubsetAndWeb), showAdvanced && renderFontSection("eot", "ttf"), showAdvanced && renderFontSection("svg", "ttf"), renderCssSection(), showAdvanced && renderDataSection(), status === "ready" && ((fileInput == null ? void 0 : fileInput.ttf) || (fileInput == null ? void 0 : fileInput.otf) || (fileInput == null ? void 0 : fileInput.woff) || (fileInput == null ? void 0 : fileInput.woff2)) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(), text: "Delete All", style: { width: "100%" } }));
2927
2002
  };
2928
2003
 
2929
2004
  // src/components/UploadScriptsComponent.jsx
2930
- import React9, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo4, useState as useState6 } from "react";
2931
- import { Button as Button6, Flex as Flex6, Grid as Grid4, Stack as Stack6, Text as Text8, TextInput, MenuButton, Menu, MenuItem, Select } from "@sanity/ui";
2932
- import * as fontkit6 from "fontkit";
2933
- import slugify3 from "slugify";
2005
+ import React8, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo4, useState as useState6 } from "react";
2006
+ import { Button as Button6, Flex as Flex5, Grid as Grid4, Stack as Stack6, Text as Text7, TextInput, MenuButton, Menu, MenuItem, Select } from "@sanity/ui";
2007
+ import slugify2 from "slugify";
2934
2008
  import { useFormValue as useFormValue6 } from "sanity";
2935
- import { nanoid as nanoid7 } from "nanoid";
2009
+ import { nanoid as nanoid4 } from "nanoid";
2936
2010
 
2937
2011
  // src/utils/utils.js
2938
- import React8 from "react";
2012
+ import React7 from "react";
2939
2013
  var HtmlDescription = ({ children }) => {
2940
2014
  return children || "";
2941
2015
  };
@@ -2953,8 +2027,8 @@ var UploadScriptsComponent = (props) => {
2953
2027
  const { elementProps: { ref } } = props;
2954
2028
  const client = useSanityClient();
2955
2029
  const [selectedScript, setSelectedScript] = useState6("");
2956
- const [status, setStatus] = React9.useState("");
2957
- const [ready, setReady] = React9.useState(true);
2030
+ const [status, setStatus] = React8.useState("");
2031
+ const [ready, setReady] = React8.useState(true);
2958
2032
  let doc_id = useFormValue6(["_id"]);
2959
2033
  const title = useFormValue6(["title"]);
2960
2034
  const slug = useFormValue6(["slug"]);
@@ -2978,7 +2052,6 @@ var UploadScriptsComponent = (props) => {
2978
2052
  });
2979
2053
  };
2980
2054
  const handleUpload = useCallback5(async (event, script) => {
2981
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
2982
2055
  setReady(false);
2983
2056
  try {
2984
2057
  let failedFiles = [];
@@ -2995,21 +2068,22 @@ var UploadScriptsComponent = (props) => {
2995
2068
  for (var i = 0; i < event.target.files.length; i++) {
2996
2069
  const file = event.target.files[i];
2997
2070
  const fontBuffer = await readFontFile3(file);
2998
- const font = fontkit6.create(fontBuffer);
2999
- console.log("reading font : ", font.fullName + " " + file.name, font.name.records);
3000
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) ? (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.preferredSubfamily : (_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fontSubfamily;
3001
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
3002
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").trim();
3003
- if ((weightName == "" || weightName.toLowerCase() == "roman") && ((_h = (_g = font == null ? void 0 : font.name) == null ? void 0 : _g.records) == null ? void 0 : _h.fullName)) {
3004
- weightName = (_j = (_i = font == null ? void 0 : font.name) == null ? void 0 : _i.records) == null ? void 0 : _j.fullName;
3005
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
3006
- weightName = weightName == null ? void 0 : weightName.replace(title + " ", "").replace(title, "").trim();
3007
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").trim();
2071
+ const font = await parseFont(fontBuffer, file.name);
2072
+ const fullName = getNameString(font, 4);
2073
+ const familyName = getNameString(font, 1);
2074
+ console.log("Reading font:", fullName, file.name);
2075
+ let weightName = getNameString(font, 17) || getNameString(font, 2) || "";
2076
+ weightName = weightName.replace("Italic", "").replace("It", "").trim();
2077
+ if ((weightName == "" || weightName.toLowerCase() == "roman") && fullName) {
2078
+ weightName = fullName.replace(title + " ", "").replace(title, "").trim();
2079
+ weightName = weightName.replace("Italic", "").replace("It", "").trim();
3008
2080
  }
3009
- let variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0 ? true : false;
3010
- let subfamilyName = font.familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
3011
- let fontTitle = font == null ? void 0 : font.fullName;
3012
- let style = (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular";
2081
+ const axes = getVariationAxes(font);
2082
+ let variableFont = axes !== null;
2083
+ let subfamilyName = familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
2084
+ let fontTitle = fullName;
2085
+ const italicAngle = getItalicAngle(font);
2086
+ let style = italicAngle !== 0 || fullName.toLowerCase().includes("italic") ? "Italic" : "Regular";
3013
2087
  if (fontTitle.toLowerCase().trim().includes(script)) {
3014
2088
  fontTitle = fontTitle.toLowerCase().trim().replace(script, "").trim();
3015
2089
  fontTitle = fontTitle.split(" ").map((word) => {
@@ -3048,13 +2122,13 @@ var UploadScriptsComponent = (props) => {
3048
2122
  fontTitle = fontTitle + italicKW.join(" ");
3049
2123
  style = "Italic";
3050
2124
  }
3051
- let id = slugify3(fontTitle.toLowerCase().trim());
2125
+ let id = slugify2(fontTitle.toLowerCase().trim());
3052
2126
  console.log("=== Font Info ====");
3053
2127
  console.log(" ");
3054
2128
  console.log("font id : ", id);
3055
2129
  console.log("font title : ", fontTitle);
3056
- console.log("fontkit fullName : ", font.fullName);
3057
- console.log("fontkit family name: ", font.familyName);
2130
+ console.log("Full name:", fullName);
2131
+ console.log("Family name:", familyName);
3058
2132
  console.log("file name : ", file.name);
3059
2133
  console.log("subfamily : ", subfamilyName);
3060
2134
  console.log("style : ", style);
@@ -3068,18 +2142,17 @@ var UploadScriptsComponent = (props) => {
3068
2142
  fontsObjects[id].files = [...fontsObjects[id].files, file];
3069
2143
  } else {
3070
2144
  let fontObject = {
3071
- _key: nanoid7(),
2145
+ _key: nanoid4(),
3072
2146
  _id: id,
3073
2147
  title: fontTitle,
3074
2148
  slug: { _type: "slug", current: id },
3075
2149
  typefaceName: title,
3076
2150
  // Change to match Typeface Document
3077
- style: (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular",
2151
+ style,
3078
2152
  variableFont,
3079
2153
  weightName,
3080
2154
  normalWeight: true,
3081
- // TODO : check if weight is normal ??
3082
- weight: ((_k = font["OS/2"]) == null ? void 0 : _k.usWeightClass) ? Number((_l = font["OS/2"]) == null ? void 0 : _l.usWeightClass) : /hairline|extra thin|extrathin/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 100 : /thin|extra light|extralight/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 200 : /light|book/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 300 : /regular|normal/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 400 : /medium/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 500 : /semi bold|semibold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 600 : /bold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 700 : /extra bold|extrabold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 800 : /black|ultra/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 900 : 400,
2155
+ weight: getWeightClass(font) || (/hairline|extra thin|extrathin/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 100 : /thin|extra light|extralight/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 200 : /light|book/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 300 : /regular|normal/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 400 : /medium/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 500 : /semi bold|semibold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 600 : /bold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 700 : /extra bold|extrabold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 800 : /black|ultra/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 900 : 400),
3083
2156
  files: [file],
3084
2157
  fontKit: font,
3085
2158
  scriptFileInput: { [script]: {} }
@@ -3181,7 +2254,7 @@ var UploadScriptsComponent = (props) => {
3181
2254
  fontResponse = await client.patch(font._id).set({ scriptFileInput: font.scriptFileInput }).commit();
3182
2255
  } else {
3183
2256
  fontResponse = await client.createOrReplace({
3184
- _key: nanoid7(),
2257
+ _key: nanoid4(),
3185
2258
  _id: font._id,
3186
2259
  _type: "font",
3187
2260
  ...font
@@ -3194,7 +2267,7 @@ var UploadScriptsComponent = (props) => {
3194
2267
  })];
3195
2268
  continue;
3196
2269
  }
3197
- const fontRef = { _key: nanoid7(), _type: "reference", _ref: fontResponse._id, _weak: true };
2270
+ const fontRef = { _key: nanoid4(), _type: "reference", _ref: fontResponse._id, _weak: true };
3198
2271
  console.log("font response : ", fontResponse);
3199
2272
  console.log("existing styles object : ", stylesObject);
3200
2273
  if (!font.variableFont) {
@@ -3262,8 +2335,8 @@ var UploadScriptsComponent = (props) => {
3262
2335
  console.log("failed files : ", failedFiles);
3263
2336
  const names = failedFiles.map((file) => file.name);
3264
2337
  console.log("names : ", failedFiles.map((file) => {
3265
- var _a2, _b2;
3266
- return (_b2 = (_a2 = file == null ? void 0 : file.fk) == null ? void 0 : _a2.name) == null ? void 0 : _b2.records;
2338
+ var _a, _b;
2339
+ return (_b = (_a = file == null ? void 0 : file.fk) == null ? void 0 : _a.name) == null ? void 0 : _b.records;
3267
2340
  }));
3268
2341
  setStatus("fonts uploaded with errors. Failed files : " + names.join(", "));
3269
2342
  } else {
@@ -3276,26 +2349,26 @@ var UploadScriptsComponent = (props) => {
3276
2349
  }
3277
2350
  setReady(true);
3278
2351
  }, [title, slug, doc_id]);
3279
- return /* @__PURE__ */ React9.createElement(Stack6, null, !ready && /* @__PURE__ */ React9.createElement(Text8, null, /* @__PURE__ */ React9.createElement("br", null), status, /* @__PURE__ */ React9.createElement("br", null), /* @__PURE__ */ React9.createElement("br", null)), ready && /* @__PURE__ */ React9.createElement(Stack6, null, /* @__PURE__ */ React9.createElement(Grid4, { columns: !!(selectedScript && selectedScript !== "") ? 2 : 1, gap: 2 }, /* @__PURE__ */ React9.createElement(
2352
+ return /* @__PURE__ */ React8.createElement(Stack6, null, !ready && /* @__PURE__ */ React8.createElement(Text7, null, /* @__PURE__ */ React8.createElement("br", null), status, /* @__PURE__ */ React8.createElement("br", null), /* @__PURE__ */ React8.createElement("br", null)), ready && /* @__PURE__ */ React8.createElement(Stack6, null, /* @__PURE__ */ React8.createElement(Grid4, { columns: !!(selectedScript && selectedScript !== "") ? 2 : 1, gap: 2 }, /* @__PURE__ */ React8.createElement(
3280
2353
  Select,
3281
2354
  {
3282
2355
  id: "menu-button-example",
3283
2356
  onChange: (e) => setSelectedScript(e.target.value)
3284
2357
  },
3285
- /* @__PURE__ */ React9.createElement("option", { key: "script-none", value: "" }, " "),
2358
+ /* @__PURE__ */ React8.createElement("option", { key: "script-none", value: "" }, " "),
3286
2359
  SCRIPTS.map(
3287
2360
  (script, i) => {
3288
2361
  var _a;
3289
- return /* @__PURE__ */ React9.createElement("option", { key: "script-" + i, value: script }, ((_a = script[0]) == null ? void 0 : _a.toUpperCase()) + script.slice(1));
2362
+ return /* @__PURE__ */ React8.createElement("option", { key: "script-" + i, value: script }, ((_a = script[0]) == null ? void 0 : _a.toUpperCase()) + script.slice(1));
3290
2363
  }
3291
2364
  )
3292
- ), !!(selectedScript && selectedScript !== "") && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("label", { htmlFor: "upload-scripts-file" }, /* @__PURE__ */ React9.createElement(
2365
+ ), !!(selectedScript && selectedScript !== "") && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("label", { htmlFor: "upload-scripts-file" }, /* @__PURE__ */ React8.createElement(
3293
2366
  Button6,
3294
2367
  {
3295
2368
  style: { pointerEvents: "none" },
3296
2369
  text: "Upload (ttf/otf/woff/woff2/etc..)"
3297
2370
  }
3298
- )), /* @__PURE__ */ React9.createElement(
2371
+ )), /* @__PURE__ */ React8.createElement(
3299
2372
  "input",
3300
2373
  {
3301
2374
  ref,
@@ -3310,8 +2383,8 @@ var UploadScriptsComponent = (props) => {
3310
2383
  };
3311
2384
 
3312
2385
  // src/components/FontScriptUploaderComponent.jsx
3313
- import React10, { useState as useState7, useEffect as useEffect5, useCallback as useCallback6 } from "react";
3314
- import { Stack as Stack7, Flex as Flex7, Text as Text9, Button as Button7 } from "@sanity/ui";
2386
+ import React9, { useState as useState7, useEffect as useEffect5, useCallback as useCallback6 } from "react";
2387
+ import { Stack as Stack7, Flex as Flex6, Text as Text8, Button as Button7 } from "@sanity/ui";
3315
2388
  import { useFormValue as useFormValue7, set as set3, unset as unset2 } from "sanity";
3316
2389
  var FontScriptUploaderComponent = (props) => {
3317
2390
  const client = useSanityClient();
@@ -3519,17 +2592,17 @@ var FontScriptUploaderComponent = (props) => {
3519
2592
  }
3520
2593
  }
3521
2594
  }, [scriptFileInput]);
3522
- return /* @__PURE__ */ React10.createElement(Stack7, { space: 4 }, SCRIPTS && scriptFileInput && SCRIPTS.map((language, i) => {
2595
+ return /* @__PURE__ */ React9.createElement(Stack7, { space: 4 }, SCRIPTS && scriptFileInput && SCRIPTS.map((language, i) => {
3523
2596
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga;
3524
- return /* @__PURE__ */ React10.createElement(Stack7, { space: 2, key: "language-" + i, style: { borderBottom: "1px solid var(--card-border-color)", paddingBottom: 8 } }, /* @__PURE__ */ React10.createElement(Flex7, { gap: 2 }, /* @__PURE__ */ React10.createElement(Text9, { weight: "semibold" }, ((_a = language[0]) == null ? void 0 : _a.toUpperCase()) + language.slice(1)), message && message[language] && message[language] !== "" && /* @__PURE__ */ React10.createElement(Text9, { style: { color: "green" } }, message[language])), expanded[language] && /* @__PURE__ */ React10.createElement(Stack7, { space: 2 }, /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "TTF:\xA0", !((_d = (_c = (_b = scriptFileInput[language]) == null ? void 0 : _b.ttf) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref) ? ((_e = filenames[language]) == null ? void 0 : _e.ttf) ? /* @__PURE__ */ React10.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_h = (_g = (_f = scriptFileInput[language]) == null ? void 0 : _f.ttf) == null ? void 0 : _g.asset) == null ? void 0 : _h._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_i = filenames[language]) == null ? void 0 : _i.ttf) ? /* @__PURE__ */ React10.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: (event) => handleUpload(event, language, "ttf") })), ((_j = value[language]) == null ? void 0 : _j.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("ttf", language) }, "\xD7"))), status === "ready" && ((_k = value[language]) == null ? void 0 : _k.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("all", value[language].ttf, language) }, "Regenerate Files from TTF"), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "OTF:\xA0", !((_n = (_m = (_l = scriptFileInput[language]) == null ? void 0 : _l.otf) == null ? void 0 : _m.asset) == null ? void 0 : _n._ref) ? ((_o = filenames[language]) == null ? void 0 : _o.otf) ? /* @__PURE__ */ React10.createElement("b", null, (_p = filenames[language]) == null ? void 0 : _p.otf) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_s = (_r = (_q = scriptFileInput[language]) == null ? void 0 : _q.otf) == null ? void 0 : _r.asset) == null ? void 0 : _s._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_t = filenames[language]) == null ? void 0 : _t.otf) ? /* @__PURE__ */ React10.createElement("b", null, (_u = filenames[language]) == null ? void 0 : _u.otf) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_v = value[language]) == null ? void 0 : _v.woff) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("otf", value[language].woff, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "otf") })), ((_w = value[language]) == null ? void 0 : _w.otf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("otf", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "WOFF:\xA0", !((_z = (_y = (_x = scriptFileInput[language]) == null ? void 0 : _x.woff) == null ? void 0 : _y.asset) == null ? void 0 : _z._ref) ? ((_A = filenames[language]) == null ? void 0 : _A.woff) ? /* @__PURE__ */ React10.createElement("b", null, (_B = filenames[language]) == null ? void 0 : _B.woff) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_E = (_D = (_C = scriptFileInput[language]) == null ? void 0 : _C.woff) == null ? void 0 : _D.asset) == null ? void 0 : _E._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_F = filenames[language]) == null ? void 0 : _F.woff) ? /* @__PURE__ */ React10.createElement("b", null, (_G = filenames[language]) == null ? void 0 : _G.woff) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_H = value[language]) == null ? void 0 : _H.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff") })), ((_I = value[language]) == null ? void 0 : _I.woff) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "WOFF2:\xA0", !((_L = (_K = (_J = scriptFileInput[language]) == null ? void 0 : _J.woff2) == null ? void 0 : _K.asset) == null ? void 0 : _L._ref) ? ((_M = filenames[language]) == null ? void 0 : _M.woff2) ? /* @__PURE__ */ React10.createElement("b", null, (_N = filenames[language]) == null ? void 0 : _N.woff2) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_Q = (_P = (_O = scriptFileInput[language]) == null ? void 0 : _O.woff2) == null ? void 0 : _P.asset) == null ? void 0 : _Q._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_R = filenames[language]) == null ? void 0 : _R.woff2) ? /* @__PURE__ */ React10.createElement("b", null, (_S = filenames[language]) == null ? void 0 : _S.woff2) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_T = value[language]) == null ? void 0 : _T.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff2", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff2") })), ((_U = value[language]) == null ? void 0 : _U.woff2) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff2", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "EOT:\xA0", !((_X = (_W = (_V = scriptFileInput[language]) == null ? void 0 : _V.eot) == null ? void 0 : _W.asset) == null ? void 0 : _X._ref) ? ((_Y = filenames[language]) == null ? void 0 : _Y.eot) ? /* @__PURE__ */ React10.createElement("b", null, (_Z = filenames[language]) == null ? void 0 : _Z.eot) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_aa = (_$ = (__ = scriptFileInput[language]) == null ? void 0 : __.eot) == null ? void 0 : _$.asset) == null ? void 0 : _aa._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_ba = filenames[language]) == null ? void 0 : _ba.eot) ? /* @__PURE__ */ React10.createElement("b", null, (_ca = filenames[language]) == null ? void 0 : _ca.eot) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_da = value[language]) == null ? void 0 : _da.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("eot", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "eot") })), ((_ea = value[language]) == null ? void 0 : _ea.eot) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("eot", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "SVG:\xA0", !((_ha = (_ga = (_fa = scriptFileInput[language]) == null ? void 0 : _fa.svg) == null ? void 0 : _ga.asset) == null ? void 0 : _ha._ref) ? ((_ia = filenames[language]) == null ? void 0 : _ia.svg) ? /* @__PURE__ */ React10.createElement("b", null, (_ja = filenames[language]) == null ? void 0 : _ja.svg) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ma = (_la = (_ka = scriptFileInput[language]) == null ? void 0 : _ka.svg) == null ? void 0 : _la.asset) == null ? void 0 : _ma._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_na = filenames[language]) == null ? void 0 : _na.svg) ? /* @__PURE__ */ React10.createElement("b", null, (_oa = filenames[language]) == null ? void 0 : _oa.svg) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_pa = value[language]) == null ? void 0 : _pa.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("svg", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "svg") })), ((_qa = value[language]) == null ? void 0 : _qa.svg) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("svg", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "CSS:\xA0", !((_ta = (_sa = (_ra = scriptFileInput[language]) == null ? void 0 : _ra.css) == null ? void 0 : _sa.asset) == null ? void 0 : _ta._ref) ? ((_ua = filenames[language]) == null ? void 0 : _ua.css) ? /* @__PURE__ */ React10.createElement("b", null, (_va = filenames[language]) == null ? void 0 : _va.css) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ya = (_xa = (_wa = scriptFileInput[language]) == null ? void 0 : _wa.css) == null ? void 0 : _xa.asset) == null ? void 0 : _ya._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_za = filenames[language]) == null ? void 0 : _za.css) ? /* @__PURE__ */ React10.createElement("b", null, (_Aa = filenames[language]) == null ? void 0 : _Aa.css) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_Ba = value[language]) == null ? void 0 : _Ba.woff2) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateCssFile(language) }, "Build"), ((_Ca = value[language]) == null ? void 0 : _Ca.css) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("css", language) }, "\xD7"))), status === "ready" && (((_Da = value[language]) == null ? void 0 : _Da.ttf) || ((_Ea = value[language]) == null ? void 0 : _Ea.otf) || ((_Fa = value[language]) == null ? void 0 : _Fa.woff) || ((_Ga = value[language]) == null ? void 0 : _Ga.woff2)) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(language), style: { width: "100%" } }, "Delete All")));
2597
+ return /* @__PURE__ */ React9.createElement(Stack7, { space: 2, key: "language-" + i, style: { borderBottom: "1px solid var(--card-border-color)", paddingBottom: 8 } }, /* @__PURE__ */ React9.createElement(Flex6, { gap: 2 }, /* @__PURE__ */ React9.createElement(Text8, { weight: "semibold" }, ((_a = language[0]) == null ? void 0 : _a.toUpperCase()) + language.slice(1)), message && message[language] && message[language] !== "" && /* @__PURE__ */ React9.createElement(Text8, { style: { color: "green" } }, message[language])), expanded[language] && /* @__PURE__ */ React9.createElement(Stack7, { space: 2 }, /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "TTF:\xA0", !((_d = (_c = (_b = scriptFileInput[language]) == null ? void 0 : _b.ttf) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref) ? ((_e = filenames[language]) == null ? void 0 : _e.ttf) ? /* @__PURE__ */ React9.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_h = (_g = (_f = scriptFileInput[language]) == null ? void 0 : _f.ttf) == null ? void 0 : _g.asset) == null ? void 0 : _h._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_i = filenames[language]) == null ? void 0 : _i.ttf) ? /* @__PURE__ */ React9.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: (event) => handleUpload(event, language, "ttf") })), ((_j = value[language]) == null ? void 0 : _j.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("ttf", language) }, "\xD7"))), status === "ready" && ((_k = value[language]) == null ? void 0 : _k.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("all", value[language].ttf, language) }, "Regenerate Files from TTF"), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "OTF:\xA0", !((_n = (_m = (_l = scriptFileInput[language]) == null ? void 0 : _l.otf) == null ? void 0 : _m.asset) == null ? void 0 : _n._ref) ? ((_o = filenames[language]) == null ? void 0 : _o.otf) ? /* @__PURE__ */ React9.createElement("b", null, (_p = filenames[language]) == null ? void 0 : _p.otf) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_s = (_r = (_q = scriptFileInput[language]) == null ? void 0 : _q.otf) == null ? void 0 : _r.asset) == null ? void 0 : _s._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_t = filenames[language]) == null ? void 0 : _t.otf) ? /* @__PURE__ */ React9.createElement("b", null, (_u = filenames[language]) == null ? void 0 : _u.otf) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_v = value[language]) == null ? void 0 : _v.woff) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("otf", value[language].woff, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "otf") })), ((_w = value[language]) == null ? void 0 : _w.otf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("otf", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "WOFF:\xA0", !((_z = (_y = (_x = scriptFileInput[language]) == null ? void 0 : _x.woff) == null ? void 0 : _y.asset) == null ? void 0 : _z._ref) ? ((_A = filenames[language]) == null ? void 0 : _A.woff) ? /* @__PURE__ */ React9.createElement("b", null, (_B = filenames[language]) == null ? void 0 : _B.woff) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_E = (_D = (_C = scriptFileInput[language]) == null ? void 0 : _C.woff) == null ? void 0 : _D.asset) == null ? void 0 : _E._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_F = filenames[language]) == null ? void 0 : _F.woff) ? /* @__PURE__ */ React9.createElement("b", null, (_G = filenames[language]) == null ? void 0 : _G.woff) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_H = value[language]) == null ? void 0 : _H.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff") })), ((_I = value[language]) == null ? void 0 : _I.woff) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "WOFF2:\xA0", !((_L = (_K = (_J = scriptFileInput[language]) == null ? void 0 : _J.woff2) == null ? void 0 : _K.asset) == null ? void 0 : _L._ref) ? ((_M = filenames[language]) == null ? void 0 : _M.woff2) ? /* @__PURE__ */ React9.createElement("b", null, (_N = filenames[language]) == null ? void 0 : _N.woff2) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_Q = (_P = (_O = scriptFileInput[language]) == null ? void 0 : _O.woff2) == null ? void 0 : _P.asset) == null ? void 0 : _Q._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_R = filenames[language]) == null ? void 0 : _R.woff2) ? /* @__PURE__ */ React9.createElement("b", null, (_S = filenames[language]) == null ? void 0 : _S.woff2) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_T = value[language]) == null ? void 0 : _T.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff2", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff2") })), ((_U = value[language]) == null ? void 0 : _U.woff2) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff2", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "EOT:\xA0", !((_X = (_W = (_V = scriptFileInput[language]) == null ? void 0 : _V.eot) == null ? void 0 : _W.asset) == null ? void 0 : _X._ref) ? ((_Y = filenames[language]) == null ? void 0 : _Y.eot) ? /* @__PURE__ */ React9.createElement("b", null, (_Z = filenames[language]) == null ? void 0 : _Z.eot) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_aa = (_$ = (__ = scriptFileInput[language]) == null ? void 0 : __.eot) == null ? void 0 : _$.asset) == null ? void 0 : _aa._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_ba = filenames[language]) == null ? void 0 : _ba.eot) ? /* @__PURE__ */ React9.createElement("b", null, (_ca = filenames[language]) == null ? void 0 : _ca.eot) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_da = value[language]) == null ? void 0 : _da.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("eot", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "eot") })), ((_ea = value[language]) == null ? void 0 : _ea.eot) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("eot", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "SVG:\xA0", !((_ha = (_ga = (_fa = scriptFileInput[language]) == null ? void 0 : _fa.svg) == null ? void 0 : _ga.asset) == null ? void 0 : _ha._ref) ? ((_ia = filenames[language]) == null ? void 0 : _ia.svg) ? /* @__PURE__ */ React9.createElement("b", null, (_ja = filenames[language]) == null ? void 0 : _ja.svg) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ma = (_la = (_ka = scriptFileInput[language]) == null ? void 0 : _ka.svg) == null ? void 0 : _la.asset) == null ? void 0 : _ma._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_na = filenames[language]) == null ? void 0 : _na.svg) ? /* @__PURE__ */ React9.createElement("b", null, (_oa = filenames[language]) == null ? void 0 : _oa.svg) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_pa = value[language]) == null ? void 0 : _pa.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("svg", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "svg") })), ((_qa = value[language]) == null ? void 0 : _qa.svg) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("svg", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "CSS:\xA0", !((_ta = (_sa = (_ra = scriptFileInput[language]) == null ? void 0 : _ra.css) == null ? void 0 : _sa.asset) == null ? void 0 : _ta._ref) ? ((_ua = filenames[language]) == null ? void 0 : _ua.css) ? /* @__PURE__ */ React9.createElement("b", null, (_va = filenames[language]) == null ? void 0 : _va.css) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ya = (_xa = (_wa = scriptFileInput[language]) == null ? void 0 : _wa.css) == null ? void 0 : _xa.asset) == null ? void 0 : _ya._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_za = filenames[language]) == null ? void 0 : _za.css) ? /* @__PURE__ */ React9.createElement("b", null, (_Aa = filenames[language]) == null ? void 0 : _Aa.css) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_Ba = value[language]) == null ? void 0 : _Ba.woff2) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateCssFile(language) }, "Build"), ((_Ca = value[language]) == null ? void 0 : _Ca.css) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("css", language) }, "\xD7"))), status === "ready" && (((_Da = value[language]) == null ? void 0 : _Da.ttf) || ((_Ea = value[language]) == null ? void 0 : _Ea.otf) || ((_Fa = value[language]) == null ? void 0 : _Fa.woff) || ((_Ga = value[language]) == null ? void 0 : _Ga.woff2)) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(language), style: { width: "100%" } }, "Delete All")));
3525
2598
  }));
3526
2599
  };
3527
2600
 
3528
2601
  // src/components/UploadButton.jsx
3529
- import React11, { forwardRef } from "react";
3530
- import { Button as Button8, Text as Text10 } from "@sanity/ui";
2602
+ import React10, { forwardRef } from "react";
2603
+ import { Button as Button8, Text as Text9 } from "@sanity/ui";
3531
2604
  var UploadButton = forwardRef(({ handleUpload }, ref) => {
3532
- return /* @__PURE__ */ React11.createElement(
2605
+ return /* @__PURE__ */ React10.createElement(
3533
2606
  Button8,
3534
2607
  {
3535
2608
  mode: "ghost",
@@ -3538,8 +2611,8 @@ var UploadButton = forwardRef(({ handleUpload }, ref) => {
3538
2611
  padding: 3,
3539
2612
  style: { position: "relative" }
3540
2613
  },
3541
- /* @__PURE__ */ React11.createElement(Text10, { align: "center" }, "Upload (ttf/otf/woff/woff2/etc...)"),
3542
- /* @__PURE__ */ React11.createElement(
2614
+ /* @__PURE__ */ React10.createElement(Text9, { align: "center" }, "Upload (ttf/otf/woff/woff2/etc...)"),
2615
+ /* @__PURE__ */ React10.createElement(
3543
2616
  "input",
3544
2617
  {
3545
2618
  ref,
@@ -3563,7 +2636,7 @@ UploadButton.displayName = "UploadButton";
3563
2636
  var UploadButton_default = UploadButton;
3564
2637
 
3565
2638
  // src/components/KeyValueInput.jsx
3566
- import React12, { useState as useState8, useCallback as useCallback7 } from "react";
2639
+ import React11, { useState as useState8, useCallback as useCallback7 } from "react";
3567
2640
  import { Button as Button9, Grid as Grid5, Stack as Stack8, TextInput as TextInput2 } from "@sanity/ui";
3568
2641
  import { AddIcon, ArrowDownIcon, ArrowUpIcon, TrashIcon as TrashIcon3 } from "@sanity/icons";
3569
2642
  import { set as set4 } from "sanity";
@@ -3599,37 +2672,37 @@ function KeyValueInput({ value = [], onChange }) {
3599
2672
  setPairs(updatedPairs);
3600
2673
  onChange(set4(updatedPairs));
3601
2674
  }, [pairs, onChange]);
3602
- return /* @__PURE__ */ React12.createElement(Stack8, { space: 3 }, pairs.map((pair, index) => /* @__PURE__ */ React12.createElement(Grid5, { className: "manualButtonWrap", columns: [2], key: index, gap: 0, style: { position: "relative" } }, /* @__PURE__ */ React12.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-10px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React12.createElement(ArrowUpIcon, null)), /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React12.createElement(ArrowDownIcon, null))), /* @__PURE__ */ React12.createElement(
2675
+ return /* @__PURE__ */ React11.createElement(Stack8, { space: 3 }, pairs.map((pair, index) => /* @__PURE__ */ React11.createElement(Grid5, { className: "manualButtonWrap", columns: [2], key: index, gap: 0, style: { position: "relative" } }, /* @__PURE__ */ React11.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-10px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React11.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React11.createElement(ArrowUpIcon, null)), /* @__PURE__ */ React11.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React11.createElement(ArrowDownIcon, null))), /* @__PURE__ */ React11.createElement(
3603
2676
  TextInput2,
3604
2677
  {
3605
2678
  value: pair.key,
3606
2679
  onChange: (e) => handlePairChange(index, "key", e.target.value),
3607
2680
  placeholder: "Key"
3608
2681
  }
3609
- ), /* @__PURE__ */ React12.createElement("div", { style: { marginLeft: "-1px" } }, /* @__PURE__ */ React12.createElement(
2682
+ ), /* @__PURE__ */ React11.createElement("div", { style: { marginLeft: "-1px" } }, /* @__PURE__ */ React11.createElement(
3610
2683
  TextInput2,
3611
2684
  {
3612
2685
  value: pair.value,
3613
2686
  onChange: (e) => handlePairChange(index, "value", e.target.value),
3614
2687
  placeholder: "Value"
3615
2688
  }
3616
- )), /* @__PURE__ */ React12.createElement(
2689
+ )), /* @__PURE__ */ React11.createElement(
3617
2690
  "button",
3618
2691
  {
3619
2692
  className: "manualButton",
3620
2693
  onClick: () => handleRemovePair(index),
3621
2694
  style: { position: "absolute", top: "0", right: "-10px", transform: "translate(100%, 0%)" }
3622
2695
  },
3623
- /* @__PURE__ */ React12.createElement(TrashIcon3, null)
3624
- ))), /* @__PURE__ */ React12.createElement(Button9, { tone: "primary", onClick: handleAddPair, icon: AddIcon, text: "Add Row" }));
2696
+ /* @__PURE__ */ React11.createElement(TrashIcon3, null)
2697
+ ))), /* @__PURE__ */ React11.createElement(Button9, { tone: "primary", onClick: handleAddPair, icon: AddIcon, text: "Add Row" }));
3625
2698
  }
3626
2699
 
3627
2700
  // src/components/KeyValueReferenceInput.jsx
3628
- import React13, { useState as useState9, useCallback as useCallback8, useEffect as useEffect6 } from "react";
3629
- import { Button as Button10, Stack as Stack9, TextInput as TextInput3, Box as Box4, Card as Card4, Flex as Flex8, Text as Text11, Dialog, Menu as Menu2, MenuButton as MenuButton2, MenuItem as MenuItem2, Autocomplete } from "@sanity/ui";
2701
+ import React12, { useState as useState9, useCallback as useCallback8, useEffect as useEffect6 } from "react";
2702
+ import { Button as Button10, Stack as Stack9, TextInput as TextInput3, Box as Box4, Card as Card4, Flex as Flex7, Text as Text10, Dialog, Menu as Menu2, MenuButton as MenuButton2, MenuItem as MenuItem2, Autocomplete } from "@sanity/ui";
3630
2703
  import { AddIcon as AddIcon2, ArrowDownIcon as ArrowDownIcon2, ArrowUpIcon as ArrowUpIcon2, TrashIcon as TrashIcon4, SyncIcon, EllipsisHorizontalIcon } from "@sanity/icons";
3631
2704
  import { set as set5, useFormValue as useFormValue8 } from "sanity";
3632
- import { nanoid as nanoid8 } from "nanoid";
2705
+ import { nanoid as nanoid5 } from "nanoid";
3633
2706
  function KeyValueReferenceInput(props) {
3634
2707
  var _a, _b, _c, _d, _e, _f, _g, _h;
3635
2708
  const { value = [], onChange, schemaType, referenceType, fetchReferences, topActions } = props;
@@ -3675,7 +2748,7 @@ function KeyValueReferenceInput(props) {
3675
2748
  onChange(set5(updatedPairs));
3676
2749
  }, [pairs, onChange]);
3677
2750
  const handleAddPair = useCallback8(() => {
3678
- const updatedPairs = [...pairs, { key: "", value: null, _key: nanoid8() }];
2751
+ const updatedPairs = [...pairs, { key: "", value: null, _key: nanoid5() }];
3679
2752
  setPairs(updatedPairs);
3680
2753
  onChange(set5(updatedPairs));
3681
2754
  }, [pairs, onChange]);
@@ -3736,48 +2809,48 @@ function KeyValueReferenceInput(props) {
3736
2809
  const valueTitle = (valueField == null ? void 0 : valueField.title) || "Value";
3737
2810
  const keyPlaceholder = (keyField == null ? void 0 : keyField.placeholder) || "Enter key";
3738
2811
  const pickerLabel = referenceType || valueTitle.toLowerCase();
3739
- return /* @__PURE__ */ React13.createElement(Stack9, { space: 3 }, topActions && /* @__PURE__ */ React13.createElement(Box4, { paddingBottom: 2 }, topActions), /* @__PURE__ */ React13.createElement(Box4, null, /* @__PURE__ */ React13.createElement(Stack9, { space: 2 }, pairs.map((pair, index) => {
2812
+ return /* @__PURE__ */ React12.createElement(Stack9, { space: 3 }, topActions && /* @__PURE__ */ React12.createElement(Box4, { paddingBottom: 2 }, topActions), /* @__PURE__ */ React12.createElement(Box4, null, /* @__PURE__ */ React12.createElement(Stack9, { space: 2 }, pairs.map((pair, index) => {
3740
2813
  var _a2;
3741
- return /* @__PURE__ */ React13.createElement(Box4, { key: index, style: { position: "relative" } }, /* @__PURE__ */ React13.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-5px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React13.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React13.createElement(ArrowUpIcon2, null)), /* @__PURE__ */ React13.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React13.createElement(ArrowDownIcon2, null))), /* @__PURE__ */ React13.createElement(Flex8, { gap: 2, align: "flex-start" }, /* @__PURE__ */ React13.createElement(Box4, { flex: 1 }, /* @__PURE__ */ React13.createElement(
2814
+ return /* @__PURE__ */ React12.createElement(Box4, { key: index, style: { position: "relative" } }, /* @__PURE__ */ React12.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-5px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React12.createElement(ArrowUpIcon2, null)), /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React12.createElement(ArrowDownIcon2, null))), /* @__PURE__ */ React12.createElement(Flex7, { gap: 2, align: "flex-start" }, /* @__PURE__ */ React12.createElement(Box4, { flex: 1 }, /* @__PURE__ */ React12.createElement(
3742
2815
  TextInput3,
3743
2816
  {
3744
2817
  value: pair.key,
3745
2818
  onChange: (e) => handlePairChange(index, "key", e.target.value),
3746
2819
  placeholder: keyPlaceholder
3747
2820
  }
3748
- )), /* @__PURE__ */ React13.createElement(Box4, { flex: 1, style: { minHeight: "100%" } }, ((_a2 = pair.value) == null ? void 0 : _a2._ref) ? /* @__PURE__ */ React13.createElement(Card4, { className: "referenceCard", radius: 2, tone: "primary", style: { paddingLeft: "1rem", height: "fit-content" } }, /* @__PURE__ */ React13.createElement(Flex8, { align: "center", justify: "space-between" }, /* @__PURE__ */ React13.createElement(
3749
- Text11,
2821
+ )), /* @__PURE__ */ React12.createElement(Box4, { flex: 1, style: { minHeight: "100%" } }, ((_a2 = pair.value) == null ? void 0 : _a2._ref) ? /* @__PURE__ */ React12.createElement(Card4, { className: "referenceCard", radius: 2, tone: "primary", style: { paddingLeft: "1rem", height: "fit-content" } }, /* @__PURE__ */ React12.createElement(Flex7, { align: "center", justify: "space-between" }, /* @__PURE__ */ React12.createElement(
2822
+ Text10,
3750
2823
  {
3751
2824
  size: 2,
3752
2825
  style: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "90%" }
3753
2826
  },
3754
2827
  referenceData[pair.value._ref] || "Loading..."
3755
- ), /* @__PURE__ */ React13.createElement(
2828
+ ), /* @__PURE__ */ React12.createElement(
3756
2829
  MenuButton2,
3757
2830
  {
3758
- button: /* @__PURE__ */ React13.createElement(Button10, { icon: EllipsisHorizontalIcon, mode: "bleed", title: "Options" }),
2831
+ button: /* @__PURE__ */ React12.createElement(Button10, { icon: EllipsisHorizontalIcon, mode: "bleed", title: "Options" }),
3759
2832
  id: `ref-options-${index}`,
3760
- menu: /* @__PURE__ */ React13.createElement(Menu2, null, /* @__PURE__ */ React13.createElement(MenuItem2, { tone: "critical", icon: TrashIcon4, text: "Remove", onClick: () => handlePairChange(index, "value", null) }), /* @__PURE__ */ React13.createElement(MenuItem2, { icon: SyncIcon, text: "Replace", onClick: () => openReferenceSelector(index) })),
2833
+ menu: /* @__PURE__ */ React12.createElement(Menu2, null, /* @__PURE__ */ React12.createElement(MenuItem2, { tone: "critical", icon: TrashIcon4, text: "Remove", onClick: () => handlePairChange(index, "value", null) }), /* @__PURE__ */ React12.createElement(MenuItem2, { icon: SyncIcon, text: "Replace", onClick: () => openReferenceSelector(index) })),
3761
2834
  popover: { portal: true, tone: "default", placement: "left" }
3762
2835
  }
3763
- ))) : /* @__PURE__ */ React13.createElement(
2836
+ ))) : /* @__PURE__ */ React12.createElement(
3764
2837
  Box4,
3765
2838
  {
3766
2839
  padding: 2,
3767
2840
  style: { minHeight: "100%", border: "1px dashed #ccc", borderRadius: "4px", display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" },
3768
2841
  onClick: () => openReferenceSelector(index)
3769
2842
  },
3770
- /* @__PURE__ */ React13.createElement(Text11, { muted: true, size: 2 }, "Click to select a ", pickerLabel)
3771
- ))), /* @__PURE__ */ React13.createElement(
2843
+ /* @__PURE__ */ React12.createElement(Text10, { muted: true, size: 2 }, "Click to select a ", pickerLabel)
2844
+ ))), /* @__PURE__ */ React12.createElement(
3772
2845
  "button",
3773
2846
  {
3774
2847
  className: "manualButton",
3775
2848
  onClick: () => handleRemovePair(index),
3776
2849
  style: { position: "absolute", top: "0", right: "-7px", transform: "translate(100%, 0%)" }
3777
2850
  },
3778
- /* @__PURE__ */ React13.createElement(TrashIcon4, null)
2851
+ /* @__PURE__ */ React12.createElement(TrashIcon4, null)
3779
2852
  ));
3780
- }))), /* @__PURE__ */ React13.createElement(Button10, { tone: "primary", mode: "ghost", onClick: handleAddPair, icon: AddIcon2, text: `Add ${keyTitle}` }), isDialogOpen && /* @__PURE__ */ React13.createElement(
2853
+ }))), /* @__PURE__ */ React12.createElement(Button10, { tone: "primary", mode: "ghost", onClick: handleAddPair, icon: AddIcon2, text: `Add ${keyTitle}` }), isDialogOpen && /* @__PURE__ */ React12.createElement(
3781
2854
  Dialog,
3782
2855
  {
3783
2856
  header: `Select a ${pickerLabel}`,
@@ -3785,13 +2858,13 @@ function KeyValueReferenceInput(props) {
3785
2858
  onClose: closeDialog,
3786
2859
  width: 1
3787
2860
  },
3788
- /* @__PURE__ */ React13.createElement(Box4, { padding: 4 }, /* @__PURE__ */ React13.createElement(
2861
+ /* @__PURE__ */ React12.createElement(Box4, { padding: 4 }, /* @__PURE__ */ React12.createElement(
3789
2862
  Autocomplete,
3790
2863
  {
3791
2864
  id: "reference-autocomplete",
3792
2865
  options: referenceOptions,
3793
2866
  placeholder: `Search ${pickerLabel}s...`,
3794
- renderOption: (option) => /* @__PURE__ */ React13.createElement(Card4, { key: option.value, padding: 3, radius: 2, tone: "default", style: { cursor: "pointer" } }, /* @__PURE__ */ React13.createElement(Text11, { size: 2 }, option.title)),
2867
+ renderOption: (option) => /* @__PURE__ */ React12.createElement(Card4, { key: option.value, padding: 3, radius: 2, tone: "default", style: { cursor: "pointer" } }, /* @__PURE__ */ React12.createElement(Text10, { size: 2 }, option.title)),
3795
2868
  renderValue: (val) => {
3796
2869
  var _a2;
3797
2870
  return ((_a2 = referenceOptions.find((o) => o.value === val)) == null ? void 0 : _a2.title) || "";
@@ -3808,11 +2881,11 @@ function KeyValueReferenceInput(props) {
3808
2881
  }
3809
2882
 
3810
2883
  // src/components/VariableInstanceReferencesInput.jsx
3811
- import React14, { useState as useState10, useCallback as useCallback9 } from "react";
3812
- import { Button as Button11, Flex as Flex9, Dialog as Dialog2, Box as Box5, Stack as Stack10, Text as Text12 } from "@sanity/ui";
2884
+ import React13, { useState as useState10, useCallback as useCallback9 } from "react";
2885
+ import { Button as Button11, Flex as Flex8, Dialog as Dialog2, Box as Box5, Stack as Stack10, Text as Text11 } from "@sanity/ui";
3813
2886
  import { SyncIcon as SyncIcon2, DocumentTextIcon } from "@sanity/icons";
3814
2887
  import { set as set6, useFormValue as useFormValue9 } from "sanity";
3815
- import { nanoid as nanoid9 } from "nanoid";
2888
+ import { nanoid as nanoid6 } from "nanoid";
3816
2889
  function VariableInstanceReferencesInput(props) {
3817
2890
  const { value = [], onChange } = props;
3818
2891
  const [isAutofilling, setIsAutofilling] = useState10(false);
@@ -3869,7 +2942,7 @@ function VariableInstanceReferencesInput(props) {
3869
2942
  console.warn("No variable instances found in JSON");
3870
2943
  return;
3871
2944
  }
3872
- const keyOnlyPairs = keys.map((key) => ({ key, value: null, _key: nanoid9() }));
2945
+ const keyOnlyPairs = keys.map((key) => ({ key, value: null, _key: nanoid6() }));
3873
2946
  const updatedPairs = mode === "replace" ? keyOnlyPairs : [...value, ...keyOnlyPairs.filter((p) => !value.some((existing) => existing.key === p.key))];
3874
2947
  onChange(set6(updatedPairs));
3875
2948
  } catch (err) {
@@ -3905,7 +2978,7 @@ function VariableInstanceReferencesInput(props) {
3905
2978
  setPendingAction(null);
3906
2979
  }, []);
3907
2980
  const showAutofill = !!((formDocument == null ? void 0 : formDocument.variableFont) && (formDocument == null ? void 0 : formDocument.variableInstances));
3908
- const topActions = showAutofill ? /* @__PURE__ */ React14.createElement(Flex9, { gap: 2 }, /* @__PURE__ */ React14.createElement(
2981
+ const topActions = showAutofill ? /* @__PURE__ */ React13.createElement(Flex8, { gap: 2 }, /* @__PURE__ */ React13.createElement(
3909
2982
  Button11,
3910
2983
  {
3911
2984
  tone: "primary",
@@ -3916,7 +2989,7 @@ function VariableInstanceReferencesInput(props) {
3916
2989
  disabled: isAutofilling,
3917
2990
  loading: isAutofilling
3918
2991
  }
3919
- ), /* @__PURE__ */ React14.createElement(
2992
+ ), /* @__PURE__ */ React13.createElement(
3920
2993
  Button11,
3921
2994
  {
3922
2995
  tone: "default",
@@ -3928,7 +3001,7 @@ function VariableInstanceReferencesInput(props) {
3928
3001
  loading: isAutofilling
3929
3002
  }
3930
3003
  )) : null;
3931
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(
3004
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
3932
3005
  KeyValueReferenceInput,
3933
3006
  {
3934
3007
  ...props,
@@ -3936,7 +3009,7 @@ function VariableInstanceReferencesInput(props) {
3936
3009
  fetchReferences,
3937
3010
  topActions
3938
3011
  }
3939
- ), showConfirmDialog && /* @__PURE__ */ React14.createElement(
3012
+ ), showConfirmDialog && /* @__PURE__ */ React13.createElement(
3940
3013
  Dialog2,
3941
3014
  {
3942
3015
  header: "Existing entries found",
@@ -3944,15 +3017,15 @@ function VariableInstanceReferencesInput(props) {
3944
3017
  onClose: handleConfirmCancel,
3945
3018
  width: 1
3946
3019
  },
3947
- /* @__PURE__ */ React14.createElement(Box5, { padding: 4 }, /* @__PURE__ */ React14.createElement(Stack10, { space: 4 }, /* @__PURE__ */ React14.createElement(Text12, null, "You already have ", value.length, " ", value.length === 1 ? "entry" : "entries", ". How would you like to proceed?"), /* @__PURE__ */ React14.createElement(Flex9, { gap: 2, justify: "flex-end" }, /* @__PURE__ */ React14.createElement(Button11, { text: "Cancel", mode: "ghost", onClick: handleConfirmCancel }), /* @__PURE__ */ React14.createElement(Button11, { text: "Merge (Add New)", tone: "primary", mode: "ghost", onClick: () => handleConfirmChoice("merge") }), /* @__PURE__ */ React14.createElement(Button11, { text: "Replace All", tone: "critical", onClick: () => handleConfirmChoice("replace") }))))
3020
+ /* @__PURE__ */ React13.createElement(Box5, { padding: 4 }, /* @__PURE__ */ React13.createElement(Stack10, { space: 4 }, /* @__PURE__ */ React13.createElement(Text11, null, "You already have ", value.length, " ", value.length === 1 ? "entry" : "entries", ". How would you like to proceed?"), /* @__PURE__ */ React13.createElement(Flex8, { gap: 2, justify: "flex-end" }, /* @__PURE__ */ React13.createElement(Button11, { text: "Cancel", mode: "ghost", onClick: handleConfirmCancel }), /* @__PURE__ */ React13.createElement(Button11, { text: "Merge (Add New)", tone: "primary", mode: "ghost", onClick: () => handleConfirmChoice("merge") }), /* @__PURE__ */ React13.createElement(Button11, { text: "Replace All", tone: "critical", onClick: () => handleConfirmChoice("replace") }))))
3948
3021
  ));
3949
3022
  }
3950
3023
 
3951
3024
  // src/components/PrimaryCollectionGeneratorTypeface.jsx
3952
- import React15, { useCallback as useCallback10, useState as useState11 } from "react";
3953
- import { Stack as Stack11, Flex as Flex10, Text as Text13, Button as Button12, Card as Card5, Spinner as Spinner3 } from "@sanity/ui";
3025
+ import React14, { useCallback as useCallback10, useState as useState11 } from "react";
3026
+ import { Stack as Stack11, Flex as Flex9, Text as Text12, Button as Button12, Card as Card5, Spinner as Spinner3 } from "@sanity/ui";
3954
3027
  import { useFormValue as useFormValue10 } from "sanity";
3955
- import { nanoid as nanoid10 } from "nanoid";
3028
+ import { nanoid as nanoid7 } from "nanoid";
3956
3029
  var PrimaryCollectionGeneratorTypeface = () => {
3957
3030
  const client = useSanityClient();
3958
3031
  const [status, setStatus] = useState11("ready");
@@ -3972,7 +3045,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
3972
3045
  if (!id.includes("collection")) id += "-collection";
3973
3046
  const colTitle = id.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
3974
3047
  const collectionDoc = {
3975
- _key: nanoid10(),
3048
+ _key: nanoid7(),
3976
3049
  _id: id,
3977
3050
  title: colTitle,
3978
3051
  slug: { _type: "slug", current: id },
@@ -3990,7 +3063,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
3990
3063
  ...styles,
3991
3064
  collections: [{
3992
3065
  _type: "reference",
3993
- _key: nanoid10(),
3066
+ _key: nanoid7(),
3994
3067
  _ref: sanityCollection._id,
3995
3068
  _weak: true
3996
3069
  }, ...collections]
@@ -4004,7 +3077,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
4004
3077
  setReady(true);
4005
3078
  }, [docId, fonts, price, preferredStyle, styles, title, client]);
4006
3079
  if (!title || !fonts) return null;
4007
- return /* @__PURE__ */ React15.createElement(Stack11, { space: 2 }, /* @__PURE__ */ React15.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React15.createElement(Card5, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React15.createElement(Stack11, { space: 3 }, /* @__PURE__ */ React15.createElement(Flex10, { align: "center", gap: 2, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "Price"), /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "$"), /* @__PURE__ */ React15.createElement(
3080
+ return /* @__PURE__ */ React14.createElement(Stack11, { space: 2 }, /* @__PURE__ */ React14.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React14.createElement(Card5, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React14.createElement(Stack11, { space: 3 }, /* @__PURE__ */ React14.createElement(Flex9, { align: "center", gap: 2, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "Price"), /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "$"), /* @__PURE__ */ React14.createElement(
4008
3081
  "input",
4009
3082
  {
4010
3083
  value: price,
@@ -4012,7 +3085,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
4012
3085
  type: "number",
4013
3086
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
4014
3087
  }
4015
- ), /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "per full family")), /* @__PURE__ */ React15.createElement(
3088
+ ), /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "per full family")), /* @__PURE__ */ React14.createElement(
4016
3089
  Button12,
4017
3090
  {
4018
3091
  mode: "ghost",
@@ -4021,13 +3094,13 @@ var PrimaryCollectionGeneratorTypeface = () => {
4021
3094
  onClick: generateCollection,
4022
3095
  text: "Generate Full Family Collection"
4023
3096
  }
4024
- )) : /* @__PURE__ */ React15.createElement(Flex10, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React15.createElement(Spinner3, null), /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1 }, status))));
3097
+ )) : /* @__PURE__ */ React14.createElement(Flex9, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React14.createElement(Spinner3, null), /* @__PURE__ */ React14.createElement(Text12, { muted: true, size: 1 }, status))));
4025
3098
  };
4026
3099
 
4027
3100
  // src/components/SetOTF.jsx
4028
- import React16, { useState as useState12 } from "react";
3101
+ import React15, { useState as useState12 } from "react";
4029
3102
  import { set as set7, useFormValue as useFormValue11 } from "sanity";
4030
- import { Stack as Stack12, Button as Button13, Text as Text14 } from "@sanity/ui";
3103
+ import { Stack as Stack12, Button as Button13, Text as Text13 } from "@sanity/ui";
4031
3104
  var SetOTF = (props) => {
4032
3105
  var _a, _b;
4033
3106
  const { onChange, value = {} } = props;
@@ -4076,7 +3149,7 @@ var SetOTF = (props) => {
4076
3149
  console.error("SetOTF detect error:", err);
4077
3150
  }
4078
3151
  };
4079
- return /* @__PURE__ */ React16.createElement(Stack12, { className: "openType" }, ((_a = value == null ? void 0 : value.features) == null ? void 0 : _a.length) > 0 && /* @__PURE__ */ React16.createElement(Text14, { muted: true, size: 1, style: { marginBottom: "0.5rem" } }, "Number of features: ", value.features.length), !!((_b = stylesObject == null ? void 0 : stylesObject.fonts) == null ? void 0 : _b.length) && /* @__PURE__ */ React16.createElement(
3152
+ return /* @__PURE__ */ React15.createElement(Stack12, { className: "openType" }, ((_a = value == null ? void 0 : value.features) == null ? void 0 : _a.length) > 0 && /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1, style: { marginBottom: "0.5rem" } }, "Number of features: ", value.features.length), !!((_b = stylesObject == null ? void 0 : stylesObject.fonts) == null ? void 0 : _b.length) && /* @__PURE__ */ React15.createElement(
4080
3153
  Button13,
4081
3154
  {
4082
3155
  text: "Detect OTF",
@@ -4084,23 +3157,23 @@ var SetOTF = (props) => {
4084
3157
  onClick: detect,
4085
3158
  style: { borderRadius: "0 3px 0 0", marginBottom: "1rem" }
4086
3159
  }
4087
- ), !!message && /* @__PURE__ */ React16.createElement(Text14, { muted: true, size: 1 }, /* @__PURE__ */ React16.createElement("br", null), message, /* @__PURE__ */ React16.createElement("br", null), /* @__PURE__ */ React16.createElement("br", null)), props.renderDefault(props));
3160
+ ), !!message && /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1 }, /* @__PURE__ */ React15.createElement("br", null), message, /* @__PURE__ */ React15.createElement("br", null), /* @__PURE__ */ React15.createElement("br", null)), props.renderDefault(props));
4088
3161
  };
4089
3162
 
4090
3163
  // src/components/StyleCountInput.jsx
4091
- import React17 from "react";
4092
- import { Text as Text15 } from "@sanity/ui";
3164
+ import React16 from "react";
3165
+ import { Text as Text14 } from "@sanity/ui";
4093
3166
  import { useFormValue as useFormValue12 } from "sanity";
4094
3167
  var StyleCountInput = (props) => {
4095
3168
  const styles = useFormValue12(["styles", "fonts"]) || [];
4096
3169
  const vfStyles = useFormValue12(["styles", "variableFont"]) || [];
4097
3170
  const count = styles.length + vfStyles.length;
4098
- return /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, count);
3171
+ return /* @__PURE__ */ React16.createElement(Text14, { size: 1 }, count);
4099
3172
  };
4100
3173
 
4101
3174
  // src/components/NestedObjectArraySelector.jsx
4102
- import React18, { useMemo as useMemo5, useState as useState14 } from "react";
4103
- import { Stack as Stack13, Card as Card6, Text as Text16, Checkbox, Box as Box6, Spinner as Spinner4, Flex as Flex11 } from "@sanity/ui";
3175
+ import React17, { useMemo as useMemo5, useState as useState14 } from "react";
3176
+ import { Stack as Stack13, Card as Card6, Text as Text15, Checkbox, Box as Box6, Spinner as Spinner4, Flex as Flex10 } from "@sanity/ui";
4104
3177
 
4105
3178
  // src/hooks/useNestedObjects.js
4106
3179
  import { useState as useState13, useEffect as useEffect7 } from "react";
@@ -4172,7 +3245,7 @@ function useNestedObjects({
4172
3245
 
4173
3246
  // src/components/NestedObjectArraySelector.jsx
4174
3247
  import { set as set8, unset as unset3 } from "sanity";
4175
- var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
3248
+ var NestedObjectArraySelector = React17.forwardRef((props, ref) => {
4176
3249
  const { value = [], onChange, schemaType } = props;
4177
3250
  const options = (schemaType == null ? void 0 : schemaType.options) || {};
4178
3251
  const {
@@ -4206,18 +3279,18 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4206
3279
  }
4207
3280
  };
4208
3281
  if (!sourceType || !nestedField || !titleField || !valueField) {
4209
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Configuration error: Missing required options (sourceType, nestedField, titleField, or valueField)"));
3282
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Configuration error: Missing required options (sourceType, nestedField, titleField, or valueField)"));
4210
3283
  }
4211
3284
  if (loading) {
4212
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, border: true }, /* @__PURE__ */ React18.createElement(Flex11, { align: "center", justify: "center", padding: 4 }, /* @__PURE__ */ React18.createElement(Spinner4, null), /* @__PURE__ */ React18.createElement(Box6, { marginLeft: 3 }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Loading options..."))));
3285
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, border: true }, /* @__PURE__ */ React17.createElement(Flex10, { align: "center", justify: "center", padding: 4 }, /* @__PURE__ */ React17.createElement(Spinner4, null), /* @__PURE__ */ React17.createElement(Box6, { marginLeft: 3 }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Loading options..."))));
4213
3286
  }
4214
3287
  if (error) {
4215
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Error loading options: ", error.message));
3288
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Error loading options: ", error.message));
4216
3289
  }
4217
3290
  if (objects.length === 0) {
4218
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "transparent", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, emptyMessage));
3291
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "transparent", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, emptyMessage));
4219
3292
  }
4220
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 0, border: true, ref }, objects.length > 5 && /* @__PURE__ */ React18.createElement(Box6, { padding: 3, style: { borderBottom: "1px solid var(--card-border-color)" } }, /* @__PURE__ */ React18.createElement(
3293
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 0, border: true, ref }, objects.length > 5 && /* @__PURE__ */ React17.createElement(Box6, { padding: 3, style: { borderBottom: "1px solid var(--card-border-color)" } }, /* @__PURE__ */ React17.createElement(
4221
3294
  "input",
4222
3295
  {
4223
3296
  type: "text",
@@ -4226,10 +3299,10 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4226
3299
  onChange: (e) => setSearchTerm(e.target.value),
4227
3300
  style: { width: "100%", padding: "8px 12px", border: "1px solid var(--card-border-color)", borderRadius: "4px", fontSize: "13px", fontFamily: "inherit" }
4228
3301
  }
4229
- )), /* @__PURE__ */ React18.createElement(Stack13, { space: 0 }, filteredObjects.length === 0 ? /* @__PURE__ */ React18.createElement(Box6, { padding: 3 }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, 'No results found for "', searchTerm, '"')) : filteredObjects.map((obj, index) => {
3302
+ )), /* @__PURE__ */ React17.createElement(Stack13, { space: 0 }, filteredObjects.length === 0 ? /* @__PURE__ */ React17.createElement(Box6, { padding: 3 }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, 'No results found for "', searchTerm, '"')) : filteredObjects.map((obj, index) => {
4230
3303
  const isSelected = value == null ? void 0 : value.includes(obj.value);
4231
3304
  const isLast = index === filteredObjects.length - 1;
4232
- return /* @__PURE__ */ React18.createElement(
3305
+ return /* @__PURE__ */ React17.createElement(
4233
3306
  Box6,
4234
3307
  {
4235
3308
  key: obj.value,
@@ -4237,28 +3310,28 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4237
3310
  style: { borderBottom: isLast ? "none" : "1px solid var(--card-border-color)", cursor: "pointer", backgroundColor: isSelected ? "var(--card-muted-fg-color)" : "transparent", transition: "background-color 0.2s" },
4238
3311
  onClick: () => handleToggle(obj.value)
4239
3312
  },
4240
- /* @__PURE__ */ React18.createElement(Flex11, { align: "center", gap: 3 }, /* @__PURE__ */ React18.createElement(Checkbox, { checked: isSelected, readOnly: true, style: { pointerEvents: "none" } }), /* @__PURE__ */ React18.createElement(Text16, { size: 1, weight: isSelected ? "semibold" : "regular" }, obj.title))
3313
+ /* @__PURE__ */ React17.createElement(Flex10, { align: "center", gap: 3 }, /* @__PURE__ */ React17.createElement(Checkbox, { checked: isSelected, readOnly: true, style: { pointerEvents: "none" } }), /* @__PURE__ */ React17.createElement(Text15, { size: 1, weight: isSelected ? "semibold" : "regular" }, obj.title))
4241
3314
  );
4242
- })), (value == null ? void 0 : value.length) > 0 && /* @__PURE__ */ React18.createElement(Box6, { padding: 2, paddingX: 3, style: { borderTop: "1px solid var(--card-border-color)", backgroundColor: "var(--card-muted-fg-color)" } }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, value.length, " selected")));
3315
+ })), (value == null ? void 0 : value.length) > 0 && /* @__PURE__ */ React17.createElement(Box6, { padding: 2, paddingX: 3, style: { borderTop: "1px solid var(--card-border-color)", backgroundColor: "var(--card-muted-fg-color)" } }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, value.length, " selected")));
4243
3316
  });
4244
3317
  NestedObjectArraySelector.displayName = "NestedObjectArraySelector";
4245
3318
 
4246
3319
  // src/utils/getEmptyFontKit.js
4247
- import * as fontkit7 from "fontkit";
4248
- import slugify4 from "slugify";
3320
+ import slugify3 from "slugify";
4249
3321
  async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordList }) {
4250
- var _a, _b, _c, _d, _e, _f;
4251
3322
  let fontNames = {};
4252
3323
  let subfamilies = {};
4253
3324
  for (var i = 0; i < files.length; i++) {
4254
3325
  const file = files[i];
4255
3326
  const fontBuffer = await readFontFile2(file);
4256
- const font = fontkit7.create(fontBuffer);
4257
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) ? (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.preferredSubfamily : (_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fontSubfamily;
4258
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
4259
- let variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0 ? true : false;
4260
- let subfamilyName = font.familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
4261
- let fontTitle = font == null ? void 0 : font.fullName.toLowerCase().trim();
3327
+ const font = await parseFont(fontBuffer, file.name);
3328
+ let weightName = getNameString(font, 17) || getNameString(font, 2) || "";
3329
+ const axes = getVariationAxes(font);
3330
+ let variableFont = axes !== null;
3331
+ const familyName = getNameString(font, 1);
3332
+ const fullName = getNameString(font, 4);
3333
+ let subfamilyName = familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
3334
+ let fontTitle = fullName.toLowerCase().trim();
4262
3335
  weightKeywordList.forEach((keyword) => {
4263
3336
  const kw = keyword.toLowerCase().trim();
4264
3337
  if (fontTitle.includes(kw)) {
@@ -4280,7 +3353,7 @@ async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordL
4280
3353
  fontTitle = fontTitle.trim().split(" ").map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
4281
3354
  subfamilyName = subfamilyName.trim();
4282
3355
  subfamilyName = subfamilyName == "" ? "Regular" : subfamilyName.split(" ").map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
4283
- let id = slugify4(fontTitle.toLowerCase().trim());
3356
+ let id = slugify3(fontTitle.toLowerCase().trim());
4284
3357
  if (variableFont && !id.endsWith("-vf")) {
4285
3358
  id = id + "-vf";
4286
3359
  fontTitle = fontTitle + " VF";
@@ -4293,26 +3366,26 @@ async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordL
4293
3366
  if (!fontNames[id]) {
4294
3367
  fontNames[id] = [{
4295
3368
  file: file.name,
4296
- fullName: font.fullName,
4297
- familyName: font.familyName,
3369
+ fullName,
3370
+ familyName,
4298
3371
  subFamily: subfamilyName
4299
3372
  }];
4300
3373
  } else if (fontNames[id].indexOf(file.name) == -1) {
4301
3374
  fontNames[id].push({
4302
3375
  file: file.name,
4303
- fullName: font.fullName,
4304
- familyName: font.familyName,
3376
+ fullName,
3377
+ familyName,
4305
3378
  subFamily: subfamilyName
4306
3379
  });
4307
3380
  }
4308
3381
  }
4309
- console.log("font names : ", fontNames);
3382
+ console.log("Font names:", fontNames);
4310
3383
  }
4311
3384
  var readFontFile2 = (file) => {
4312
3385
  return new Promise((resolve, reject) => {
4313
3386
  const reader = new FileReader();
4314
3387
  reader.onload = (event) => {
4315
- resolve(new Uint8Array(event.target.result));
3388
+ resolve(event.target.result);
4316
3389
  };
4317
3390
  reader.onerror = (error) => {
4318
3391
  reject(error);
@@ -6775,15 +5848,15 @@ var stylisticSetField = {
6775
5848
  };
6776
5849
 
6777
5850
  // src/schema/stylesField.js
6778
- import React19 from "react";
5851
+ import React18 from "react";
6779
5852
  import { AdvancedRefArray } from "@liiift-studio/sanity-advanced-reference-array";
6780
5853
  var typefaceParams = (doc) => ({ typefaceName: (doc == null ? void 0 : doc.title) || "" });
6781
- var FontsRefArray = (props) => React19.createElement(AdvancedRefArray, {
5854
+ var FontsRefArray = (props) => React18.createElement(AdvancedRefArray, {
6782
5855
  ...props,
6783
5856
  filterGroq: "lower(typefaceName) == lower($typefaceName)",
6784
5857
  filterParams: typefaceParams
6785
5858
  });
6786
- var VariableFontsRefArray = (props) => React19.createElement(AdvancedRefArray, {
5859
+ var VariableFontsRefArray = (props) => React18.createElement(AdvancedRefArray, {
6787
5860
  ...props,
6788
5861
  filterGroq: "lower(typefaceName) == lower($typefaceName) && variableFont == true",
6789
5862
  filterParams: typefaceParams
@@ -7010,16 +6083,24 @@ function createStylesField({
7010
6083
  }
7011
6084
  export {
7012
6085
  BatchUploadFonts,
6086
+ BulkActions,
7013
6087
  DISCOUNT_REQUIREMENT_TYPES,
7014
6088
  DISCOUNT_REQUIREMENT_TYPES_OBJECT,
6089
+ EXECUTION_STATUS,
6090
+ ExistingDocumentResolver,
6091
+ FONT_STATUS,
6092
+ FontReviewCard_default as FontReviewCard,
7015
6093
  FontScriptUploaderComponent,
7016
6094
  GenerateCollectionsPairsComponent,
7017
6095
  HtmlDescription,
7018
6096
  KeyValueInput,
7019
6097
  KeyValueReferenceInput,
7020
6098
  NestedObjectArraySelector,
6099
+ PLAN_PHASE,
6100
+ PLAN_VERSION,
7021
6101
  PriceInput_default as PriceInput,
7022
6102
  PrimaryCollectionGeneratorTypeface,
6103
+ RECOMMENDATION,
7023
6104
  RegenerateSubfamiliesComponent,
7024
6105
  SCRIPTS,
7025
6106
  SCRIPTS_OBJECT,
@@ -7029,12 +6110,25 @@ export {
7029
6110
  StyleCountInput,
7030
6111
  UpdateScriptsComponent,
7031
6112
  UploadButton_default as UploadButton,
6113
+ UploadModal,
7032
6114
  UploadScriptsComponent,
6115
+ UploadStep1Settings,
6116
+ UploadStep2Review,
6117
+ UploadStep3Execute,
6118
+ UploadStep3bInstances,
6119
+ UploadSummary,
7033
6120
  VariableInstanceReferencesInput,
7034
6121
  addItalicToFontTitle,
6122
+ buildUploadPlan,
6123
+ createEmptyPlan,
6124
+ createFontDecisions,
7035
6125
  createFontObject,
6126
+ createInitialExecutionState,
7036
6127
  createStylesField,
7037
6128
  determineWeight,
6129
+ escapeCssFontName,
6130
+ executeUploadPlan,
6131
+ executionReducer,
7038
6132
  expandAbbreviations,
7039
6133
  extractFontMetadata,
7040
6134
  extractWeightFromFullName,
@@ -7045,16 +6139,32 @@ export {
7045
6139
  generateFontFile,
7046
6140
  generateStyleKeywords,
7047
6141
  generateSubset,
6142
+ getAllFeatureTags,
6143
+ getCharacterSet,
7048
6144
  getEmptyFontKit,
6145
+ getFamilyClass,
6146
+ getFontMetadata,
6147
+ getFontMetrics,
6148
+ getFsSelection,
6149
+ getGlyphCount,
6150
+ getItalicAngle,
6151
+ getMacStyle,
6152
+ getNameString,
6153
+ getNamedInstances,
6154
+ getVariationAxes,
6155
+ getWeightClass,
7049
6156
  logFontInfo,
7050
6157
  openTypeField,
6158
+ parseFont,
7051
6159
  parseVariableFontInstances_default as parseVariableFontInstances,
6160
+ planReducer,
7052
6161
  processFontFiles,
7053
6162
  processItalicKeywords,
7054
6163
  processSubfamilyName,
7055
6164
  readFontFile,
7056
6165
  removeWeightNames,
7057
6166
  renameFontDocuments,
6167
+ resolveExistingFont,
7058
6168
  reverseSpellingLookup,
7059
6169
  sanitizeForSanityId,
7060
6170
  sortFontObjects,