fontaine 0.8.0 → 0.8.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/README.md +32 -4
- package/dist/capsize-font-metrics.mjs +1 -1
- package/dist/fallbacks-Cj4LUWhi.d.cts +34 -0
- package/dist/fallbacks-Cj4LUWhi.d.mts +34 -0
- package/dist/index.cjs +138 -299
- package/dist/index.d.cts +65 -98
- package/dist/index.d.mts +64 -98
- package/dist/index.mjs +120 -277
- package/dist/metrics-ChAPPk2j.cjs +425 -0
- package/dist/metrics-DgPzfV2U.mjs +354 -0
- package/dist/postcss.cjs +91 -0
- package/dist/postcss.d.cts +52 -0
- package/dist/postcss.d.mts +52 -0
- package/dist/postcss.mjs +91 -0
- package/package.json +34 -15
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
let css_tree = require("css-tree");
|
|
2
|
+
let magic_regexp = require("magic-regexp");
|
|
3
|
+
let pathe = require("pathe");
|
|
4
|
+
let ufo = require("ufo");
|
|
5
|
+
let node_url = require("node:url");
|
|
6
|
+
let _capsizecss_unpack = require("@capsizecss/unpack");
|
|
7
|
+
let _capsizecss_unpack_fs = require("@capsizecss/unpack/fs");
|
|
8
|
+
//#region src/css.ts
|
|
9
|
+
function toPercentage(value, fractionDigits = 4) {
|
|
10
|
+
return `${+(value * 100).toFixed(fractionDigits)}%`;
|
|
11
|
+
}
|
|
12
|
+
function toCSS(properties, indent = 2) {
|
|
13
|
+
return Object.entries(properties).map(([key, value]) => `${" ".repeat(indent)}${key}: ${value};`).join("\n");
|
|
14
|
+
}
|
|
15
|
+
const QUOTES_RE = (0, magic_regexp.createRegExp)((0, magic_regexp.charIn)("\"'").at.lineStart().or((0, magic_regexp.charIn)("\"'").at.lineEnd()), ["g"]);
|
|
16
|
+
const withoutQuotes = (str) => str.trim().replace(QUOTES_RE, "");
|
|
17
|
+
const QUERY_OR_FRAGMENT_RE = (0, magic_regexp.createRegExp)((0, magic_regexp.charIn)("?#").and((0, magic_regexp.oneOrMore)(magic_regexp.char).optionally()).at.lineEnd());
|
|
18
|
+
/** Removes any `?query` or `#fragment` suffix, which is not part of the file a URL points to. */
|
|
19
|
+
function withoutQueryOrFragment(source) {
|
|
20
|
+
return source.replace(QUERY_OR_FRAGMENT_RE, "");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether a CSS URL may be resolved relative to the stylesheet that declared it, as opposed to
|
|
24
|
+
* the document root (`/font.woff2`) or an external location (`https:`, `//`, `data:`).
|
|
25
|
+
*
|
|
26
|
+
* Bare package specifiers and the webpack `~` convention are indistinguishable from
|
|
27
|
+
* stylesheet-relative paths here, so callers should fall back to their own resolver when
|
|
28
|
+
* resolving against the stylesheet finds nothing.
|
|
29
|
+
*/
|
|
30
|
+
function isStylesheetRelative(source) {
|
|
31
|
+
return !(0, ufo.hasProtocol)(source, { acceptRelative: true }) && !(0, pathe.isAbsolute)(source);
|
|
32
|
+
}
|
|
33
|
+
const cssWideKeywords = /* @__PURE__ */ new Set([
|
|
34
|
+
"inherit",
|
|
35
|
+
"initial",
|
|
36
|
+
"revert",
|
|
37
|
+
"revert-layer",
|
|
38
|
+
"unset"
|
|
39
|
+
]);
|
|
40
|
+
const genericCSSFamilies = /* @__PURE__ */ new Set([
|
|
41
|
+
"serif",
|
|
42
|
+
"sans-serif",
|
|
43
|
+
"monospace",
|
|
44
|
+
"cursive",
|
|
45
|
+
"fantasy",
|
|
46
|
+
"system-ui",
|
|
47
|
+
"ui-serif",
|
|
48
|
+
"ui-sans-serif",
|
|
49
|
+
"ui-monospace",
|
|
50
|
+
"ui-rounded",
|
|
51
|
+
"emoji",
|
|
52
|
+
"math",
|
|
53
|
+
"fangsong"
|
|
54
|
+
]);
|
|
55
|
+
const genericFamilyLocals = {
|
|
56
|
+
"serif": [
|
|
57
|
+
"Times New Roman",
|
|
58
|
+
"Tinos",
|
|
59
|
+
"Liberation Serif",
|
|
60
|
+
"DejaVu Serif",
|
|
61
|
+
"Times"
|
|
62
|
+
],
|
|
63
|
+
"sans-serif": [
|
|
64
|
+
"Arial",
|
|
65
|
+
"Arimo",
|
|
66
|
+
"Liberation Sans",
|
|
67
|
+
"DejaVu Sans",
|
|
68
|
+
"Helvetica"
|
|
69
|
+
],
|
|
70
|
+
"monospace": [
|
|
71
|
+
"Courier New",
|
|
72
|
+
"Cousine",
|
|
73
|
+
"Liberation Mono",
|
|
74
|
+
"DejaVu Sans Mono",
|
|
75
|
+
"Menlo"
|
|
76
|
+
],
|
|
77
|
+
"system-ui": [
|
|
78
|
+
"Segoe UI",
|
|
79
|
+
"Roboto",
|
|
80
|
+
"Helvetica Neue",
|
|
81
|
+
"Cantarell",
|
|
82
|
+
"Ubuntu",
|
|
83
|
+
"Noto Sans"
|
|
84
|
+
],
|
|
85
|
+
"cursive": [
|
|
86
|
+
"Comic Sans MS",
|
|
87
|
+
"Apple Chancery",
|
|
88
|
+
"Segoe Script",
|
|
89
|
+
"URW Chancery L"
|
|
90
|
+
],
|
|
91
|
+
"fantasy": [
|
|
92
|
+
"Impact",
|
|
93
|
+
"Papyrus",
|
|
94
|
+
"Luminari"
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
genericFamilyLocals["ui-serif"] = genericFamilyLocals.serif;
|
|
98
|
+
genericFamilyLocals["ui-sans-serif"] = genericFamilyLocals["sans-serif"];
|
|
99
|
+
genericFamilyLocals["ui-monospace"] = genericFamilyLocals.monospace;
|
|
100
|
+
genericFamilyLocals["ui-rounded"] = genericFamilyLocals["system-ui"];
|
|
101
|
+
const fontProperties = /* @__PURE__ */ new Set([
|
|
102
|
+
"font-weight",
|
|
103
|
+
"font-style",
|
|
104
|
+
"font-stretch"
|
|
105
|
+
]);
|
|
106
|
+
/**
|
|
107
|
+
* Extracts font family and source information from a CSS @font-face rule using css-tree.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} css - The CSS containing @font-face rules
|
|
110
|
+
* @returns Array<{ family?: string, source?: string }> - Array of objects with font family and source information
|
|
111
|
+
*/
|
|
112
|
+
function parseFontFace(css) {
|
|
113
|
+
const families = [];
|
|
114
|
+
const ast = typeof css === "string" ? (0, css_tree.parse)(css, { positions: true }) : css;
|
|
115
|
+
(0, css_tree.walk)(ast, {
|
|
116
|
+
visit: "Atrule",
|
|
117
|
+
enter(node) {
|
|
118
|
+
if (node.name !== "font-face") return;
|
|
119
|
+
let family;
|
|
120
|
+
const sources = [];
|
|
121
|
+
const properties = {};
|
|
122
|
+
if (node.block) (0, css_tree.walk)(node.block, {
|
|
123
|
+
visit: "Declaration",
|
|
124
|
+
enter(declaration) {
|
|
125
|
+
if (declaration.property === "font-family" && declaration.value.type === "Value") for (const child of declaration.value.children) {
|
|
126
|
+
if (child.type === "String") {
|
|
127
|
+
family = withoutQuotes(child.value);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (child.type === "Identifier" && !genericCSSFamilies.has(child.name)) {
|
|
131
|
+
family = child.name;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (fontProperties.has(declaration.property)) {
|
|
136
|
+
if (declaration.value.type === "Value") for (const child of declaration.value.children) {
|
|
137
|
+
const hasValue = !!properties[declaration.property];
|
|
138
|
+
properties[declaration.property] ||= "";
|
|
139
|
+
properties[declaration.property] += (hasValue ? " " : "") + (0, css_tree.generate)(child);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (declaration.property === "src") (0, css_tree.walk)(declaration.value, {
|
|
143
|
+
visit: "Url",
|
|
144
|
+
enter(urlNode) {
|
|
145
|
+
const source = withoutQuotes(urlNode.value);
|
|
146
|
+
if (source) sources.push(source);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
if (family) {
|
|
152
|
+
for (const source of sources) families.push({
|
|
153
|
+
index: node.loc.start.offset,
|
|
154
|
+
family,
|
|
155
|
+
source,
|
|
156
|
+
properties
|
|
157
|
+
});
|
|
158
|
+
if (!sources.length) families.push({
|
|
159
|
+
index: node.loc.start.offset,
|
|
160
|
+
family,
|
|
161
|
+
properties
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return families;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Generates a fallback name based on the first font family specified in the input string.
|
|
170
|
+
* @param {string} name - The full font family string.
|
|
171
|
+
* @returns {string} - The fallback font name.
|
|
172
|
+
*/
|
|
173
|
+
function generateFallbackName(name) {
|
|
174
|
+
return `${withoutQuotes(name.split(",").shift())} fallback`;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Generates a CSS `@font-face' declaration for a font, taking fallback and resizing into account.
|
|
178
|
+
* @param {FontFaceMetrics} metrics - The metrics of the preferred font. See {@link FontFaceMetrics}.
|
|
179
|
+
* @param {FallbackOptions} fallback - The fallback options, including name, font and optional metrics. See {@link FallbackOptions}.
|
|
180
|
+
* @returns {string} - The full `@font-face` CSS declaration.
|
|
181
|
+
*/
|
|
182
|
+
function generateFontFace(metrics, fallback) {
|
|
183
|
+
const { name: fallbackName, font: fallbackFontName, metrics: fallbackMetrics, ...properties } = fallback;
|
|
184
|
+
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
|
|
185
|
+
const fallbackFontXAvgRatio = fallbackMetrics ? fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm : 1;
|
|
186
|
+
const sizeAdjust = fallbackMetrics && preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
|
|
187
|
+
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
|
|
188
|
+
const ascentOverride = metrics.ascent / adjustedEmSquare;
|
|
189
|
+
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
|
|
190
|
+
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
|
|
191
|
+
return `@font-face {\n${toCSS({
|
|
192
|
+
"font-family": JSON.stringify(fallbackName),
|
|
193
|
+
"src": renderLocalSrc(fallbackFontName),
|
|
194
|
+
"size-adjust": toPercentage(sizeAdjust),
|
|
195
|
+
"ascent-override": toPercentage(ascentOverride),
|
|
196
|
+
"descent-override": toPercentage(descentOverride),
|
|
197
|
+
"line-gap-override": toPercentage(lineGapOverride),
|
|
198
|
+
...properties
|
|
199
|
+
})}\n}\n`;
|
|
200
|
+
}
|
|
201
|
+
function renderLocalSrc(font) {
|
|
202
|
+
return (genericFamilyLocals[withoutQuotes(font).toLowerCase()] || [font]).map((local) => `local(${JSON.stringify(local)})`).join(", ");
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
205
|
+
//#region src/fallbacks.ts
|
|
206
|
+
/**
|
|
207
|
+
* Default fallback font stacks for each font category.
|
|
208
|
+
* These are system fonts that work across different platforms.
|
|
209
|
+
*/
|
|
210
|
+
const DEFAULT_CATEGORY_FALLBACKS = {
|
|
211
|
+
"sans-serif": [
|
|
212
|
+
"BlinkMacSystemFont",
|
|
213
|
+
"Segoe UI",
|
|
214
|
+
"Helvetica Neue",
|
|
215
|
+
"Arial",
|
|
216
|
+
"Noto Sans"
|
|
217
|
+
],
|
|
218
|
+
"serif": [
|
|
219
|
+
"Times New Roman",
|
|
220
|
+
"Georgia",
|
|
221
|
+
"Noto Serif"
|
|
222
|
+
],
|
|
223
|
+
"monospace": [
|
|
224
|
+
"Courier New",
|
|
225
|
+
"Roboto Mono",
|
|
226
|
+
"Noto Sans Mono"
|
|
227
|
+
],
|
|
228
|
+
"display": [
|
|
229
|
+
"BlinkMacSystemFont",
|
|
230
|
+
"Segoe UI",
|
|
231
|
+
"Helvetica Neue",
|
|
232
|
+
"Arial",
|
|
233
|
+
"Noto Sans"
|
|
234
|
+
],
|
|
235
|
+
"handwriting": [
|
|
236
|
+
"BlinkMacSystemFont",
|
|
237
|
+
"Segoe UI",
|
|
238
|
+
"Helvetica Neue",
|
|
239
|
+
"Arial",
|
|
240
|
+
"Noto Sans"
|
|
241
|
+
]
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Resolves the appropriate fallback fonts for a given font family.
|
|
245
|
+
*
|
|
246
|
+
* Resolution order:
|
|
247
|
+
* 1. If fallbacks is an array, use it as a global override
|
|
248
|
+
* 2. If fallbacks is an object with the font family key, use that override
|
|
249
|
+
* 3. If metrics contain a category, use the category-based fallbacks
|
|
250
|
+
* 4. Default to sans-serif category fallbacks
|
|
251
|
+
*
|
|
252
|
+
* @param options - Configuration for fallback resolution
|
|
253
|
+
* @returns Array of fallback font family names
|
|
254
|
+
*/
|
|
255
|
+
function resolveCategoryFallbacks(options) {
|
|
256
|
+
const { fontFamily, fallbacks, metrics, categoryFallbacks } = options;
|
|
257
|
+
const mergedCategoryFallbacks = { ...DEFAULT_CATEGORY_FALLBACKS };
|
|
258
|
+
if (categoryFallbacks) for (const category in categoryFallbacks) {
|
|
259
|
+
const categoryKey = category;
|
|
260
|
+
const categoryFallbacksList = categoryFallbacks[categoryKey];
|
|
261
|
+
if (categoryFallbacksList) mergedCategoryFallbacks[categoryKey] = categoryFallbacksList;
|
|
262
|
+
}
|
|
263
|
+
if (Array.isArray(fallbacks)) return fallbacks;
|
|
264
|
+
const familyFallback = fallbacks[fontFamily];
|
|
265
|
+
if (familyFallback) return familyFallback;
|
|
266
|
+
if (metrics?.category) {
|
|
267
|
+
const categoryFallback = mergedCategoryFallbacks[metrics.category];
|
|
268
|
+
if (categoryFallback) return categoryFallback;
|
|
269
|
+
}
|
|
270
|
+
return mergedCategoryFallbacks["sans-serif"];
|
|
271
|
+
}
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/metrics.ts
|
|
274
|
+
const metricCache = {};
|
|
275
|
+
function filterRequiredMetrics(font) {
|
|
276
|
+
return {
|
|
277
|
+
ascent: font.ascent,
|
|
278
|
+
descent: font.descent,
|
|
279
|
+
lineGap: font.lineGap,
|
|
280
|
+
unitsPerEm: font.unitsPerEm,
|
|
281
|
+
xWidthAvg: font.xWidthAvg,
|
|
282
|
+
category: font.category
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Retrieves the font metrics for a given font family from the metrics collection. Uses caching to avoid redundant calculations.
|
|
287
|
+
* @param {string} family - The name of the font family for which metrics are requested.
|
|
288
|
+
* @returns {Promise<FontFaceMetrics | null>} - A promise that resolves with the filtered font metrics or null if not found. See {@link FontFaceMetrics}.
|
|
289
|
+
* @async
|
|
290
|
+
*/
|
|
291
|
+
async function getMetricsForFamily(family) {
|
|
292
|
+
family = withoutQuotes(family);
|
|
293
|
+
if (family in metricCache) return metricCache[family] ?? null;
|
|
294
|
+
try {
|
|
295
|
+
const name = fontFamilyToCamelCase(family);
|
|
296
|
+
const { entireMetricsCollection } = await import("#capsize-font-metrics");
|
|
297
|
+
const metrics = entireMetricsCollection[name];
|
|
298
|
+
/* v8 ignore next 4 */
|
|
299
|
+
if (!("descent" in metrics)) {
|
|
300
|
+
metricCache[family] = null;
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
const filteredMetrics = filterRequiredMetrics(metrics);
|
|
304
|
+
metricCache[family] = filteredMetrics;
|
|
305
|
+
return filteredMetrics;
|
|
306
|
+
} catch {
|
|
307
|
+
metricCache[family] = null;
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const urlRequestCache = /* @__PURE__ */ new Map();
|
|
312
|
+
/**
|
|
313
|
+
* Reads font metrics from a specified source URL or file path. This function supports both local files and remote URLs.
|
|
314
|
+
* It caches the results to optimise subsequent requests for the same source.
|
|
315
|
+
* @param {URL | string} _source - The source URL or local file path from which to read the font metrics.
|
|
316
|
+
* @returns {Promise<FontFaceMetrics | null>} - A promise that resolves to the filtered font metrics or null if the source cannot be processed.
|
|
317
|
+
* @async
|
|
318
|
+
*/
|
|
319
|
+
async function readMetrics(_source) {
|
|
320
|
+
const source = typeof _source !== "string" && "href" in _source ? _source.href : _source;
|
|
321
|
+
if (source in metricCache) return metricCache[source] ?? null;
|
|
322
|
+
const { protocol } = (0, ufo.parseURL)(source);
|
|
323
|
+
if (!protocol) return null;
|
|
324
|
+
let metrics;
|
|
325
|
+
if (protocol === "file:") metrics = await (0, _capsizecss_unpack_fs.fromFile)((0, node_url.fileURLToPath)(source));
|
|
326
|
+
else if (urlRequestCache.has(source)) metrics = await urlRequestCache.get(source);
|
|
327
|
+
else {
|
|
328
|
+
const requestPromise = (0, _capsizecss_unpack.fromUrl)(source);
|
|
329
|
+
urlRequestCache.set(source, requestPromise);
|
|
330
|
+
metrics = await requestPromise;
|
|
331
|
+
}
|
|
332
|
+
const filteredMetrics = filterRequiredMetrics(metrics);
|
|
333
|
+
metricCache[source] = filteredMetrics;
|
|
334
|
+
return filteredMetrics;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Reads font metrics for a `src` URL declared in a stylesheet.
|
|
338
|
+
*
|
|
339
|
+
* A scheme-less, non-rooted URL is resolved against the stylesheet first, then handed to
|
|
340
|
+
* `resolvePath` if that yields no metrics: bare package specifiers and webpack's `~` prefix
|
|
341
|
+
* look identical to stylesheet-relative paths, and only the caller's resolver can map them.
|
|
342
|
+
*/
|
|
343
|
+
async function readMetricsForSource(source, importer, resolvePath) {
|
|
344
|
+
if (importer && (0, pathe.isAbsolute)(importer) && isStylesheetRelative(source)) {
|
|
345
|
+
const metrics = await readMetrics(new URL(source, (0, node_url.pathToFileURL)(importer))).catch(() => null);
|
|
346
|
+
if (metrics) return metrics;
|
|
347
|
+
}
|
|
348
|
+
return readMetrics(resolvePath(source));
|
|
349
|
+
}
|
|
350
|
+
function fontFamilyToCamelCase(str) {
|
|
351
|
+
return str.split(/[\s|-]/).filter(Boolean).map((s, i) => `${s.charAt(0)[i > 0 ? "toUpperCase" : "toLowerCase"]()}${s.slice(1)}`).join("");
|
|
352
|
+
}
|
|
353
|
+
//#endregion
|
|
354
|
+
Object.defineProperty(exports, "DEFAULT_CATEGORY_FALLBACKS", {
|
|
355
|
+
enumerable: true,
|
|
356
|
+
get: function() {
|
|
357
|
+
return DEFAULT_CATEGORY_FALLBACKS;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
Object.defineProperty(exports, "cssWideKeywords", {
|
|
361
|
+
enumerable: true,
|
|
362
|
+
get: function() {
|
|
363
|
+
return cssWideKeywords;
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
Object.defineProperty(exports, "generateFallbackName", {
|
|
367
|
+
enumerable: true,
|
|
368
|
+
get: function() {
|
|
369
|
+
return generateFallbackName;
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
Object.defineProperty(exports, "generateFontFace", {
|
|
373
|
+
enumerable: true,
|
|
374
|
+
get: function() {
|
|
375
|
+
return generateFontFace;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
Object.defineProperty(exports, "genericCSSFamilies", {
|
|
379
|
+
enumerable: true,
|
|
380
|
+
get: function() {
|
|
381
|
+
return genericCSSFamilies;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
Object.defineProperty(exports, "getMetricsForFamily", {
|
|
385
|
+
enumerable: true,
|
|
386
|
+
get: function() {
|
|
387
|
+
return getMetricsForFamily;
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
Object.defineProperty(exports, "parseFontFace", {
|
|
391
|
+
enumerable: true,
|
|
392
|
+
get: function() {
|
|
393
|
+
return parseFontFace;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
Object.defineProperty(exports, "readMetrics", {
|
|
397
|
+
enumerable: true,
|
|
398
|
+
get: function() {
|
|
399
|
+
return readMetrics;
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
Object.defineProperty(exports, "readMetricsForSource", {
|
|
403
|
+
enumerable: true,
|
|
404
|
+
get: function() {
|
|
405
|
+
return readMetricsForSource;
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
Object.defineProperty(exports, "resolveCategoryFallbacks", {
|
|
409
|
+
enumerable: true,
|
|
410
|
+
get: function() {
|
|
411
|
+
return resolveCategoryFallbacks;
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
Object.defineProperty(exports, "withoutQueryOrFragment", {
|
|
415
|
+
enumerable: true,
|
|
416
|
+
get: function() {
|
|
417
|
+
return withoutQueryOrFragment;
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
Object.defineProperty(exports, "withoutQuotes", {
|
|
421
|
+
enumerable: true,
|
|
422
|
+
get: function() {
|
|
423
|
+
return withoutQuotes;
|
|
424
|
+
}
|
|
425
|
+
});
|