@liiift-studio/sanity-font-manager 2.5.0 → 2.5.2
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.
- package/dist/UploadModal-2AAJXZJK.js +6 -0
- package/dist/{UploadModal-NME2W53V.mjs → UploadModal-DDTVJ2MA.mjs} +1 -1
- package/dist/{chunk-646WCBRR.mjs → chunk-FT7YTFZW.mjs} +617 -182
- package/dist/{chunk-FH4QKHOH.js → chunk-YMQEM4AO.js} +583 -148
- package/dist/index.js +109 -66
- package/dist/index.mjs +66 -23
- package/package.json +1 -1
- package/src/components/BatchUploadFonts.jsx +1 -1
- package/src/components/FontReviewCard.jsx +41 -1
- package/src/components/KeyValueReferenceInput.jsx +69 -61
- package/src/components/SingleUploaderTool.jsx +3 -3
- package/src/components/UploadModal.jsx +43 -7
- package/src/components/UploadStep1Settings.jsx +1 -1
- package/src/components/UploadStep2Review.jsx +2 -0
- package/src/components/UploadStep3Execute.jsx +1 -1
- package/src/components/UploadStep3bInstances.jsx +396 -0
- package/src/index.js +1 -0
- package/src/schema/stylesField.js +20 -0
- package/src/utils/buildUploadPlan.js +1 -0
- package/src/utils/executeUploadPlan.js +1 -8
- package/src/utils/parseVariableFontInstances.js +237 -147
- package/src/utils/processFontFiles.js +5 -4
- package/src/utils/updateTypefaceDocument.js +15 -2
- package/dist/UploadModal-6LIX7XOK.js +0 -6
|
@@ -4488,14 +4488,14 @@ var extractFontMetadata = (font, title, weightKeywordList, italicKeywordList, pr
|
|
|
4488
4488
|
weightName = expandAbbreviations(weightName);
|
|
4489
4489
|
}
|
|
4490
4490
|
const fullName = getNameString(font, 4) || (ttfFallbackMeta == null ? void 0 : ttfFallbackMeta.fullName) || "";
|
|
4491
|
-
|
|
4491
|
+
const axes = getVariationAxes(font);
|
|
4492
|
+
const variableFont = axes !== null;
|
|
4493
|
+
if (!variableFont && (weightName === "" || weightName.toLowerCase() === "roman") && fullName) {
|
|
4492
4494
|
weightName = extractWeightFromFullName(font, title, ttfFallbackMeta);
|
|
4493
4495
|
if (!preserveShortenedNames) {
|
|
4494
4496
|
weightName = expandAbbreviations(weightName);
|
|
4495
4497
|
}
|
|
4496
4498
|
}
|
|
4497
|
-
const axes = getVariationAxes(font);
|
|
4498
|
-
const variableFont = axes !== null;
|
|
4499
4499
|
const trimmedTitle = title.trim();
|
|
4500
4500
|
const nameId4Remainder = fullName ? fullName.replace(trimmedTitle, "").trim() : "";
|
|
4501
4501
|
const nameId1 = getNameString(font, 1) || (ttfFallbackMeta == null ? void 0 : ttfFallbackMeta.familyName) || "";
|
|
@@ -4779,6 +4779,7 @@ async function buildUploadPlan({
|
|
|
4779
4779
|
onProgress
|
|
4780
4780
|
}) {
|
|
4781
4781
|
const plan = createEmptyPlan(settings);
|
|
4782
|
+
plan.settings.typefaceTitle = typefaceTitle;
|
|
4782
4783
|
plan.phase = PLAN_PHASE.PROCESSING;
|
|
4783
4784
|
plan.processingProgress.total = files.length;
|
|
4784
4785
|
for (let i = 0; i < files.length; i++) {
|
|
@@ -5189,7 +5190,7 @@ function UploadStep1Settings({ settings, onStartProcessing }) {
|
|
|
5189
5190
|
},
|
|
5190
5191
|
ext.toUpperCase()
|
|
5191
5192
|
),
|
|
5192
|
-
/* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, style: { flex: 1
|
|
5193
|
+
/* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, style: { flex: 1 } }, file.name),
|
|
5193
5194
|
/* @__PURE__ */ _react2.default.createElement(
|
|
5194
5195
|
_ui.Button,
|
|
5195
5196
|
{
|
|
@@ -5302,10 +5303,11 @@ function ExistingDocumentResolver({ decision, tempId, dispatch }) {
|
|
|
5302
5303
|
// src/components/FontReviewCard.jsx
|
|
5303
5304
|
var STANDARD_TYPES = ["ttf", "otf", "woff", "woff2"];
|
|
5304
5305
|
var EXTENDED_TYPES = ["eot", "svg", "css", "woff2_subset", "woff2_web"];
|
|
5305
|
-
var FontReviewCard = _react.memo.call(void 0, function FontReviewCard2({ entry, dispatch, allExpanded }) {
|
|
5306
|
+
var FontReviewCard = _react.memo.call(void 0, function FontReviewCard2({ entry, dispatch, allExpanded, typefaceTitle, price }) {
|
|
5306
5307
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
5307
5308
|
const [expanded, setExpanded] = _react.useState.call(void 0, false);
|
|
5308
5309
|
const [showAllFileTypes, setShowAllFileTypes] = _react.useState.call(void 0, false);
|
|
5310
|
+
const [showDocPreview, setShowDocPreview] = _react.useState.call(void 0, false);
|
|
5309
5311
|
_react.useEffect.call(void 0, () => {
|
|
5310
5312
|
setExpanded(allExpanded);
|
|
5311
5313
|
}, [allExpanded]);
|
|
@@ -5513,7 +5515,32 @@ var FontReviewCard = _react.memo.call(void 0, function FontReviewCard2({ entry,
|
|
|
5513
5515
|
tempId: entry.tempId,
|
|
5514
5516
|
dispatch
|
|
5515
5517
|
}
|
|
5516
|
-
), /* @__PURE__ */ _react2.default.createElement(_ui.
|
|
5518
|
+
), /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 2 }, /* @__PURE__ */ _react2.default.createElement(
|
|
5519
|
+
_ui.Button,
|
|
5520
|
+
{
|
|
5521
|
+
mode: "bleed",
|
|
5522
|
+
fontSize: 0,
|
|
5523
|
+
padding: 1,
|
|
5524
|
+
text: showDocPreview ? "Hide document preview" : "Show document preview",
|
|
5525
|
+
onClick: () => setShowDocPreview((v) => !v),
|
|
5526
|
+
style: { cursor: "pointer", alignSelf: "flex-start" }
|
|
5527
|
+
}
|
|
5528
|
+
), showDocPreview && /* @__PURE__ */ _react2.default.createElement(_ui.Card, { border: true, padding: 3, radius: 1, style: { fontFamily: "monospace", fontSize: 12 } }, /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 2 }, [
|
|
5529
|
+
["_id", entry.documentId],
|
|
5530
|
+
["_type", "font"],
|
|
5531
|
+
["title", entry.title],
|
|
5532
|
+
["slug", entry.documentId],
|
|
5533
|
+
["typefaceName", typefaceTitle || "\u2014"],
|
|
5534
|
+
["weightName", entry.weightName || "\u2014"],
|
|
5535
|
+
["weight", entry.weight],
|
|
5536
|
+
["style", entry.style],
|
|
5537
|
+
["subfamily", entry.subfamily || "\u2014"],
|
|
5538
|
+
["variableFont", String(entry.variableFont)],
|
|
5539
|
+
["price", _nullishCoalesce(price, () => ( "\u2014"))],
|
|
5540
|
+
["sell", price > 0 ? "true" : "false"],
|
|
5541
|
+
["normalWeight", "true"],
|
|
5542
|
+
["files", (entry.files || []).map((f) => f.name).join(", ") || "\u2014"]
|
|
5543
|
+
].map(([key, value]) => /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { key, gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true, style: { width: 120, flexShrink: 0 } }, key), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, style: { wordBreak: "break-all" } }, String(value))))))), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { justify: "flex-end", gap: 2 }, hasUserOverrides && /* @__PURE__ */ _react2.default.createElement(
|
|
5517
5544
|
_ui.Button,
|
|
5518
5545
|
{
|
|
5519
5546
|
mode: "ghost",
|
|
@@ -5922,15 +5949,20 @@ function UploadStep2Review({
|
|
|
5922
5949
|
" ",
|
|
5923
5950
|
sortBy === col.key ? sortDir === "asc" ? "\u2191" : "\u2193" : ""
|
|
5924
5951
|
))
|
|
5925
|
-
), Object.entries(groupedEntries).map(([subfamily, entries]) => /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { key: subfamily, space: 1 }, /* @__PURE__ */ _react2.default.createElement(_ui.Card, { padding: 2, radius: 1, style: { background: "var(--card-muted-bg-color)" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, weight: "semibold" }, subfamily), /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { mode: "outline", fontSize: 0 }, entries.length))), /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 0 }, entries.map((entry) =>
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5952
|
+
), Object.entries(groupedEntries).map(([subfamily, entries]) => /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { key: subfamily, space: 1 }, /* @__PURE__ */ _react2.default.createElement(_ui.Card, { padding: 2, radius: 1, style: { background: "var(--card-muted-bg-color)" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, weight: "semibold" }, subfamily), /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { mode: "outline", fontSize: 0 }, entries.length))), /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 0 }, entries.map((entry) => {
|
|
5953
|
+
var _a2, _b2;
|
|
5954
|
+
return /* @__PURE__ */ _react2.default.createElement(
|
|
5955
|
+
FontReviewCard_default,
|
|
5956
|
+
{
|
|
5957
|
+
key: entry.tempId,
|
|
5958
|
+
entry,
|
|
5959
|
+
dispatch,
|
|
5960
|
+
allExpanded,
|
|
5961
|
+
typefaceTitle: (_a2 = plan.settings) == null ? void 0 : _a2.typefaceTitle,
|
|
5962
|
+
price: (_b2 = plan.settings) == null ? void 0 : _b2.price
|
|
5963
|
+
}
|
|
5964
|
+
);
|
|
5965
|
+
})))), visibleEntries.length === 0 && fontEntries.length > 0 && /* @__PURE__ */ _react2.default.createElement(_ui.Card, { border: true, padding: 4, radius: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, muted: true, align: "center" }, "No fonts match the current filter")), isReviewing && validationErrors.length > 0 && /* @__PURE__ */ _react2.default.createElement(_ui.Card, { tone: "caution", border: true, padding: 2, radius: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 1 }, validationErrors.map((err, i) => /* @__PURE__ */ _react2.default.createElement(_ui.Text, { key: i, size: 0, tone: "caution" }, "\u2022 ", err)))), isReviewing && processedCount > 0 && /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { justify: "flex-end", gap: 2, style: { position: "sticky", bottom: 0, background: "var(--card-bg-color)", paddingTop: 8, paddingBottom: 4 } }, /* @__PURE__ */ _react2.default.createElement(
|
|
5934
5966
|
_ui.Button,
|
|
5935
5967
|
{
|
|
5936
5968
|
mode: "default",
|
|
@@ -6168,6 +6200,169 @@ async function generateFontData({ fileInput, url, fontKit, fontId, client, commi
|
|
|
6168
6200
|
|
|
6169
6201
|
// src/utils/parseVariableFontInstances.js
|
|
6170
6202
|
|
|
6203
|
+
var WIDTH_PREFIXES = [
|
|
6204
|
+
"XXXWide",
|
|
6205
|
+
"XXWide",
|
|
6206
|
+
"XWide",
|
|
6207
|
+
"Wide",
|
|
6208
|
+
"XXXNarrow",
|
|
6209
|
+
"XXNarrow",
|
|
6210
|
+
"XNarrow",
|
|
6211
|
+
"Narrow"
|
|
6212
|
+
];
|
|
6213
|
+
function parseInstanceName(instanceName) {
|
|
6214
|
+
let subfamily = "";
|
|
6215
|
+
let remaining = instanceName.trim();
|
|
6216
|
+
for (const prefix of WIDTH_PREFIXES) {
|
|
6217
|
+
if (remaining.toLowerCase().startsWith(prefix.toLowerCase() + " ") || remaining.toLowerCase() === prefix.toLowerCase()) {
|
|
6218
|
+
subfamily = prefix;
|
|
6219
|
+
remaining = remaining.substring(prefix.length).trim();
|
|
6220
|
+
break;
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
6223
|
+
let style = "";
|
|
6224
|
+
for (const suffix of ["Backslant", "Slant", "Italic", "Oblique"]) {
|
|
6225
|
+
if (remaining.toLowerCase().endsWith(" " + suffix.toLowerCase()) || remaining.toLowerCase() === suffix.toLowerCase()) {
|
|
6226
|
+
style = suffix;
|
|
6227
|
+
remaining = remaining.substring(0, remaining.length - suffix.length).trim();
|
|
6228
|
+
break;
|
|
6229
|
+
}
|
|
6230
|
+
}
|
|
6231
|
+
return { subfamily, weight: remaining || "Regular", style };
|
|
6232
|
+
}
|
|
6233
|
+
function filterBySubfamily(staticFonts, instanceSubfamily, typefaceName) {
|
|
6234
|
+
if (!instanceSubfamily) {
|
|
6235
|
+
return staticFonts.filter((sf) => {
|
|
6236
|
+
const sub = (sf.subfamily || "").toLowerCase();
|
|
6237
|
+
if (sub === "" || sub === "regular") return true;
|
|
6238
|
+
const afterTypeface = (sf.title || "").replace(typefaceName, "").trim();
|
|
6239
|
+
return !WIDTH_PREFIXES.some((p) => afterTypeface.toLowerCase().startsWith(p.toLowerCase()));
|
|
6240
|
+
});
|
|
6241
|
+
}
|
|
6242
|
+
const lowerSf = instanceSubfamily.toLowerCase();
|
|
6243
|
+
const expanded = (expandAbbreviations(instanceSubfamily) || "").toLowerCase();
|
|
6244
|
+
return staticFonts.filter((sf) => {
|
|
6245
|
+
const sub = (sf.subfamily || "").toLowerCase();
|
|
6246
|
+
if (sub === lowerSf || expanded && sub === expanded) return true;
|
|
6247
|
+
const afterTypeface = (sf.title || "").replace(typefaceName, "").trim().toLowerCase();
|
|
6248
|
+
if (afterTypeface.startsWith(lowerSf)) return true;
|
|
6249
|
+
if (expanded && afterTypeface.startsWith(expanded)) return true;
|
|
6250
|
+
return false;
|
|
6251
|
+
});
|
|
6252
|
+
}
|
|
6253
|
+
var WEIGHT_MAP = [
|
|
6254
|
+
{ term: "ultra", weight: 950 },
|
|
6255
|
+
{ term: "xxlight", weight: 200 },
|
|
6256
|
+
{ term: "xlight", weight: 250 },
|
|
6257
|
+
{ term: "extralight", weight: 200 },
|
|
6258
|
+
{ term: "extra light", weight: 200 },
|
|
6259
|
+
{ term: "thin", weight: 100 },
|
|
6260
|
+
{ term: "hairline", weight: 100 },
|
|
6261
|
+
{ term: "light", weight: 300 },
|
|
6262
|
+
{ term: "regular", weight: 400 },
|
|
6263
|
+
{ term: "normal", weight: 400 },
|
|
6264
|
+
{ term: "medium", weight: 500 },
|
|
6265
|
+
{ term: "semibold", weight: 600 },
|
|
6266
|
+
{ term: "semi bold", weight: 600 },
|
|
6267
|
+
{ term: "extrabold", weight: 800 },
|
|
6268
|
+
{ term: "extra bold", weight: 800 },
|
|
6269
|
+
{ term: "xbold", weight: 800 },
|
|
6270
|
+
{ term: "bold", weight: 700 },
|
|
6271
|
+
{ term: "black", weight: 900 },
|
|
6272
|
+
{ term: "heavy", weight: 900 }
|
|
6273
|
+
];
|
|
6274
|
+
function weightFromName(name) {
|
|
6275
|
+
const lower = name.toLowerCase();
|
|
6276
|
+
for (const { term, weight } of WEIGHT_MAP) {
|
|
6277
|
+
if (lower === term || lower.includes(term)) return weight;
|
|
6278
|
+
}
|
|
6279
|
+
return 400;
|
|
6280
|
+
}
|
|
6281
|
+
var STRATEGIES = [
|
|
6282
|
+
// Pass 1: Exact title match (with typeface prefix)
|
|
6283
|
+
{
|
|
6284
|
+
name: "exact-title",
|
|
6285
|
+
match: (instanceName, parsed, candidates, typefaceName) => {
|
|
6286
|
+
const withPrefix = `${typefaceName} ${instanceName}`;
|
|
6287
|
+
return candidates.find((sf) => sf.title === instanceName || sf.title === withPrefix) || null;
|
|
6288
|
+
}
|
|
6289
|
+
},
|
|
6290
|
+
// Pass 2: Title normalisation — strip typeface name and compare remainder
|
|
6291
|
+
{
|
|
6292
|
+
name: "title-normalised",
|
|
6293
|
+
match: (instanceName, parsed, candidates, typefaceName) => {
|
|
6294
|
+
return candidates.find((sf) => {
|
|
6295
|
+
const sfName = (sf.title || "").replace(typefaceName, "").trim();
|
|
6296
|
+
if (sfName.toLowerCase() === instanceName.toLowerCase()) return true;
|
|
6297
|
+
if (parsed.weight === "Regular" && !parsed.style) {
|
|
6298
|
+
if (sfName.toLowerCase() === parsed.subfamily.toLowerCase()) return true;
|
|
6299
|
+
}
|
|
6300
|
+
return false;
|
|
6301
|
+
}) || null;
|
|
6302
|
+
}
|
|
6303
|
+
},
|
|
6304
|
+
// Pass 3: Abbreviation expansion (XLight → ExtraLight, XBold → ExtraBold)
|
|
6305
|
+
{
|
|
6306
|
+
name: "abbreviation",
|
|
6307
|
+
match: (instanceName, parsed, candidates, typefaceName) => {
|
|
6308
|
+
const expandedFull = instanceName.split(" ").map((w) => expandAbbreviations(w) || w).join(" ");
|
|
6309
|
+
let found = candidates.find((sf) => {
|
|
6310
|
+
const sfName = (sf.title || "").replace(typefaceName, "").trim();
|
|
6311
|
+
return sfName.toLowerCase() === expandedFull.toLowerCase();
|
|
6312
|
+
});
|
|
6313
|
+
if (found) return found;
|
|
6314
|
+
const expandedWeight = expandAbbreviations(parsed.weight) || parsed.weight;
|
|
6315
|
+
const target = [parsed.subfamily, expandedWeight, parsed.style].filter(Boolean).join(" ");
|
|
6316
|
+
return candidates.find((sf) => {
|
|
6317
|
+
const sfName = (sf.title || "").replace(typefaceName, "").trim();
|
|
6318
|
+
return sfName.toLowerCase() === target.toLowerCase();
|
|
6319
|
+
}) || null;
|
|
6320
|
+
}
|
|
6321
|
+
},
|
|
6322
|
+
// Pass 4: fullName metadata comparison
|
|
6323
|
+
{
|
|
6324
|
+
name: "metadata-fullName",
|
|
6325
|
+
match: (instanceName, parsed, candidates, typefaceName) => {
|
|
6326
|
+
return candidates.find((sf) => {
|
|
6327
|
+
var _a;
|
|
6328
|
+
if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
|
|
6329
|
+
const typefacePattern = new RegExp(`^${typefaceName}\\s+`, "i");
|
|
6330
|
+
const stylePart = sf.metaData.fullName.replace(typefacePattern, "").trim();
|
|
6331
|
+
return instanceName.toLowerCase() === stylePart.toLowerCase();
|
|
6332
|
+
}) || null;
|
|
6333
|
+
}
|
|
6334
|
+
},
|
|
6335
|
+
// Pass 5: Weight + style matching (numeric, within subfamily)
|
|
6336
|
+
{
|
|
6337
|
+
name: "weight-style",
|
|
6338
|
+
match: (instanceName, parsed, candidates) => {
|
|
6339
|
+
const instanceWeight = weightFromName(parsed.weight);
|
|
6340
|
+
const isBackslant = parsed.style.toLowerCase() === "backslant";
|
|
6341
|
+
const isSlant = parsed.style.toLowerCase() === "slant";
|
|
6342
|
+
const isItalic = parsed.style.toLowerCase() === "italic";
|
|
6343
|
+
return candidates.find((sf) => {
|
|
6344
|
+
var _a, _b;
|
|
6345
|
+
if (Number(sf.weight) !== instanceWeight) return false;
|
|
6346
|
+
if (isBackslant) return sf.style === "Italic" && ((_a = sf.title) == null ? void 0 : _a.toLowerCase().includes("backslant"));
|
|
6347
|
+
if (isSlant) return sf.style === "Italic" && !((_b = sf.title) == null ? void 0 : _b.toLowerCase().includes("backslant"));
|
|
6348
|
+
if (isItalic) return sf.style === "Italic";
|
|
6349
|
+
return sf.style === "Regular";
|
|
6350
|
+
}) || null;
|
|
6351
|
+
}
|
|
6352
|
+
},
|
|
6353
|
+
// Pass 6: weightName string comparison
|
|
6354
|
+
{
|
|
6355
|
+
name: "weightName",
|
|
6356
|
+
match: (instanceName, parsed, candidates) => {
|
|
6357
|
+
const cleanInstance = parsed.weight.toLowerCase().trim();
|
|
6358
|
+
return candidates.find((sf) => {
|
|
6359
|
+
if (!sf.weightName) return false;
|
|
6360
|
+
const cleanWeight = sf.weightName.toLowerCase().replace(/italic|slant|backslant/gi, "").trim();
|
|
6361
|
+
return cleanInstance === cleanWeight;
|
|
6362
|
+
}) || null;
|
|
6363
|
+
}
|
|
6364
|
+
}
|
|
6365
|
+
];
|
|
6171
6366
|
var parseVariableFontInstances = async (font, client) => {
|
|
6172
6367
|
if (!font.variableFont || !font.variableInstances) return [];
|
|
6173
6368
|
let variableInstances;
|
|
@@ -6182,14 +6377,7 @@ var parseVariableFontInstances = async (font, client) => {
|
|
|
6182
6377
|
const typeface = await client.fetch(
|
|
6183
6378
|
`*[_type == 'typeface' && title == $typefaceName][0]{
|
|
6184
6379
|
'fonts': styles.fonts[]-> {
|
|
6185
|
-
_id,
|
|
6186
|
-
title,
|
|
6187
|
-
subfamily,
|
|
6188
|
-
style,
|
|
6189
|
-
weight,
|
|
6190
|
-
weightName,
|
|
6191
|
-
metaData,
|
|
6192
|
-
variableFont
|
|
6380
|
+
_id, title, subfamily, style, weight, weightName, metaData, variableFont
|
|
6193
6381
|
}
|
|
6194
6382
|
}`,
|
|
6195
6383
|
{ typefaceName: font.typefaceName }
|
|
@@ -6201,127 +6389,49 @@ var parseVariableFontInstances = async (font, client) => {
|
|
|
6201
6389
|
console.warn("Typeface not found or no fonts in curated list, falling back to all fonts query");
|
|
6202
6390
|
staticFonts = await client.fetch(
|
|
6203
6391
|
`*[_type == 'font' && typefaceName == $typefaceName && variableFont != true]{
|
|
6204
|
-
_id,
|
|
6205
|
-
title,
|
|
6206
|
-
subfamily,
|
|
6207
|
-
style,
|
|
6208
|
-
weight,
|
|
6209
|
-
weightName,
|
|
6210
|
-
metaData
|
|
6392
|
+
_id, title, subfamily, style, weight, weightName, metaData
|
|
6211
6393
|
}`,
|
|
6212
6394
|
{ typefaceName: font.typefaceName }
|
|
6213
6395
|
);
|
|
6214
6396
|
}
|
|
6215
|
-
|
|
6216
|
-
console.log("
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
}
|
|
6234
|
-
if (variableName) {
|
|
6235
|
-
const words = variableName.split(/\s+/).map((w) => w.trim()).filter(Boolean);
|
|
6236
|
-
if (words.length > 0) {
|
|
6237
|
-
const regex = new RegExp(`\\b(${words.join("|")})\\b`, "gi");
|
|
6238
|
-
const stripped = fullName.replace(regex, "").replace(/\s{2,}/g, " ").trim();
|
|
6239
|
-
if (stripped !== "") fullName = stripped;
|
|
6240
|
-
}
|
|
6241
|
-
}
|
|
6242
|
-
if (fullName.startsWith(font.typefaceName)) {
|
|
6243
|
-
fullName = fullName.substring(font.typefaceName.length).trim();
|
|
6244
|
-
}
|
|
6245
|
-
if (((_d = sf.style) == null ? void 0 : _d.toLowerCase()) === "italic" && !fullName.toLowerCase().endsWith("italic") && !fullName.toLowerCase().endsWith("slanted")) {
|
|
6246
|
-
fullName = fullName + " Italic";
|
|
6247
|
-
}
|
|
6248
|
-
if (fullName.trim().toLowerCase().endsWith("regular")) {
|
|
6249
|
-
if (instanceName.trim().toLowerCase() + " regular" === fullName.trim().toLowerCase()) return true;
|
|
6250
|
-
}
|
|
6251
|
-
if (fullName.trim().toLowerCase().startsWith("regular")) {
|
|
6252
|
-
if ("regular " + instanceName.trim().toLowerCase() === fullName.trim().toLowerCase()) return true;
|
|
6253
|
-
}
|
|
6254
|
-
if (fullName.trim().toLowerCase().endsWith("italic")) {
|
|
6255
|
-
if (instanceName.trim().toLowerCase().endsWith("italic")) {
|
|
6256
|
-
const k = instanceName.trim().toLowerCase().slice(0, -6).trim() + " regular italic";
|
|
6257
|
-
if (k === fullName.trim().toLowerCase()) return true;
|
|
6258
|
-
}
|
|
6259
|
-
}
|
|
6260
|
-
return fullName.trim().toLowerCase() === instanceName.trim().toLowerCase();
|
|
6261
|
-
});
|
|
6262
|
-
}
|
|
6263
|
-
if (!matchingFont) {
|
|
6264
|
-
const expandedName = instanceName.split(" ").map((word) => expandAbbreviations(word)).join(" ");
|
|
6265
|
-
matchingFont = staticFonts.find((sf) => {
|
|
6266
|
-
const nameWithoutTypeface = sf.title.replace(font.typefaceName, "").trim();
|
|
6267
|
-
return nameWithoutTypeface === expandedName;
|
|
6268
|
-
});
|
|
6269
|
-
}
|
|
6270
|
-
if (!matchingFont) {
|
|
6271
|
-
const isItalic = instanceName.toLowerCase().includes("italic");
|
|
6272
|
-
const weightTerms = [
|
|
6273
|
-
{ term: "thin", weight: "100" },
|
|
6274
|
-
{ term: "extralight", weight: "200" },
|
|
6275
|
-
{ term: "extra light", weight: "200" },
|
|
6276
|
-
{ term: "light", weight: "300" },
|
|
6277
|
-
{ term: "regular", weight: "400" },
|
|
6278
|
-
{ term: "normal", weight: "400" },
|
|
6279
|
-
{ term: "medium", weight: "500" },
|
|
6280
|
-
{ term: "semibold", weight: "600" },
|
|
6281
|
-
{ term: "semi bold", weight: "600" },
|
|
6282
|
-
{ term: "bold", weight: "700" },
|
|
6283
|
-
{ term: "extrabold", weight: "800" },
|
|
6284
|
-
{ term: "extra bold", weight: "800" },
|
|
6285
|
-
{ term: "black", weight: "900" },
|
|
6286
|
-
{ term: "heavy", weight: "900" }
|
|
6287
|
-
];
|
|
6288
|
-
let instanceWeight = "400";
|
|
6289
|
-
for (const { term, weight } of weightTerms) {
|
|
6290
|
-
if (instanceName.toLowerCase().includes(term)) {
|
|
6291
|
-
instanceWeight = weight;
|
|
6292
|
-
break;
|
|
6293
|
-
}
|
|
6397
|
+
const instanceNames = Object.keys(variableInstances);
|
|
6398
|
+
console.log("Variable font instances:", instanceNames.length);
|
|
6399
|
+
console.log("Available static fonts:", staticFonts.length);
|
|
6400
|
+
const parsedInstances = instanceNames.map((name) => ({
|
|
6401
|
+
name,
|
|
6402
|
+
parsed: parseInstanceName(name)
|
|
6403
|
+
}));
|
|
6404
|
+
const results = /* @__PURE__ */ new Map();
|
|
6405
|
+
const claimedFontIds = /* @__PURE__ */ new Set();
|
|
6406
|
+
for (const strategy of STRATEGIES) {
|
|
6407
|
+
const unmatched = parsedInstances.filter((inst) => !results.has(inst.name));
|
|
6408
|
+
if (unmatched.length === 0) break;
|
|
6409
|
+
const passMatches = [];
|
|
6410
|
+
for (const inst of unmatched) {
|
|
6411
|
+
const subfamilyCandidates = filterBySubfamily(staticFonts, inst.parsed.subfamily, font.typefaceName).filter((sf) => !claimedFontIds.has(sf._id));
|
|
6412
|
+
const match = strategy.match(inst.name, inst.parsed, subfamilyCandidates, font.typefaceName, font);
|
|
6413
|
+
if (match) {
|
|
6414
|
+
passMatches.push({ instanceName: inst.name, font: match, strategy: strategy.name });
|
|
6294
6415
|
}
|
|
6295
|
-
matchingFont = staticFonts.find(
|
|
6296
|
-
(sf) => sf.weight === instanceWeight && (isItalic && sf.style === "Italic" || !isItalic && sf.style === "Regular")
|
|
6297
|
-
);
|
|
6298
6416
|
}
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
return cleanInstance === cleanWeight;
|
|
6305
|
-
});
|
|
6306
|
-
}
|
|
6307
|
-
if (!matchingFont && staticFonts.some((sf) => {
|
|
6308
|
-
var _a;
|
|
6309
|
-
return (_a = sf.metaData) == null ? void 0 : _a.fullName;
|
|
6310
|
-
})) {
|
|
6311
|
-
matchingFont = staticFonts.find((sf) => {
|
|
6312
|
-
var _a;
|
|
6313
|
-
if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
|
|
6314
|
-
const typefacePattern = new RegExp(`^${font.typefaceName}\\s+`, "i");
|
|
6315
|
-
const stylePart = sf.metaData.fullName.replace(typefacePattern, "").trim();
|
|
6316
|
-
return instanceName.toLowerCase() === stylePart.toLowerCase();
|
|
6317
|
-
});
|
|
6417
|
+
for (const m of passMatches) {
|
|
6418
|
+
if (!claimedFontIds.has(m.font._id) && !results.has(m.instanceName)) {
|
|
6419
|
+
results.set(m.instanceName, { fontId: m.font._id, strategy: m.strategy });
|
|
6420
|
+
claimedFontIds.add(m.font._id);
|
|
6421
|
+
}
|
|
6318
6422
|
}
|
|
6319
|
-
|
|
6320
|
-
|
|
6423
|
+
}
|
|
6424
|
+
const matched = [...results.values()].length;
|
|
6425
|
+
console.log(`[parseVariableFontInstances] Matched ${matched}/${instanceNames.length} instances across ${STRATEGIES.length} passes`);
|
|
6426
|
+
const instanceMappings = instanceNames.map((instanceName) => {
|
|
6427
|
+
const result = results.get(instanceName);
|
|
6428
|
+
const matchedFont = result ? staticFonts.find((sf) => sf._id === result.fontId) : null;
|
|
6429
|
+
console.log(`Instance "${instanceName}" \u2192 ${matchedFont ? `${matchedFont.title} (${result.strategy})` : "No match"}`);
|
|
6430
|
+
return {
|
|
6321
6431
|
key: instanceName,
|
|
6322
|
-
value:
|
|
6432
|
+
value: matchedFont ? { _type: "reference", _ref: matchedFont._id, _weak: true } : null,
|
|
6323
6433
|
_key: _nanoid.nanoid.call(void 0, )
|
|
6324
|
-
}
|
|
6434
|
+
};
|
|
6325
6435
|
});
|
|
6326
6436
|
return instanceMappings;
|
|
6327
6437
|
};
|
|
@@ -6332,9 +6442,20 @@ var parseVariableFontInstances_default = parseVariableFontInstances;
|
|
|
6332
6442
|
var updateTypefaceDocument = async (doc_id, fontRefs, variableRefs, subfamilies, uniqueSubfamilies, subfamiliesArray, preferredStyleRef, newPreferredStyle, stylesObject, client, setStatus, setError) => {
|
|
6333
6443
|
console.log("Updating typeface document with new fonts:", { fontRefs, variableRefs, subfamilies, uniqueSubfamilies });
|
|
6334
6444
|
setStatus("Updating typeface references...");
|
|
6445
|
+
const dedupeRefs = (existing, incoming) => {
|
|
6446
|
+
const merged = [...existing || []];
|
|
6447
|
+
const existingRefs = new Set(merged.map((r) => r._ref).filter(Boolean));
|
|
6448
|
+
incoming.forEach((ref) => {
|
|
6449
|
+
if (ref._ref && !existingRefs.has(ref._ref)) {
|
|
6450
|
+
merged.push(ref);
|
|
6451
|
+
existingRefs.add(ref._ref);
|
|
6452
|
+
}
|
|
6453
|
+
});
|
|
6454
|
+
return merged;
|
|
6455
|
+
};
|
|
6335
6456
|
let patch = {
|
|
6336
|
-
"styles.fonts": stylesObject.fonts
|
|
6337
|
-
"styles.variableFont": (stylesObject == null ? void 0 : stylesObject.variableFont
|
|
6457
|
+
"styles.fonts": dedupeRefs(stylesObject.fonts, fontRefs),
|
|
6458
|
+
"styles.variableFont": dedupeRefs(stylesObject == null ? void 0 : stylesObject.variableFont, variableRefs)
|
|
6338
6459
|
};
|
|
6339
6460
|
setStatus("Organising font subfamilies...");
|
|
6340
6461
|
subfamiliesArray = subfamiliesArray || [];
|
|
@@ -6539,7 +6660,7 @@ async function executeUploadPlan({
|
|
|
6539
6660
|
return result;
|
|
6540
6661
|
}
|
|
6541
6662
|
async function executeSingleFont({ entry, plan, client, progress, onProgress }) {
|
|
6542
|
-
var _a, _b, _c, _d
|
|
6663
|
+
var _a, _b, _c, _d;
|
|
6543
6664
|
const fontProgress = progress[entry.tempId];
|
|
6544
6665
|
fontProgress.status = EXECUTION_STATUS.UPLOADING_ASSETS;
|
|
6545
6666
|
if (onProgress) {
|
|
@@ -6656,7 +6777,7 @@ async function executeSingleFont({ entry, plan, client, progress, onProgress })
|
|
|
6656
6777
|
_key: _nanoid.nanoid.call(void 0, ),
|
|
6657
6778
|
title: entry.title,
|
|
6658
6779
|
slug: { _type: "slug", current: fontDocId },
|
|
6659
|
-
typefaceName:
|
|
6780
|
+
typefaceName: plan.settings.typefaceTitle || entry.title,
|
|
6660
6781
|
style: entry.style,
|
|
6661
6782
|
variableFont: entry.variableFont,
|
|
6662
6783
|
weightName: entry.weightName,
|
|
@@ -6667,7 +6788,6 @@ async function executeSingleFont({ entry, plan, client, progress, onProgress })
|
|
|
6667
6788
|
normalWeight: true,
|
|
6668
6789
|
fileInput
|
|
6669
6790
|
};
|
|
6670
|
-
fontDoc.typefaceName = ((_j = (_i = (_h = Object.values(plan.fonts)[0]) == null ? void 0 : _h.decisions) == null ? void 0 : _i.title) == null ? void 0 : _j.original) ? plan.settings.typefaceTitle || fontDoc.typefaceName : fontDoc.typefaceName;
|
|
6671
6791
|
if (entry.metaData) fontDoc.metaData = entry.metaData;
|
|
6672
6792
|
if (entry.metrics) fontDoc.metrics = entry.metrics;
|
|
6673
6793
|
if (entry.variableAxes) fontDoc.variableAxes = entry.variableAxes;
|
|
@@ -6896,10 +7016,295 @@ function UploadStep3Execute({
|
|
|
6896
7016
|
)))), execState.status !== "complete" && execState.status !== "error" && /* @__PURE__ */ _react2.default.createElement(_ui.Card, { tone: "caution", border: true, radius: 2, padding: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_icons.WarningOutlineIcon, { style: { flexShrink: 0 } }), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, weight: "semibold" }, "Do not close or reload this tab"))), /* @__PURE__ */ _react2.default.createElement(_ui.Box, { style: { maxHeight: 400, overflowY: "auto" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 1 }, fontEntries.map((entry) => {
|
|
6897
7017
|
const progress = execState.progress[entry.tempId];
|
|
6898
7018
|
const status = (progress == null ? void 0 : progress.status) || EXECUTION_STATUS.QUEUED;
|
|
6899
|
-
return /* @__PURE__ */ _react2.default.createElement(_ui.Card, { key: entry.tempId, border: true, radius: 1, padding: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, style: {
|
|
7019
|
+
return /* @__PURE__ */ _react2.default.createElement(_ui.Card, { key: entry.tempId, border: true, radius: 1, padding: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, style: { flex: 1 } }, entry.title), /* @__PURE__ */ _react2.default.createElement(_ui.Box, { style: { width: 120, flexShrink: 0, textAlign: "right" } }, status === EXECUTION_STATUS.QUEUED && /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { mode: "outline", fontSize: 0 }, "Queued"), status === EXECUTION_STATUS.UPLOADING_ASSETS && /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 1, align: "center", justify: "flex-end" }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true }, (progress == null ? void 0 : progress.currentFile) || "Uploading..."), /* @__PURE__ */ _react2.default.createElement(_ui.Spinner, { style: { width: 12, height: 12 } })), (status === EXECUTION_STATUS.GENERATING_CSS || status === EXECUTION_STATUS.GENERATING_METADATA) && /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 1, align: "center", justify: "flex-end" }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true }, status === EXECUTION_STATUS.GENERATING_CSS ? "CSS" : "Metadata"), /* @__PURE__ */ _react2.default.createElement(_ui.Spinner, { style: { width: 12, height: 12 } })), status === EXECUTION_STATUS.CREATING_DOCUMENT && /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 1, align: "center", justify: "flex-end" }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true }, "Creating doc"), /* @__PURE__ */ _react2.default.createElement(_ui.Spinner, { style: { width: 12, height: 12 } })), status === EXECUTION_STATUS.COMPLETE && /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { tone: "positive", fontSize: 0 }, "Done"), status === EXECUTION_STATUS.ERROR && /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { tone: "critical", fontSize: 0 }, "Failed"))), status === EXECUTION_STATUS.ERROR && (progress == null ? void 0 : progress.error) && /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true, style: { marginTop: 4 } }, progress.error));
|
|
6900
7020
|
}))), execState.error && /* @__PURE__ */ _react2.default.createElement(_ui.Card, { tone: "critical", border: true, padding: 3, radius: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1 }, execState.error)));
|
|
6901
7021
|
}
|
|
6902
7022
|
|
|
7023
|
+
// src/components/UploadStep3bInstances.jsx
|
|
7024
|
+
|
|
7025
|
+
|
|
7026
|
+
|
|
7027
|
+
|
|
7028
|
+
function UploadStep3bInstances({
|
|
7029
|
+
plan,
|
|
7030
|
+
executionResult,
|
|
7031
|
+
client,
|
|
7032
|
+
typefaceTitle,
|
|
7033
|
+
onComplete
|
|
7034
|
+
}) {
|
|
7035
|
+
const [loading, setLoading] = _react.useState.call(void 0, true);
|
|
7036
|
+
const [saving, setSaving] = _react.useState.call(void 0, false);
|
|
7037
|
+
const [vfMappings, setVfMappings] = _react.useState.call(void 0, {});
|
|
7038
|
+
const [allStaticFonts, setAllStaticFonts] = _react.useState.call(void 0, []);
|
|
7039
|
+
const [filterUnmatched, setFilterUnmatched] = _react.useState.call(void 0, false);
|
|
7040
|
+
const vfEntries = _react.useMemo.call(void 0,
|
|
7041
|
+
() => Object.values(plan.fonts).filter((f) => f.variableFont && f.status !== "error"),
|
|
7042
|
+
[plan.fonts]
|
|
7043
|
+
);
|
|
7044
|
+
const runMatching = _react.useCallback.call(void 0, async () => {
|
|
7045
|
+
var _a;
|
|
7046
|
+
setLoading(true);
|
|
7047
|
+
const mappings = {};
|
|
7048
|
+
let staticFonts = [];
|
|
7049
|
+
try {
|
|
7050
|
+
const typeface = await client.fetch(
|
|
7051
|
+
`*[_type == 'typeface' && title == $typefaceTitle][0]{
|
|
7052
|
+
'fonts': styles.fonts[]-> {
|
|
7053
|
+
_id, title, subfamily, style, weight, weightName, metaData, variableFont
|
|
7054
|
+
}
|
|
7055
|
+
}`,
|
|
7056
|
+
{ typefaceTitle }
|
|
7057
|
+
);
|
|
7058
|
+
if (((_a = typeface == null ? void 0 : typeface.fonts) == null ? void 0 : _a.length) > 0) {
|
|
7059
|
+
staticFonts = typeface.fonts.filter((f) => !f.variableFont);
|
|
7060
|
+
}
|
|
7061
|
+
if (staticFonts.length === 0) {
|
|
7062
|
+
staticFonts = await client.fetch(
|
|
7063
|
+
`*[_type == 'font' && typefaceName == $typefaceTitle && variableFont != true]{
|
|
7064
|
+
_id, title, subfamily, style, weight, weightName, metaData
|
|
7065
|
+
}`,
|
|
7066
|
+
{ typefaceTitle }
|
|
7067
|
+
);
|
|
7068
|
+
}
|
|
7069
|
+
} catch (err) {
|
|
7070
|
+
console.error("[InstanceMapper] Failed to fetch static fonts:", err);
|
|
7071
|
+
}
|
|
7072
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
7073
|
+
staticFonts.forEach((f) => {
|
|
7074
|
+
if (f._id && !deduped.has(f._id)) deduped.set(f._id, f);
|
|
7075
|
+
});
|
|
7076
|
+
staticFonts = [...deduped.values()];
|
|
7077
|
+
console.log(`[InstanceMapper] Found ${staticFonts.length} static fonts for "${typefaceTitle}"`);
|
|
7078
|
+
setAllStaticFonts(staticFonts);
|
|
7079
|
+
for (const vf of vfEntries) {
|
|
7080
|
+
try {
|
|
7081
|
+
const vfDoc = await client.fetch(
|
|
7082
|
+
`*[_id == $id][0]{
|
|
7083
|
+
_id, title, typefaceName, variableFont, variableInstances, metaData
|
|
7084
|
+
}`,
|
|
7085
|
+
{ id: vf.documentId }
|
|
7086
|
+
);
|
|
7087
|
+
if (!vfDoc) {
|
|
7088
|
+
console.warn(`[InstanceMapper] VF document not found: ${vf.documentId}`);
|
|
7089
|
+
mappings[vf.tempId] = [];
|
|
7090
|
+
continue;
|
|
7091
|
+
}
|
|
7092
|
+
console.log(`[InstanceMapper] Running matcher for VF: ${vfDoc.title}, variableInstances: ${vfDoc.variableInstances ? "present" : "missing"}`);
|
|
7093
|
+
const instanceMappings = await parseVariableFontInstances(vfDoc, client);
|
|
7094
|
+
console.log(`[InstanceMapper] Matched ${instanceMappings.filter((m) => m.value).length}/${instanceMappings.length} instances for ${vfDoc.title}`);
|
|
7095
|
+
mappings[vf.tempId] = instanceMappings.map((m) => {
|
|
7096
|
+
var _a2;
|
|
7097
|
+
return {
|
|
7098
|
+
instanceName: m.key,
|
|
7099
|
+
matchedFontId: ((_a2 = m.value) == null ? void 0 : _a2._ref) || "",
|
|
7100
|
+
matchedFontTitle: "",
|
|
7101
|
+
_key: m._key || _nanoid.nanoid.call(void 0, )
|
|
7102
|
+
};
|
|
7103
|
+
});
|
|
7104
|
+
} catch (err) {
|
|
7105
|
+
console.error(`[InstanceMapper] Error matching VF ${vf.documentId}:`, err);
|
|
7106
|
+
mappings[vf.tempId] = [];
|
|
7107
|
+
}
|
|
7108
|
+
}
|
|
7109
|
+
const allMatchedIds = /* @__PURE__ */ new Set();
|
|
7110
|
+
Object.values(mappings).forEach((m) => m.forEach((i) => {
|
|
7111
|
+
if (i.matchedFontId) allMatchedIds.add(i.matchedFontId);
|
|
7112
|
+
}));
|
|
7113
|
+
if (allMatchedIds.size > 0) {
|
|
7114
|
+
try {
|
|
7115
|
+
const titles = await client.fetch(`*[_id in $ids]{ _id, title }`, { ids: [...allMatchedIds] });
|
|
7116
|
+
const titleMap = {};
|
|
7117
|
+
titles.forEach((t) => {
|
|
7118
|
+
titleMap[t._id] = t.title;
|
|
7119
|
+
});
|
|
7120
|
+
Object.values(mappings).forEach((m) => {
|
|
7121
|
+
m.forEach((i) => {
|
|
7122
|
+
if (i.matchedFontId) i.matchedFontTitle = titleMap[i.matchedFontId] || i.matchedFontId;
|
|
7123
|
+
});
|
|
7124
|
+
});
|
|
7125
|
+
} catch (err) {
|
|
7126
|
+
console.warn("[InstanceMapper] Failed to resolve font titles:", err);
|
|
7127
|
+
}
|
|
7128
|
+
}
|
|
7129
|
+
setVfMappings(mappings);
|
|
7130
|
+
setLoading(false);
|
|
7131
|
+
}, [vfEntries, client, typefaceTitle]);
|
|
7132
|
+
_react.useEffect.call(void 0, () => {
|
|
7133
|
+
runMatching();
|
|
7134
|
+
}, [runMatching]);
|
|
7135
|
+
const claimedFontIds = _react.useMemo.call(void 0, () => {
|
|
7136
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
7137
|
+
Object.values(vfMappings).forEach((mappings) => {
|
|
7138
|
+
mappings.forEach((m) => {
|
|
7139
|
+
if (m.matchedFontId) claimed.add(m.matchedFontId);
|
|
7140
|
+
});
|
|
7141
|
+
});
|
|
7142
|
+
return claimed;
|
|
7143
|
+
}, [vfMappings]);
|
|
7144
|
+
const handleMappingChange = _react.useCallback.call(void 0, (vfTempId, instanceKey, fontId) => {
|
|
7145
|
+
const font = allStaticFonts.find((sf) => sf._id === fontId);
|
|
7146
|
+
setVfMappings((prev) => ({
|
|
7147
|
+
...prev,
|
|
7148
|
+
[vfTempId]: prev[vfTempId].map(
|
|
7149
|
+
(m) => m._key === instanceKey ? { ...m, matchedFontId: fontId, matchedFontTitle: (font == null ? void 0 : font.title) || fontId } : m
|
|
7150
|
+
)
|
|
7151
|
+
}));
|
|
7152
|
+
}, [allStaticFonts]);
|
|
7153
|
+
const handleSave = _react.useCallback.call(void 0, async () => {
|
|
7154
|
+
setSaving(true);
|
|
7155
|
+
const errors = [];
|
|
7156
|
+
for (const vf of vfEntries) {
|
|
7157
|
+
const mappings = vfMappings[vf.tempId] || [];
|
|
7158
|
+
const references = mappings.filter((m) => m.matchedFontId).map((m) => ({
|
|
7159
|
+
_key: _nanoid.nanoid.call(void 0, ),
|
|
7160
|
+
_type: "object",
|
|
7161
|
+
key: m.instanceName,
|
|
7162
|
+
value: {
|
|
7163
|
+
_type: "reference",
|
|
7164
|
+
_ref: m.matchedFontId,
|
|
7165
|
+
_weak: true
|
|
7166
|
+
}
|
|
7167
|
+
}));
|
|
7168
|
+
try {
|
|
7169
|
+
await client.patch(vf.documentId).set({
|
|
7170
|
+
variableInstanceReferences: references
|
|
7171
|
+
}).commit();
|
|
7172
|
+
console.log(`Patched VF instance mappings: ${vf.documentId} (${references.length} instances)`);
|
|
7173
|
+
} catch (err) {
|
|
7174
|
+
console.error(`Failed to patch VF ${vf.documentId}:`, err);
|
|
7175
|
+
errors.push({ vfTitle: vf.title, error: err.message });
|
|
7176
|
+
}
|
|
7177
|
+
}
|
|
7178
|
+
setSaving(false);
|
|
7179
|
+
onComplete({ success: errors.length === 0, errors });
|
|
7180
|
+
}, [vfEntries, vfMappings, client, onComplete]);
|
|
7181
|
+
const totalInstances = Object.values(vfMappings).reduce((sum, m) => sum + m.length, 0);
|
|
7182
|
+
const matchedInstances = Object.values(vfMappings).reduce(
|
|
7183
|
+
(sum, m) => sum + m.filter((i) => i.matchedFontId).length,
|
|
7184
|
+
0
|
|
7185
|
+
);
|
|
7186
|
+
const unmatchedInstances = totalInstances - matchedInstances;
|
|
7187
|
+
const getAutocompleteOptions = _react.useCallback.call(void 0, (currentFontId) => {
|
|
7188
|
+
return allStaticFonts.filter((sf) => !claimedFontIds.has(sf._id) || sf._id === currentFontId).map((sf) => ({
|
|
7189
|
+
value: sf._id,
|
|
7190
|
+
payload: sf
|
|
7191
|
+
}));
|
|
7192
|
+
}, [allStaticFonts, claimedFontIds]);
|
|
7193
|
+
if (loading) {
|
|
7194
|
+
return /* @__PURE__ */ _react2.default.createElement(_ui.Card, { border: true, padding: 4, radius: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 3, justify: "center" }, /* @__PURE__ */ _react2.default.createElement(_ui.Spinner, null), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1 }, "Matching variable font instances to static fonts...")));
|
|
7195
|
+
}
|
|
7196
|
+
if (vfEntries.length === 0) {
|
|
7197
|
+
onComplete({ success: true, errors: [] });
|
|
7198
|
+
return null;
|
|
7199
|
+
}
|
|
7200
|
+
return /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 4 }, /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 2, weight: "semibold" }, "Map Variable Font Instances"), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, muted: true }, "Review the auto-matched instances below. Each named instance should map to its corresponding static font document.")), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 2, align: "center" }, /* @__PURE__ */ _react2.default.createElement(
|
|
7201
|
+
_ui.Button,
|
|
7202
|
+
{
|
|
7203
|
+
mode: "ghost",
|
|
7204
|
+
tone: "primary",
|
|
7205
|
+
icon: _icons.SearchIcon,
|
|
7206
|
+
text: "Re-run Matching",
|
|
7207
|
+
fontSize: 0,
|
|
7208
|
+
padding: 2,
|
|
7209
|
+
onClick: runMatching,
|
|
7210
|
+
disabled: loading,
|
|
7211
|
+
style: { cursor: "pointer" }
|
|
7212
|
+
}
|
|
7213
|
+
), /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { tone: "positive", fontSize: 0 }, matchedInstances, " matched"), unmatchedInstances > 0 && /* @__PURE__ */ _react2.default.createElement(
|
|
7214
|
+
_ui.Badge,
|
|
7215
|
+
{
|
|
7216
|
+
tone: "critical",
|
|
7217
|
+
fontSize: 0,
|
|
7218
|
+
style: { cursor: "pointer" },
|
|
7219
|
+
onClick: () => setFilterUnmatched((v) => !v)
|
|
7220
|
+
},
|
|
7221
|
+
unmatchedInstances,
|
|
7222
|
+
" unmatched ",
|
|
7223
|
+
filterUnmatched ? "(showing)" : ""
|
|
7224
|
+
), filterUnmatched && /* @__PURE__ */ _react2.default.createElement(
|
|
7225
|
+
_ui.Badge,
|
|
7226
|
+
{
|
|
7227
|
+
mode: "outline",
|
|
7228
|
+
fontSize: 0,
|
|
7229
|
+
style: { cursor: "pointer" },
|
|
7230
|
+
onClick: () => setFilterUnmatched(false)
|
|
7231
|
+
},
|
|
7232
|
+
"Clear filter"
|
|
7233
|
+
), /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { mode: "outline", fontSize: 0 }, allStaticFonts.length, " fonts available")), vfEntries.map((vf) => {
|
|
7234
|
+
const mappings = vfMappings[vf.tempId] || [];
|
|
7235
|
+
const displayMappings = filterUnmatched ? mappings.filter((m) => !m.matchedFontId) : mappings;
|
|
7236
|
+
const vfMatched = mappings.filter((m) => m.matchedFontId).length;
|
|
7237
|
+
return /* @__PURE__ */ _react2.default.createElement(_ui.Card, { key: vf.tempId, border: true, padding: 3, radius: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 3 }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { tone: "primary", fontSize: 0 }, "VF"), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, weight: "semibold" }, vf.title), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true, style: { marginLeft: "auto" } }, vfMatched, "/", mappings.length, " matched")), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2, paddingY: 1, style: { borderBottom: "1px solid var(--card-border-color)" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Box, { style: { width: 20 } }), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, weight: "semibold", muted: true, style: { flex: 1 } }, "Instance"), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, weight: "semibold", muted: true, style: { flex: 2 } }, "Static Font Document")), /* @__PURE__ */ _react2.default.createElement(_ui.Stack, { space: 1 }, displayMappings.map((mapping) => {
|
|
7238
|
+
const isMatched = !!mapping.matchedFontId;
|
|
7239
|
+
const options = getAutocompleteOptions(mapping.matchedFontId);
|
|
7240
|
+
return /* @__PURE__ */ _react2.default.createElement(
|
|
7241
|
+
_ui.Flex,
|
|
7242
|
+
{
|
|
7243
|
+
key: mapping._key,
|
|
7244
|
+
align: "center",
|
|
7245
|
+
gap: 2,
|
|
7246
|
+
paddingY: 2,
|
|
7247
|
+
style: { borderBottom: "1px solid var(--card-border-color)" }
|
|
7248
|
+
},
|
|
7249
|
+
/* @__PURE__ */ _react2.default.createElement(_ui.Box, { style: { width: 20, flexShrink: 0 } }, isMatched ? /* @__PURE__ */ _react2.default.createElement(_icons.CheckmarkCircleIcon, { style: { color: "#43b649", fontSize: 16 } }) : /* @__PURE__ */ _react2.default.createElement(_icons.CloseCircleIcon, { style: { color: "#f03e2f", fontSize: 16 } })),
|
|
7250
|
+
/* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, style: { flex: 1, whiteSpace: "nowrap" } }, mapping.instanceName),
|
|
7251
|
+
/* @__PURE__ */ _react2.default.createElement(_ui.Box, { style: { flex: 2 } }, /* @__PURE__ */ _react2.default.createElement(
|
|
7252
|
+
_ui.Autocomplete,
|
|
7253
|
+
{
|
|
7254
|
+
id: `instance-${mapping._key}`,
|
|
7255
|
+
options,
|
|
7256
|
+
value: mapping.matchedFontId,
|
|
7257
|
+
placeholder: "Search for a font...",
|
|
7258
|
+
icon: _icons.SearchIcon,
|
|
7259
|
+
fontSize: 1,
|
|
7260
|
+
filterOption: (query, option) => {
|
|
7261
|
+
var _a, _b, _c, _d;
|
|
7262
|
+
const sf = option.payload;
|
|
7263
|
+
const q = query.toLowerCase();
|
|
7264
|
+
return ((_a = sf.title) == null ? void 0 : _a.toLowerCase().includes(q)) || ((_b = sf._id) == null ? void 0 : _b.toLowerCase().includes(q)) || ((_c = sf.weightName) == null ? void 0 : _c.toLowerCase().includes(q)) || String(sf.weight).includes(q) || ((_d = sf.subfamily) == null ? void 0 : _d.toLowerCase().includes(q));
|
|
7265
|
+
},
|
|
7266
|
+
renderOption: (option) => {
|
|
7267
|
+
const sf = option.payload;
|
|
7268
|
+
const isClaimed = claimedFontIds.has(sf._id) && sf._id !== mapping.matchedFontId;
|
|
7269
|
+
return /* @__PURE__ */ _react2.default.createElement(_ui.Card, { as: "button", padding: 2, style: { opacity: isClaimed ? 0.4 : 1 } }, /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { align: "center", gap: 2 }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1 }, sf.title), /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 0, muted: true }, sf.weight, " ", sf.style), sf.subfamily && sf.subfamily !== "Regular" && /* @__PURE__ */ _react2.default.createElement(_ui.Badge, { mode: "outline", fontSize: 0 }, sf.subfamily)));
|
|
7270
|
+
},
|
|
7271
|
+
renderValue: (value, option) => {
|
|
7272
|
+
if (option == null ? void 0 : option.payload) return option.payload.title;
|
|
7273
|
+
if (mapping.matchedFontTitle) return mapping.matchedFontTitle;
|
|
7274
|
+
const font = allStaticFonts.find((sf) => sf._id === value);
|
|
7275
|
+
return (font == null ? void 0 : font.title) || value;
|
|
7276
|
+
},
|
|
7277
|
+
onSelect: (value) => handleMappingChange(vf.tempId, mapping._key, value),
|
|
7278
|
+
openButton: true
|
|
7279
|
+
}
|
|
7280
|
+
))
|
|
7281
|
+
);
|
|
7282
|
+
})), mappings.length === 0 && /* @__PURE__ */ _react2.default.createElement(_ui.Text, { size: 1, muted: true }, "No named instances found in this variable font.")));
|
|
7283
|
+
}), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { justify: "flex-end", gap: 2, style: { position: "sticky", bottom: 0, background: "var(--card-bg-color)", paddingTop: 8, paddingBottom: 4 } }, /* @__PURE__ */ _react2.default.createElement(
|
|
7284
|
+
_ui.Button,
|
|
7285
|
+
{
|
|
7286
|
+
mode: "ghost",
|
|
7287
|
+
text: "Skip \u2014 I'll map instances later",
|
|
7288
|
+
fontSize: 1,
|
|
7289
|
+
padding: 3,
|
|
7290
|
+
onClick: () => onComplete({ success: true, errors: [], skipped: true }),
|
|
7291
|
+
style: { cursor: "pointer" }
|
|
7292
|
+
}
|
|
7293
|
+
), /* @__PURE__ */ _react2.default.createElement(
|
|
7294
|
+
_ui.Button,
|
|
7295
|
+
{
|
|
7296
|
+
mode: "default",
|
|
7297
|
+
tone: "positive",
|
|
7298
|
+
text: saving ? "Saving..." : `Save Mappings (${matchedInstances}/${totalInstances})`,
|
|
7299
|
+
fontSize: 1,
|
|
7300
|
+
padding: 3,
|
|
7301
|
+
disabled: saving,
|
|
7302
|
+
onClick: handleSave,
|
|
7303
|
+
style: { cursor: "pointer" }
|
|
7304
|
+
}
|
|
7305
|
+
)));
|
|
7306
|
+
}
|
|
7307
|
+
|
|
6903
7308
|
// src/components/UploadSummary.jsx
|
|
6904
7309
|
|
|
6905
7310
|
|
|
@@ -6995,7 +7400,8 @@ function UploadSummary({
|
|
|
6995
7400
|
var STEPS = [
|
|
6996
7401
|
{ key: 1, label: "Upload Files" },
|
|
6997
7402
|
{ key: 2, label: "Review" },
|
|
6998
|
-
{ key: 3, label: "Upload" }
|
|
7403
|
+
{ key: 3, label: "Upload" },
|
|
7404
|
+
{ key: 4, label: "Map Instances" }
|
|
6999
7405
|
];
|
|
7000
7406
|
function phaseToStep(phase) {
|
|
7001
7407
|
switch (phase) {
|
|
@@ -7031,10 +7437,17 @@ function UploadModal({
|
|
|
7031
7437
|
const [processingCancelled, setProcessingCancelled] = _react.useState.call(void 0, false);
|
|
7032
7438
|
const [executionResult, setExecutionResult] = _react.useState.call(void 0, null);
|
|
7033
7439
|
const [retryTempIds, setRetryTempIds] = _react.useState.call(void 0, null);
|
|
7440
|
+
const [instanceMappingPhase, setInstanceMappingPhase] = _react.useState.call(void 0, false);
|
|
7441
|
+
const [instanceMappingResult, setInstanceMappingResult] = _react.useState.call(void 0, null);
|
|
7034
7442
|
const cancelRef = _react.useRef.call(void 0, false);
|
|
7035
7443
|
const focusRef = _react.useRef.call(void 0, null);
|
|
7036
7444
|
const { weightKeywordList, italicKeywordList } = _react.useMemo.call(void 0, () => generateStyleKeywords(), []);
|
|
7037
|
-
const
|
|
7445
|
+
const hasVFs = _react.useMemo.call(void 0,
|
|
7446
|
+
() => Object.values(plan.fonts).some((f) => f.variableFont && f.status !== "error"),
|
|
7447
|
+
[plan.fonts]
|
|
7448
|
+
);
|
|
7449
|
+
const baseStep = phaseToStep(plan.phase);
|
|
7450
|
+
const currentStep = instanceMappingPhase ? 4 : plan.phase === PLAN_PHASE.COMPLETE && !instanceMappingResult ? baseStep : baseStep;
|
|
7038
7451
|
const isExecuting = plan.phase === PLAN_PHASE.EXECUTING;
|
|
7039
7452
|
_react.useEffect.call(void 0, () => {
|
|
7040
7453
|
if (!open || !isExecuting) return;
|
|
@@ -7061,7 +7474,7 @@ function UploadModal({
|
|
|
7061
7474
|
onClose();
|
|
7062
7475
|
}, [plan, isExecuting, onClose]);
|
|
7063
7476
|
const handleStartProcessing = _react.useCallback.call(void 0, async (files, settings) => {
|
|
7064
|
-
dispatch({ type: "SET_SETTINGS", settings });
|
|
7477
|
+
dispatch({ type: "SET_SETTINGS", settings: { ...settings, typefaceTitle } });
|
|
7065
7478
|
dispatch({ type: "SET_PHASE", phase: PLAN_PHASE.PROCESSING, totalFiles: files.length });
|
|
7066
7479
|
cancelRef.current = false;
|
|
7067
7480
|
setProcessingCancelled(false);
|
|
@@ -7104,7 +7517,16 @@ function UploadModal({
|
|
|
7104
7517
|
}, []);
|
|
7105
7518
|
const handleExecutionComplete = _react.useCallback.call(void 0, (result) => {
|
|
7106
7519
|
setExecutionResult(result);
|
|
7107
|
-
|
|
7520
|
+
if (hasVFs && result.success !== false) {
|
|
7521
|
+
setInstanceMappingPhase(true);
|
|
7522
|
+
dispatch({ type: "SET_PHASE", phase: PLAN_PHASE.COMPLETE });
|
|
7523
|
+
} else {
|
|
7524
|
+
dispatch({ type: "SET_PHASE", phase: PLAN_PHASE.COMPLETE });
|
|
7525
|
+
}
|
|
7526
|
+
}, [hasVFs]);
|
|
7527
|
+
const handleInstanceMappingComplete = _react.useCallback.call(void 0, (result) => {
|
|
7528
|
+
setInstanceMappingResult(result);
|
|
7529
|
+
setInstanceMappingPhase(false);
|
|
7108
7530
|
}, []);
|
|
7109
7531
|
if (!open) return null;
|
|
7110
7532
|
const handleStepClick = _react.useCallback.call(void 0, (stepKey) => {
|
|
@@ -7121,7 +7543,7 @@ function UploadModal({
|
|
|
7121
7543
|
_ui.Dialog,
|
|
7122
7544
|
{
|
|
7123
7545
|
id: "upload-modal",
|
|
7124
|
-
header: /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { direction: "column", gap: 3, style: { width: "100%" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { weight: "semibold", size: 2 }, "Upload Fonts"), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 1, style: { width: "100%" } }, STEPS.map((step, i) => {
|
|
7546
|
+
header: /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { direction: "column", gap: 3, style: { width: "100%" } }, /* @__PURE__ */ _react2.default.createElement(_ui.Text, { weight: "semibold", size: 2 }, "Upload Fonts"), /* @__PURE__ */ _react2.default.createElement(_ui.Flex, { gap: 1, style: { width: "100%" } }, STEPS.filter((step) => step.key !== 4 || hasVFs).map((step, i) => {
|
|
7125
7547
|
const isActive = currentStep === step.key;
|
|
7126
7548
|
const isCompleted = currentStep > step.key;
|
|
7127
7549
|
const isClickable = !isExecuting && step.key < currentStep;
|
|
@@ -7192,15 +7614,27 @@ function UploadModal({
|
|
|
7192
7614
|
handleExecutionComplete(result);
|
|
7193
7615
|
}
|
|
7194
7616
|
}
|
|
7195
|
-
), plan.phase === PLAN_PHASE.COMPLETE && /* @__PURE__ */ _react2.default.createElement(
|
|
7617
|
+
), plan.phase === PLAN_PHASE.COMPLETE && instanceMappingPhase && /* @__PURE__ */ _react2.default.createElement(
|
|
7618
|
+
UploadStep3bInstances,
|
|
7619
|
+
{
|
|
7620
|
+
plan,
|
|
7621
|
+
executionResult,
|
|
7622
|
+
client,
|
|
7623
|
+
typefaceTitle,
|
|
7624
|
+
onComplete: handleInstanceMappingComplete
|
|
7625
|
+
}
|
|
7626
|
+
), plan.phase === PLAN_PHASE.COMPLETE && !instanceMappingPhase && /* @__PURE__ */ _react2.default.createElement(
|
|
7196
7627
|
UploadSummary,
|
|
7197
7628
|
{
|
|
7198
7629
|
plan,
|
|
7199
7630
|
result: executionResult,
|
|
7631
|
+
instanceMappingResult,
|
|
7200
7632
|
onClose: handleClose,
|
|
7201
7633
|
onRetry: (failedTempIds) => {
|
|
7202
7634
|
setRetryTempIds(failedTempIds || null);
|
|
7203
7635
|
setExecutionResult(null);
|
|
7636
|
+
setInstanceMappingPhase(false);
|
|
7637
|
+
setInstanceMappingResult(null);
|
|
7204
7638
|
dispatch({ type: "SET_PHASE", phase: PLAN_PHASE.EXECUTING });
|
|
7205
7639
|
},
|
|
7206
7640
|
client,
|
|
@@ -7273,4 +7707,5 @@ function UploadModal({
|
|
|
7273
7707
|
|
|
7274
7708
|
|
|
7275
7709
|
|
|
7276
|
-
|
|
7710
|
+
|
|
7711
|
+
exports.parseFont = parseFont; exports.getNameString = getNameString; exports.getAllFeatureTags = getAllFeatureTags; exports.getCharacterSet = getCharacterSet; exports.getVariationAxes = getVariationAxes; exports.getNamedInstances = getNamedInstances; exports.getFontMetrics = getFontMetrics; exports.getFontMetadata = getFontMetadata; exports.getWeightClass = getWeightClass; exports.getFsSelection = getFsSelection; exports.getMacStyle = getMacStyle; exports.getItalicAngle = getItalicAngle; exports.getGlyphCount = getGlyphCount; exports.getFamilyClass = getFamilyClass; exports.escapeCssFontName = escapeCssFontName; exports.reverseSpellingLookup = reverseSpellingLookup; exports.expandAbbreviations = expandAbbreviations; exports.removeWeightNames = removeWeightNames; exports.generateStyleKeywords = generateStyleKeywords; exports.sanitizeForSanityId = sanitizeForSanityId; exports.readFontFile = readFontFile; exports.processFontFiles = processFontFiles; exports.extractFontMetadata = extractFontMetadata; exports.extractWeightName = extractWeightName; exports.extractWeightFromFullName = extractWeightFromFullName; exports.processSubfamilyName = processSubfamilyName; exports.processItalicKeywords = processItalicKeywords; exports.formatFontTitle = formatFontTitle; exports.addItalicToFontTitle = addItalicToFontTitle; exports.createFontObject = createFontObject; exports.determineWeight = determineWeight; exports.sortFontObjects = sortFontObjects; exports.logFontInfo = logFontInfo; exports.generateCssFile = generateCssFile; exports.generateFontData = generateFontData; exports.parseVariableFontInstances = parseVariableFontInstances; exports.parseVariableFontInstances_default = parseVariableFontInstances_default; exports.updateTypefaceDocument = updateTypefaceDocument; exports.PriceInput_default = PriceInput_default; exports.FONT_STATUS = FONT_STATUS; exports.PLAN_PHASE = PLAN_PHASE; exports.RECOMMENDATION = RECOMMENDATION; exports.EXECUTION_STATUS = EXECUTION_STATUS; exports.PLAN_VERSION = PLAN_VERSION; exports.createFontDecisions = createFontDecisions; exports.createEmptyPlan = createEmptyPlan; exports.planReducer = planReducer; exports.resolveExistingFont = resolveExistingFont; exports.buildUploadPlan = buildUploadPlan; exports.UploadStep1Settings = UploadStep1Settings; exports.ExistingDocumentResolver = ExistingDocumentResolver; exports.FontReviewCard_default = FontReviewCard_default; exports.BulkActions = BulkActions; exports.UploadStep2Review = UploadStep2Review; exports.executeUploadPlan = executeUploadPlan; exports.createInitialExecutionState = createInitialExecutionState; exports.executionReducer = executionReducer; exports.UploadStep3Execute = UploadStep3Execute; exports.UploadStep3bInstances = UploadStep3bInstances; exports.UploadSummary = UploadSummary; exports.UploadModal = UploadModal;
|