@bamboocss/shared 1.11.2 → 1.11.3
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/index.cjs +377 -53
- package/dist/index.d.cts +116 -5
- package/dist/index.d.mts +116 -5
- package/dist/index.mjs +326 -2
- package/dist/shared.cjs +303 -20
- package/dist/shared.d.cts +101 -1
- package/dist/shared.d.mts +101 -1
- package/dist/shared.mjs +284 -1
- package/package.json +1 -1
- package/dist/uniq-DRfJ796t.mjs +0 -310
- package/dist/uniq-DcY1asOl.d.mts +0 -112
- package/dist/uniq-i0QQ2OJM.d.cts +0 -112
- package/dist/uniq-xizdZz1Z.cjs +0 -501
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { A as isObjectOrArray, C as filterBaseConditions, D as isBoolean, E as memo, M as isSymbol, O as isFunction, S as toHash, T as compact, _ as mergeProps, a as getPatternStyles, b as withoutImportant, c as isCssUnit, d as createCss, f as createMergeCss, g as walkObject, h as mapObject, i as getSlotRecipes, j as isString, k as isObject, l as isCssFunction, m as toResponsiveObject, n as splitProps, o as patternFns, p as normalizeStyleObject, r as getSlotCompoundVariant, s as isCssVar, t as uniq, u as hypenateProperty, v as isImportant, w as isBaseCondition, x as withoutSpace, y as markImportant } from "./uniq-DRfJ796t.mjs";
|
|
2
|
-
import { astish } from "./astish.mjs";
|
|
3
1
|
//#region src/arbitrary-value.ts
|
|
4
2
|
const getArbitraryValue = (_value) => {
|
|
5
3
|
if (!_value || typeof _value !== "string") return _value;
|
|
@@ -17,12 +15,39 @@ const getArbitraryValue = (_value) => {
|
|
|
17
15
|
return value;
|
|
18
16
|
};
|
|
19
17
|
//#endregion
|
|
18
|
+
//#region src/assert.ts
|
|
19
|
+
const isString = (v) => typeof v === "string";
|
|
20
|
+
const isBoolean = (v) => typeof v === "boolean";
|
|
21
|
+
const isFunction = (v) => typeof v === "function";
|
|
22
|
+
function isObject(value) {
|
|
23
|
+
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
const isSymbol = (v) => typeof v === "symbol";
|
|
26
|
+
const isObjectOrArray = (obj) => typeof obj === "object" && obj !== null;
|
|
27
|
+
//#endregion
|
|
20
28
|
//#region src/assign.ts
|
|
21
29
|
function assign(target, ...sources) {
|
|
22
30
|
for (const source of sources) for (const key in source) if (!target?.hasOwnProperty?.(key)) target[key] = source[key];
|
|
23
31
|
return target;
|
|
24
32
|
}
|
|
25
33
|
//#endregion
|
|
34
|
+
//#region src/astish.ts
|
|
35
|
+
const newRule = /(?:([\u0080-\uFFFF\w-%@]+) *:? *([^{;]+?);|([^;}{]*?) *{)|(}\s*)/g;
|
|
36
|
+
const ruleClean = /\/\*[^]*?\*\/| +/g;
|
|
37
|
+
const ruleNewline = /\n+/g;
|
|
38
|
+
const empty = " ";
|
|
39
|
+
const astish = (val, tree = [{}]) => {
|
|
40
|
+
if (!val) return tree[0];
|
|
41
|
+
let block, left;
|
|
42
|
+
while (block = newRule.exec(val.replace(ruleClean, ""))) if (block[4]) tree.shift();
|
|
43
|
+
else if (block[3]) {
|
|
44
|
+
left = block[3].replace(ruleNewline, empty).trim();
|
|
45
|
+
if (!left.includes("&") && !left.startsWith("@")) left = "& " + left;
|
|
46
|
+
tree.unshift(tree[0][left] = tree[0][left] || {});
|
|
47
|
+
} else tree[0][block[1]] = block[2].replace(ruleNewline, empty).trim();
|
|
48
|
+
return tree[0];
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
26
51
|
//#region src/cache-map.ts
|
|
27
52
|
var CacheMap = class {
|
|
28
53
|
cache;
|
|
@@ -125,6 +150,19 @@ const calc = { negate(x) {
|
|
|
125
150
|
return multiply(value, -1);
|
|
126
151
|
} };
|
|
127
152
|
//#endregion
|
|
153
|
+
//#region src/memo.ts
|
|
154
|
+
const memo = (fn) => {
|
|
155
|
+
const cache = /* @__PURE__ */ new Map();
|
|
156
|
+
const get = (...args) => {
|
|
157
|
+
const key = JSON.stringify(args);
|
|
158
|
+
if (cache.has(key)) return cache.get(key);
|
|
159
|
+
const result = fn(...args);
|
|
160
|
+
cache.set(key, result);
|
|
161
|
+
return result;
|
|
162
|
+
};
|
|
163
|
+
return get;
|
|
164
|
+
};
|
|
165
|
+
//#endregion
|
|
128
166
|
//#region src/camelcase-property.ts
|
|
129
167
|
const regex = /-(\w|$)/g;
|
|
130
168
|
const callback = (_dashChar, char) => char.toUpperCase();
|
|
@@ -141,6 +179,205 @@ const camelCaseRegex = /([a-z])([A-Z])/g;
|
|
|
141
179
|
const dashCase = (s) => s.replace(camelCaseRegex, "$1-$2").toLowerCase();
|
|
142
180
|
const uncapitalize = (s) => s.charAt(0).toLowerCase() + s.slice(1);
|
|
143
181
|
//#endregion
|
|
182
|
+
//#region src/compact.ts
|
|
183
|
+
function compact(value) {
|
|
184
|
+
return Object.fromEntries(Object.entries(value ?? {}).filter(([_, value]) => value !== void 0));
|
|
185
|
+
}
|
|
186
|
+
//#endregion
|
|
187
|
+
//#region src/condition.ts
|
|
188
|
+
const isBaseCondition = (v) => v === "base";
|
|
189
|
+
function filterBaseConditions(c) {
|
|
190
|
+
return c.slice().filter((v) => !isBaseCondition(v));
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/hash.ts
|
|
194
|
+
function toChar(code) {
|
|
195
|
+
return String.fromCharCode(code + (code > 25 ? 39 : 97));
|
|
196
|
+
}
|
|
197
|
+
function toName(code) {
|
|
198
|
+
let name = "";
|
|
199
|
+
let x;
|
|
200
|
+
for (x = Math.abs(code); x > 52; x = x / 52 | 0) name = toChar(x % 52) + name;
|
|
201
|
+
return toChar(x % 52) + name;
|
|
202
|
+
}
|
|
203
|
+
function toPhash(h, x) {
|
|
204
|
+
let i = x.length;
|
|
205
|
+
while (i) h = h * 33 ^ x.charCodeAt(--i);
|
|
206
|
+
return h;
|
|
207
|
+
}
|
|
208
|
+
function toHash(value) {
|
|
209
|
+
return toName(toPhash(5381, value) >>> 0);
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/important.ts
|
|
213
|
+
const importantRegex = /\s*!(important)?/i;
|
|
214
|
+
function isImportant(value) {
|
|
215
|
+
return typeof value === "string" ? importantRegex.test(value) : false;
|
|
216
|
+
}
|
|
217
|
+
function withoutImportant(value) {
|
|
218
|
+
return typeof value === "string" ? value.replace(importantRegex, "").trim() : value;
|
|
219
|
+
}
|
|
220
|
+
function withoutSpace(str) {
|
|
221
|
+
return typeof str === "string" ? str.replaceAll(" ", "_") : str;
|
|
222
|
+
}
|
|
223
|
+
function markImportant(obj) {
|
|
224
|
+
if (typeof obj !== "object" || obj === null) return obj;
|
|
225
|
+
const result = Array.isArray(obj) ? [] : {};
|
|
226
|
+
const stack = [{
|
|
227
|
+
obj,
|
|
228
|
+
result
|
|
229
|
+
}];
|
|
230
|
+
while (stack.length > 0) {
|
|
231
|
+
const { obj, result } = stack.pop();
|
|
232
|
+
for (const [key, value] of Object.entries(obj)) if (typeof value === "string" || typeof value === "number") result[key] = `${value} !important`;
|
|
233
|
+
else if (typeof value === "object" && value !== null) {
|
|
234
|
+
const next = Array.isArray(value) ? [] : {};
|
|
235
|
+
result[key] = next;
|
|
236
|
+
stack.push({
|
|
237
|
+
obj: value,
|
|
238
|
+
result: next
|
|
239
|
+
});
|
|
240
|
+
} else result[key] = value;
|
|
241
|
+
}
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/merge-props.ts
|
|
246
|
+
const MERGE_OMIT$2 = new Set([
|
|
247
|
+
"__proto__",
|
|
248
|
+
"constructor",
|
|
249
|
+
"prototype"
|
|
250
|
+
]);
|
|
251
|
+
function mergeProps(...sources) {
|
|
252
|
+
return sources.reduce((prev, obj) => {
|
|
253
|
+
if (!obj) return prev;
|
|
254
|
+
Object.keys(obj).forEach((key) => {
|
|
255
|
+
if (MERGE_OMIT$2.has(key)) return;
|
|
256
|
+
const prevValue = prev[key];
|
|
257
|
+
const value = obj[key];
|
|
258
|
+
if (isObject(prevValue) && isObject(value)) prev[key] = mergeProps(prevValue, value);
|
|
259
|
+
else prev[key] = value;
|
|
260
|
+
});
|
|
261
|
+
return prev;
|
|
262
|
+
}, {});
|
|
263
|
+
}
|
|
264
|
+
//#endregion
|
|
265
|
+
//#region src/walk-object.ts
|
|
266
|
+
const isNotNullish = (element) => element != null;
|
|
267
|
+
function walkObject(target, predicate, options = {}) {
|
|
268
|
+
const { stop, getKey } = options;
|
|
269
|
+
function inner(value, path = []) {
|
|
270
|
+
if (isObjectOrArray(value)) {
|
|
271
|
+
const result = {};
|
|
272
|
+
for (const [prop, child] of Object.entries(value)) {
|
|
273
|
+
const key = getKey?.(prop, child) ?? prop;
|
|
274
|
+
const childPath = [...path, key];
|
|
275
|
+
if (stop?.(value, childPath)) return predicate(value, path);
|
|
276
|
+
const next = inner(child, childPath);
|
|
277
|
+
if (isNotNullish(next)) result[key] = next;
|
|
278
|
+
}
|
|
279
|
+
return result;
|
|
280
|
+
}
|
|
281
|
+
return predicate(value, path);
|
|
282
|
+
}
|
|
283
|
+
return inner(target);
|
|
284
|
+
}
|
|
285
|
+
function mapObject(obj, fn) {
|
|
286
|
+
if (Array.isArray(obj)) return obj.map((value) => fn(value));
|
|
287
|
+
if (!isObject(obj)) return fn(obj);
|
|
288
|
+
return walkObject(obj, (value) => fn(value));
|
|
289
|
+
}
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region src/normalize-style-object.ts
|
|
292
|
+
function toResponsiveObject(values, breakpoints) {
|
|
293
|
+
return values.reduce((acc, current, index) => {
|
|
294
|
+
const key = breakpoints[index];
|
|
295
|
+
if (current != null) acc[key] = current;
|
|
296
|
+
return acc;
|
|
297
|
+
}, {});
|
|
298
|
+
}
|
|
299
|
+
function normalizeStyleObject(styles, context, shorthand = true) {
|
|
300
|
+
const { utility, conditions } = context;
|
|
301
|
+
const { hasShorthand, resolveShorthand } = utility;
|
|
302
|
+
return walkObject(styles, (value) => {
|
|
303
|
+
return Array.isArray(value) ? toResponsiveObject(value, conditions.breakpoints.keys) : value;
|
|
304
|
+
}, {
|
|
305
|
+
stop: (value) => Array.isArray(value),
|
|
306
|
+
getKey: shorthand ? (prop) => hasShorthand ? resolveShorthand(prop) : prop : void 0
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/classname.ts
|
|
311
|
+
const fallbackCondition = {
|
|
312
|
+
shift: (v) => v,
|
|
313
|
+
finalize: (v) => v,
|
|
314
|
+
breakpoints: { keys: [] }
|
|
315
|
+
};
|
|
316
|
+
const sanitize = (value) => typeof value === "string" ? value.replaceAll(/[\n\s]+/g, " ") : value;
|
|
317
|
+
const ENTRY_SEP = "]___[";
|
|
318
|
+
const COND_SEP = "<___>";
|
|
319
|
+
function createCss(context) {
|
|
320
|
+
const { utility, hash, grouped, conditions: conds = fallbackCondition } = context;
|
|
321
|
+
const formatClassName = (str) => [utility.prefix, str].filter(Boolean).join("-");
|
|
322
|
+
const hashFn = (conditions, className) => {
|
|
323
|
+
let result;
|
|
324
|
+
if (hash) {
|
|
325
|
+
const baseArray = [...conds.finalize(conditions), className];
|
|
326
|
+
result = formatClassName(utility.toHash(baseArray, toHash));
|
|
327
|
+
} else result = [...conds.finalize(conditions), formatClassName(className)].join(":");
|
|
328
|
+
return result;
|
|
329
|
+
};
|
|
330
|
+
if (grouped) return memo(({ base, ...styles } = {}) => {
|
|
331
|
+
const normalizedObject = normalizeStyleObject(Object.assign(styles, base), context);
|
|
332
|
+
const hashes = [];
|
|
333
|
+
walkObject(normalizedObject, (value, paths) => {
|
|
334
|
+
if (value == null) return;
|
|
335
|
+
const [prop, ...allConditions] = conds.shift(paths);
|
|
336
|
+
const conditions = filterBaseConditions(allConditions);
|
|
337
|
+
const parts = [`${prop}${ENTRY_SEP}value:${value}`];
|
|
338
|
+
if (conditions.length) parts.push(`cond:${conditions.join(COND_SEP)}`);
|
|
339
|
+
hashes.push(parts.join(ENTRY_SEP));
|
|
340
|
+
});
|
|
341
|
+
if (hashes.length === 0) return "";
|
|
342
|
+
hashes.sort();
|
|
343
|
+
const groupId = hashes.join("|");
|
|
344
|
+
return formatClassName(utility.toHash(["grouped", groupId], toHash));
|
|
345
|
+
});
|
|
346
|
+
return memo(({ base, ...styles } = {}) => {
|
|
347
|
+
const normalizedObject = normalizeStyleObject(Object.assign(styles, base), context);
|
|
348
|
+
const classNames = /* @__PURE__ */ new Set();
|
|
349
|
+
walkObject(normalizedObject, (value, paths) => {
|
|
350
|
+
if (value == null) return;
|
|
351
|
+
const important = isImportant(value);
|
|
352
|
+
const [prop, ...allConditions] = conds.shift(paths);
|
|
353
|
+
let className = hashFn(filterBaseConditions(allConditions), utility.transform(prop, withoutImportant(sanitize(value))).className);
|
|
354
|
+
if (important) className = `${className}!`;
|
|
355
|
+
classNames.add(className);
|
|
356
|
+
});
|
|
357
|
+
return Array.from(classNames).join(" ");
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
function compactStyles(...styles) {
|
|
361
|
+
return styles.flat().filter((style) => isObject(style) && Object.keys(compact(style)).length > 0);
|
|
362
|
+
}
|
|
363
|
+
function createMergeCss(context) {
|
|
364
|
+
function resolve(styles) {
|
|
365
|
+
const allStyles = compactStyles(...styles);
|
|
366
|
+
if (allStyles.length === 1) return allStyles;
|
|
367
|
+
return allStyles.map((style) => normalizeStyleObject(style, context));
|
|
368
|
+
}
|
|
369
|
+
function mergeCss(...styles) {
|
|
370
|
+
return mergeProps(...resolve(styles));
|
|
371
|
+
}
|
|
372
|
+
function assignCss(...styles) {
|
|
373
|
+
return Object.assign({}, ...resolve(styles));
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
mergeCss: memo(mergeCss),
|
|
377
|
+
assignCss
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
//#endregion
|
|
144
381
|
//#region src/css-var.ts
|
|
145
382
|
const escRegex = /[^a-zA-Z0-9_\u0081-\uffff-]/g;
|
|
146
383
|
function esc$1(string) {
|
|
@@ -253,6 +490,31 @@ function getOrCreateSet(map, key) {
|
|
|
253
490
|
return set;
|
|
254
491
|
}
|
|
255
492
|
//#endregion
|
|
493
|
+
//#region src/hypenate-property.ts
|
|
494
|
+
const wordRegex = /([A-Z])/g;
|
|
495
|
+
const msRegex = /^ms-/;
|
|
496
|
+
const hypenateProperty = memo((property) => {
|
|
497
|
+
if (property.startsWith("--")) return property;
|
|
498
|
+
return property.replace(wordRegex, "-$1").replace(msRegex, "-ms-").toLowerCase();
|
|
499
|
+
});
|
|
500
|
+
//#endregion
|
|
501
|
+
//#region src/is-css-function.ts
|
|
502
|
+
const fnRegExp = new RegExp(`^(${[
|
|
503
|
+
"min",
|
|
504
|
+
"max",
|
|
505
|
+
"clamp",
|
|
506
|
+
"calc"
|
|
507
|
+
].join("|")})\\(.*\\)`);
|
|
508
|
+
const isCssFunction = (v) => typeof v === "string" && fnRegExp.test(v);
|
|
509
|
+
//#endregion
|
|
510
|
+
//#region src/is-css-unit.ts
|
|
511
|
+
const lengthUnitsPattern = `(?:${"cm,mm,Q,in,pc,pt,px,em,ex,ch,rem,lh,rlh,vw,vh,vmin,vmax,vb,vi,svw,svh,lvw,lvh,dvw,dvh,cqw,cqh,cqi,cqb,cqmin,cqmax,%".split(",").join("|")})`;
|
|
512
|
+
const lengthRegExp = new RegExp(`^[+-]?[0-9]*.?[0-9]+(?:[eE][+-]?[0-9]+)?${lengthUnitsPattern}$`);
|
|
513
|
+
const isCssUnit = (v) => typeof v === "string" && lengthRegExp.test(v);
|
|
514
|
+
//#endregion
|
|
515
|
+
//#region src/is-css-var.ts
|
|
516
|
+
const isCssVar = (v) => typeof v === "string" && /^var\(--.+\)$/.test(v);
|
|
517
|
+
//#endregion
|
|
256
518
|
//#region src/merge-anything.ts
|
|
257
519
|
/**
|
|
258
520
|
* Credits: https://github.com/mesqueeb/merge-anything
|
|
@@ -376,6 +638,19 @@ const omit = (obj, paths) => {
|
|
|
376
638
|
//#region src/bamboo-config-name.ts
|
|
377
639
|
const BAMBOO_CONFIG_NAME = "__bamboo.config__";
|
|
378
640
|
//#endregion
|
|
641
|
+
//#region src/pattern-fns.ts
|
|
642
|
+
const patternFns = {
|
|
643
|
+
map: mapObject,
|
|
644
|
+
isCssFunction,
|
|
645
|
+
isCssVar,
|
|
646
|
+
isCssUnit
|
|
647
|
+
};
|
|
648
|
+
const getPatternStyles = (pattern, styles) => {
|
|
649
|
+
if (!pattern?.defaultValues) return styles;
|
|
650
|
+
const defaults = typeof pattern.defaultValues === "function" ? pattern.defaultValues(styles) : pattern.defaultValues;
|
|
651
|
+
return Object.assign({}, defaults, compact(styles));
|
|
652
|
+
};
|
|
653
|
+
//#endregion
|
|
379
654
|
//#region src/split.ts
|
|
380
655
|
function splitBy(value, separator = ",") {
|
|
381
656
|
const result = [];
|
|
@@ -909,6 +1184,46 @@ const parseJson = (config) => {
|
|
|
909
1184
|
return JSON.parse(config);
|
|
910
1185
|
};
|
|
911
1186
|
//#endregion
|
|
1187
|
+
//#region src/slot.ts
|
|
1188
|
+
const getSlotRecipes = (recipe = {}) => {
|
|
1189
|
+
const init = (slot) => ({
|
|
1190
|
+
className: [recipe.className, slot].filter(Boolean).join("__"),
|
|
1191
|
+
base: recipe.base?.[slot] ?? {},
|
|
1192
|
+
variants: {},
|
|
1193
|
+
defaultVariants: recipe.defaultVariants ?? {},
|
|
1194
|
+
compoundVariants: recipe.compoundVariants ? getSlotCompoundVariant(recipe.compoundVariants, slot) : []
|
|
1195
|
+
});
|
|
1196
|
+
const recipeParts = (recipe.slots ?? []).map((slot) => [slot, init(slot)]);
|
|
1197
|
+
for (const [variantsKey, variantsSpec] of Object.entries(recipe.variants ?? {})) for (const [variantKey, variantSpec] of Object.entries(variantsSpec)) recipeParts.forEach(([slot, slotRecipe]) => {
|
|
1198
|
+
slotRecipe.variants[variantsKey] ??= {};
|
|
1199
|
+
slotRecipe.variants[variantsKey][variantKey] = variantSpec[slot] ?? {};
|
|
1200
|
+
});
|
|
1201
|
+
return Object.fromEntries(recipeParts);
|
|
1202
|
+
};
|
|
1203
|
+
const getSlotCompoundVariant = (compoundVariants, slotName) => compoundVariants.filter((compoundVariant) => compoundVariant.css[slotName]).map((compoundVariant) => ({
|
|
1204
|
+
...compoundVariant,
|
|
1205
|
+
css: compoundVariant.css[slotName]
|
|
1206
|
+
}));
|
|
1207
|
+
//#endregion
|
|
1208
|
+
//#region src/split-props.ts
|
|
1209
|
+
function splitProps(props, ...keys) {
|
|
1210
|
+
const descriptors = Object.getOwnPropertyDescriptors(props);
|
|
1211
|
+
const dKeys = Object.keys(descriptors);
|
|
1212
|
+
const split = (k) => {
|
|
1213
|
+
const clone = {};
|
|
1214
|
+
for (let i = 0; i < k.length; i++) {
|
|
1215
|
+
const key = k[i];
|
|
1216
|
+
if (descriptors[key]) {
|
|
1217
|
+
Object.defineProperty(clone, key, descriptors[key]);
|
|
1218
|
+
delete descriptors[key];
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return clone;
|
|
1222
|
+
};
|
|
1223
|
+
const fn = (key) => split(Array.isArray(key) ? key : dKeys.filter(key));
|
|
1224
|
+
return keys.map(fn).concat(split(dKeys));
|
|
1225
|
+
}
|
|
1226
|
+
//#endregion
|
|
912
1227
|
//#region src/to-json.ts
|
|
913
1228
|
function mapToJson(map) {
|
|
914
1229
|
const obj = {};
|
|
@@ -927,6 +1242,15 @@ function unionType(values, opts = {}) {
|
|
|
927
1242
|
return arr.map((v) => stringify(v)).join(" | ");
|
|
928
1243
|
}
|
|
929
1244
|
//#endregion
|
|
1245
|
+
//#region src/uniq.ts
|
|
1246
|
+
const uniq = (...items) => {
|
|
1247
|
+
const set = items.reduce((acc, currItems) => {
|
|
1248
|
+
if (currItems) currItems.forEach((item) => acc.add(item));
|
|
1249
|
+
return acc;
|
|
1250
|
+
}, /* @__PURE__ */ new Set([]));
|
|
1251
|
+
return Array.from(set);
|
|
1252
|
+
};
|
|
1253
|
+
//#endregion
|
|
930
1254
|
//#region src/unit-conversion.ts
|
|
931
1255
|
const BASE_FONT_SIZE = 16;
|
|
932
1256
|
const UNIT_PX = "px";
|