Initial commit

This commit is contained in:
mats committed 2026-09-22 08:41:20 +02:00
commit 89053153cc
8152 files changed
+2086461

No files matched your search

Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../lz-string/bin/bin.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../oxlint/bin/oxlint
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rolldown/bin/cli.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@bramus/specificity/bin/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../tldts/bin/cli.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsserver
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vitest/vitest.mjs
+1
View File
@@ -0,0 +1 @@
../why-is-node-running/cli.js
+1689
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"root":["../../src/App.tsx","../../src/main.tsx","../../src/api/client.ts","../../src/api/items.ts","../../src/app/AppStateProvider.tsx","../../src/app/appState.ts","../../src/app/index.ts","../../src/app/persist.ts","../../src/app/routes.tsx","../../src/auth/SessionCard.tsx","../../src/auth/UserMenu.tsx","../../src/auth/useSession.ts","../../src/components/AIWorkflowSection.tsx","../../src/components/Button.tsx","../../src/components/ButtonMatrix.tsx","../../src/components/CodeEditor.tsx","../../src/components/CodeSample.tsx","../../src/components/FormField.tsx","../../src/components/Hero.tsx","../../src/components/Icon.tsx","../../src/components/IconMatrix.tsx","../../src/components/MarkdownRenderer.tsx","../../src/components/RightRail.tsx","../../src/components/SearchPalette.tsx","../../src/components/Section.tsx","../../src/components/Sidebar.tsx","../../src/components/TokenGrid.tsx","../../src/components/Topbar.tsx","../../src/components/TypographySection.tsx","../../src/components/icon-registry.ts","../../src/components/examples/DeploymentModal.tsx","../../src/components/examples/MetricsDashboard.tsx","../../src/components/examples/ServiceTable.tsx","../../src/components/examples/SettingsPanel.tsx","../../src/components/examples/index.ts","../../src/components/ui/Alert.tsx","../../src/components/ui/Avatar.tsx","../../src/components/ui/Badge.tsx","../../src/components/ui/Card.tsx","../../src/components/ui/Dialog.tsx","../../src/components/ui/EmptyState.tsx","../../src/components/ui/Kbd.tsx","../../src/components/ui/Overlay.tsx","../../src/components/ui/Progress.tsx","../../src/components/ui/Sheet.tsx","../../src/components/ui/Skeleton.tsx","../../src/components/ui/Spinner.tsx","../../src/components/ui/StatCard.tsx","../../src/components/ui/Switch.tsx","../../src/components/ui/Table.tsx","../../src/components/ui/Tabs.tsx","../../src/components/ui/Tooltip.tsx","../../src/components/ui/index.ts","../../src/components/ui/overlayBehavior.ts","../../src/data/library.ts","../../src/data/patterns.ts","../../src/dev/ErrorBoundary.tsx","../../src/dev/errorSink.ts","../../src/hooks/useItems.ts","../../src/pages/ButtonsPage.tsx","../../src/pages/ColorsPage.tsx","../../src/pages/EditorPage.tsx","../../src/pages/FormsPage.tsx","../../src/pages/IconsPage.tsx","../../src/pages/ItemsPage.tsx","../../src/pages/MarkdownPage.tsx","../../src/pages/NotFoundPage.tsx","../../src/pages/OverviewPage.tsx","../../src/pages/PatternsPage.tsx","../../src/pages/PrimitivesPage.tsx","../../src/pages/TypographyPage.tsx","../../src/utils/cn.ts","../../src/utils/useTimeout.ts"],"version":"6.0.3"}
+1
View File
@@ -0,0 +1 @@
{"root":["../../vite.config.ts"],"version":"6.0.3"}
+66
View File
@@ -0,0 +1,66 @@
{
"hash": "976b9c3d",
"configHash": "89e67727",
"lockfileHash": "0d4791a3",
"browserHash": "4b2fbac7",
"optimized": {
"lucide-react": {
"src": "../../lucide-react/dist/esm/lucide-react.mjs",
"file": "lucide-react.js",
"fileHash": "6c3cfb80",
"needsInterop": false
},
"react-dom": {
"src": "../../react-dom/index.js",
"file": "react-dom.js",
"fileHash": "25030b7a",
"needsInterop": true
},
"react-dom/client": {
"src": "../../react-dom/client.js",
"file": "react-dom_client.js",
"fileHash": "de15c997",
"needsInterop": true
},
"react": {
"src": "../../react/index.js",
"file": "react.js",
"fileHash": "e97c5b5e",
"needsInterop": true
},
"react/jsx-dev-runtime": {
"src": "../../react/jsx-dev-runtime.js",
"file": "react_jsx-dev-runtime.js",
"fileHash": "15b8f65b",
"needsInterop": true
},
"react/jsx-runtime": {
"src": "../../react/jsx-runtime.js",
"file": "react_jsx-runtime.js",
"fileHash": "6d9e10ca",
"needsInterop": true
},
"swr": {
"src": "../../swr/dist/index/index.mjs",
"file": "swr.js",
"fileHash": "5dedc4fa",
"needsInterop": false
},
"wouter": {
"src": "../../wouter/src/index.js",
"file": "wouter.js",
"fileHash": "9e6a9f9c",
"needsInterop": false
}
},
"chunks": {
"rolldown-runtime-DC62tzP2": {
"file": "rolldown-runtime-DC62tzP2.js",
"isDynamicEntry": false
},
"shim-BX6a9SD7": {
"file": "shim-BX6a9SD7.js",
"isDynamicEntry": false
}
}
}
+63820
View File
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"lucide-react.js","names":["createContext","useMemo","createElement","useContext","forwardRef","createElement","forwardRef","createElement","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__iconData","__Line truncated
+3
View File
@@ -0,0 +1,3 @@
{
"type": "module"
}
+198
View File
@@ -0,0 +1,198 @@
import { t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
//#region node_modules/react-dom/cjs/react-dom.development.js
/**
* @license React
* react-dom.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_react_dom_development = /* @__PURE__ */ __commonJSMin(((exports) => {
(function() {
function noop() {}
function testStringCoercion(value) {
return "" + value;
}
function createPortal$1(children, containerInfo, implementation) {
var key = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;
if (null == key) key = null;
else if (key === REACT_OPTIMISTIC_KEY) key = REACT_OPTIMISTIC_KEY;
else {
try {
testStringCoercion(key);
var JSCompiler_inline_result = !1;
} catch (e) {
JSCompiler_inline_result = !0;
}
JSCompiler_inline_result && (console.error("The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", "function" === typeof Symbol && Symbol.toStringTag && key[Symbol.toStringTag] || key.constructor.name || "Object"), testStringCoercion(key));
key = "" + key;
}
return {
$$typeof: REACT_PORTAL_TYPE,
key,
children,
containerInfo,
implementation
};
}
function getCrossOriginStringAs(as, input) {
if ("font" === as) return "";
if ("string" === typeof input) return "use-credentials" === input ? input : "";
}
function getValueDescriptorExpectingObjectForWarning(thing) {
return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "something with type \"" + typeof thing + "\"";
}
function getValueDescriptorExpectingEnumForWarning(thing) {
return null === thing ? "`null`" : void 0 === thing ? "`undefined`" : "" === thing ? "an empty string" : "string" === typeof thing ? JSON.stringify(thing) : "number" === typeof thing ? "`" + thing + "`" : "something with type \"" + typeof thing + "\"";
}
function resolveDispatcher() {
var dispatcher = ReactSharedInternals.H;
null === dispatcher && console.error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.");
return dispatcher;
}
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
var React = require_react(), Internals = {
d: {
f: noop,
r: function() {
throw Error("Invalid form element. requestFormReset must be passed a form that was rendered by React.");
},
D: noop,
C: noop,
L: noop,
m: noop,
X: noop,
S: noop,
M: noop
},
p: 0,
findDOMNode: null
}, REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_RECOVERABLE_TYPE = Symbol.for("react.recoverable"), REACT_OPTIMISTIC_KEY = Symbol.for("react.optimistic_key"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
"function" === typeof Map && null != Map.prototype && "function" === typeof Map.prototype.forEach && "function" === typeof Set && null != Set.prototype && "function" === typeof Set.prototype.clear && "function" === typeof Set.prototype.forEach || console.error("React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills");
exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = Internals;
exports.browser = function(reason) {
return {
$$typeof: REACT_RECOVERABLE_TYPE,
_reason: reason
};
};
exports.createPortal = function(children, container) {
var key = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;
if (!container || 1 !== container.nodeType && 9 !== container.nodeType && 11 !== container.nodeType) throw Error("Target container is not a DOM element.");
return createPortal$1(children, container, null, key);
};
exports.flushSync = function(fn) {
var previousTransition = ReactSharedInternals.T, previousUpdatePriority = Internals.p;
try {
if (ReactSharedInternals.T = null, Internals.p = 2, fn) return fn();
} finally {
ReactSharedInternals.T = previousTransition, Internals.p = previousUpdatePriority, Internals.d.f() && console.error("flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task.");
}
};
exports.preconnect = function(href, options) {
"string" === typeof href && href ? null != options && "object" !== typeof options ? console.error("ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.", getValueDescriptorExpectingEnumForWarning(options)) : null != options && "string" !== typeof options.crossOrigin && console.error("ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.", getValueDescriptorExpectingObjectForWarning(options.crossOrigin)) : console.error("ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
"string" === typeof href && (options ? (options = options.crossOrigin, options = "string" === typeof options ? "use-credentials" === options ? options : "" : void 0) : options = null, Internals.d.C(href, options));
};
exports.prefetchDNS = function(href) {
if ("string" !== typeof href || !href) console.error("ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
else if (1 < arguments.length) {
var options = arguments[1];
"object" === typeof options && options.hasOwnProperty("crossOrigin") ? console.error("ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.", getValueDescriptorExpectingEnumForWarning(options)) : console.error("ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.", getValueDescriptorExpectingEnumForWarning(options));
}
"string" === typeof href && Internals.d.D(href);
};
exports.preinit = function(href, options) {
"string" === typeof href && href ? null == options || "object" !== typeof options ? console.error("ReactDOM.preinit(): Expected the `options` argument (second) to be an object with an `as` property describing the type of resource to be preinitialized but encountered %s instead.", getValueDescriptorExpectingEnumForWarning(options)) : "style" !== options.as && "script" !== options.as && console.error("ReactDOM.preinit(): Expected the `as` property in the `options` argument (second) to contain a valid value describing the type of resource to be preinitialized but encountered %s instead. Valid values for `as` are \"style\" and \"script\".", getValueDescriptorExpectingEnumForWarning(options.as)) : console.error("ReactDOM.preinit(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.", getValueDescriptorExpectingObjectForWarning(href));
if ("string" === typeof href && options && "string" === typeof options.as) {
var as = options.as, crossOrigin = getCrossOriginStringAs(as, options.crossOrigin), integrity = "string" === typeof options.integrity ? options.integrity : void 0, fetchPriority = "string" === typeof options.fetchPriority ? options.fetchPriority : void 0;
"style" === as ? Internals.d.S(href, "string" === typeof options.precedence ? options.precedence : void 0, {
crossOrigin,
integrity,
fetchPriority
}) : "script" === as && Internals.d.X(href, {
crossOrigin,
integrity,
fetchPriority,
nonce: "string" === typeof options.nonce ? options.nonce : void 0
});
}
};
exports.preinitModule = function(href, options) {
var encountered = "";
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "script" !== options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingEnumForWarning(options.as) + ".");
if (encountered) console.error("ReactDOM.preinitModule(): Expected up to two arguments, a non-empty `href` string and, optionally, an `options` object with a valid `as` property.%s", encountered);
else switch (encountered = options && "string" === typeof options.as ? options.as : "script", encountered) {
case "script": break;
default: encountered = getValueDescriptorExpectingEnumForWarning(encountered), console.error("ReactDOM.preinitModule(): Currently the only supported \"as\" type for this function is \"script\" but received \"%s\" instead. This warning was generated for `href` \"%s\". In the future other module types will be supported, aligning with the import-attributes proposal. Learn more here: (https://github.com/tc39/proposal-import-attributes)", encountered, href);
}
if ("string" === typeof href) if ("object" === typeof options && null !== options) {
if (null == options.as || "script" === options.as) encountered = getCrossOriginStringAs(options.as, options.crossOrigin), Internals.d.M(href, {
crossOrigin: encountered,
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
});
} else options ?? Internals.d.M(href);
};
exports.preload = function(href, options) {
var encountered = "";
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
null == options || "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : "string" === typeof options.as && options.as || (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
encountered && console.error("ReactDOM.preload(): Expected two arguments, a non-empty `href` string and an `options` object with an `as` property valid for a `<link rel=\"preload\" as=\"...\" />` tag.%s", encountered);
if ("string" === typeof href && "object" === typeof options && null !== options && "string" === typeof options.as) {
encountered = options.as;
var crossOrigin = getCrossOriginStringAs(encountered, options.crossOrigin);
Internals.d.L(href, encountered, {
crossOrigin,
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
type: "string" === typeof options.type ? options.type : void 0,
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0,
referrerPolicy: "string" === typeof options.referrerPolicy ? options.referrerPolicy : void 0,
imageSrcSet: "string" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,
imageSizes: "string" === typeof options.imageSizes ? options.imageSizes : void 0,
media: "string" === typeof options.media ? options.media : void 0
});
}
};
exports.preloadModule = function(href, options) {
var encountered = "";
"string" === typeof href && href || (encountered += " The `href` argument encountered was " + getValueDescriptorExpectingObjectForWarning(href) + ".");
void 0 !== options && "object" !== typeof options ? encountered += " The `options` argument encountered was " + getValueDescriptorExpectingObjectForWarning(options) + "." : options && "as" in options && "string" !== typeof options.as && (encountered += " The `as` option encountered was " + getValueDescriptorExpectingObjectForWarning(options.as) + ".");
encountered && console.error("ReactDOM.preloadModule(): Expected two arguments, a non-empty `href` string and, optionally, an `options` object with an `as` property valid for a `<link rel=\"modulepreload\" as=\"...\" />` tag.%s", encountered);
"string" === typeof href && (options ? (encountered = getCrossOriginStringAs(options.as, options.crossOrigin), Internals.d.m(href, {
as: "string" === typeof options.as && "script" !== options.as ? options.as : void 0,
crossOrigin: encountered,
integrity: "string" === typeof options.integrity ? options.integrity : void 0,
nonce: "string" === typeof options.nonce ? options.nonce : void 0,
fetchPriority: "string" === typeof options.fetchPriority ? options.fetchPriority : void 0
})) : Internals.d.m(href));
};
exports.requestFormReset = function(form) {
Internals.d.r(form);
};
exports.unstable_batchedUpdates = function(fn, a) {
return fn(a);
};
exports.useFormState = function(action, initialState, permalink) {
return resolveDispatcher().useFormState(action, initialState, permalink);
};
exports.useFormStatus = function() {
return resolveDispatcher().useHostTransitionStatus();
};
exports.version = "19.3.0";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
})();
}));
//#endregion
//#region node_modules/react-dom/index.js
var require_react_dom = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = require_react_dom_development();
}));
//#endregion
export default require_react_dom();
export { require_react_dom as t };
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"react-dom.js","names":[],"sources":["../../react-dom/cjs/react-dom.development.js","../../react-dom/index.js"],"sourcesContent":["/**\n * @license React\n * react-dom.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function noop() {}\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function createPortal$1(children, containerInfo, implementation) {\n var key =\n 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;\n if (null == key) key = null;\n else if (key === REACT_OPTIMISTIC_KEY) key = REACT_OPTIMISTIC_KEY;\n else {\n try {\n testStringCoercion(key);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n JSCompiler_inline_result &&\n (console.error(\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n key[Symbol.toStringTag]) ||\n key.constructor.name ||\n \"Object\"\n ),\n testStringCoercion(key));\n key = \"\" + key;\n }\n return {\n $$typeof: REACT_PORTAL_TYPE,\n key: key,\n children: children,\n containerInfo: containerInfo,\n implementation: implementation\n };\n }\n function getCrossOriginStringAs(as, input) {\n if (\"font\" === as) return \"\";\n if (\"string\" === typeof input)\n return \"use-credentials\" === input ? input : \"\";\n }\n function getValueDescriptorExpectingObjectForWarning(thing) {\n return null === thing\n ? \"`null`\"\n : void 0 === thing\n ? \"`undefined`\"\n : \"\" === thing\n ? \"an empty string\"\n : 'something with type \"' + typeof thing + '\"';\n }\n function getValueDescriptorExpectingEnumForWarning(thing) {\n return null === thing\n ? \"`null`\"\n : void 0 === thing\n ? \"`undefined`\"\n : \"\" === thing\n ? \"an empty string\"\n : \"string\" === typeof thing\n ? JSON.stringify(thing)\n : \"number\" === typeof thing\n ? \"`\" + thing + \"`\"\n : 'something with type \"' + typeof thing + '\"';\n }\n function resolveDispatcher() {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher;\n }\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());\n var React = require(\"react\"),\n Internals = {\n d: {\n f: noop,\n r: function () {\n throw Error(\n \"Invalid form element. requestFormReset must be passed a form that was rendered by React.\"\n );\n },\n D: noop,\n C: noop,\n L: noop,\n m: noop,\n X: noop,\n S: noop,\n M: noop\n },\n p: 0,\n findDOMNode: null\n },\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_RECOVERABLE_TYPE = Symbol.for(\"react.recoverable\"),\n REACT_OPTIMISTIC_KEY = Symbol.for(\"react.optimistic_key\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\n (\"function\" === typeof Map &&\n null != Map.prototype &&\n \"function\" === typeof Map.prototype.forEach &&\n \"function\" === typeof Set &&\n null != Set.prototype &&\n \"function\" === typeof Set.prototype.clear &&\n \"function\" === typeof Set.prototype.forEach) ||\n console.error(\n \"React depends on Map and Set built-in types. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills\"\n );\n exports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n Internals;\n exports.browser = function (reason) {\n retLine truncated
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"react-dom_client.js","names":[],"sources":["../../scheduler/cjs/scheduler.development.js","../../scheduler/index.js","../../react-dom/cjs/react-dom-client.development.js","../../react-dom/client.js"],"sourcesContent":["/**\n * @license React\n * scheduler.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function performWorkUntilDeadline() {\n needsPaint = !1;\n if (isMessageLoopRunning) {\n var currentTime = exports.unstable_now();\n startTime = currentTime;\n var hasMoreWork = !0;\n try {\n a: {\n isHostCallbackScheduled = !1;\n isHostTimeoutScheduled &&\n ((isHostTimeoutScheduled = !1),\n localClearTimeout(taskTimeoutID),\n (taskTimeoutID = -1));\n isPerformingWork = !0;\n var previousPriorityLevel = currentPriorityLevel;\n try {\n b: {\n advanceTimers(currentTime);\n for (\n currentTask = peek(taskQueue);\n null !== currentTask &&\n !(\n currentTask.expirationTime > currentTime &&\n shouldYieldToHost()\n );\n\n ) {\n var callback = currentTask.callback;\n if (\"function\" === typeof callback) {\n currentTask.callback = null;\n currentPriorityLevel = currentTask.priorityLevel;\n var continuationCallback = callback(\n currentTask.expirationTime <= currentTime\n );\n currentTime = exports.unstable_now();\n if (\"function\" === typeof continuationCallback) {\n currentTask.callback = continuationCallback;\n advanceTimers(currentTime);\n hasMoreWork = !0;\n break b;\n }\n currentTask === peek(taskQueue) && pop(taskQueue);\n advanceTimers(currentTime);\n } else pop(taskQueue);\n currentTask = peek(taskQueue);\n }\n if (null !== currentTask) hasMoreWork = !0;\n else {\n var firstTimer = peek(timerQueue);\n null !== firstTimer &&\n requestHostTimeout(\n handleTimeout,\n firstTimer.startTime - currentTime\n );\n hasMoreWork = !1;\n }\n }\n break a;\n } finally {\n (currentTask = null),\n (currentPriorityLevel = previousPriorityLevel),\n (isPerformingWork = !1);\n }\n hasMoreWork = void 0;\n }\n } finally {\n hasMoreWork\n ? schedulePerformWorkUntilDeadline()\n : (isMessageLoopRunning = !1);\n }\n }\n }\n function push(heap, node) {\n var index = heap.length;\n heap.push(node);\n a: for (; 0 < index; ) {\n var parentIndex = (index - 1) >>> 1,\n parent = heap[parentIndex];\n if (0 < compare(parent, node))\n (heap[parentIndex] = node),\n (heap[index] = parent),\n (index = parentIndex);\n else break a;\n }\n }\n function peek(heap) {\n return 0 === heap.length ? null : heap[0];\n }\n function pop(heap) {\n if (0 === heap.length) return null;\n var first = heap[0],\n last = heap.pop();\n if (last !== first) {\n heap[0] = last;\n a: for (\n var index = 0, length = heap.length, halfLength = length >>> 1;\n index < halfLength;\n\n ) {\n var leftIndex = 2 * (index + 1) - 1,\n left = heap[leftIndex],\n rightIndex = leftIndex + 1,\n right = heap[rightIndex];\n if (0 > compare(left, last))\n rightIndex < length && 0 > compare(right, left)\n ? ((heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex))\n : ((heap[index] = left),\n (heap[leftIndex] = last),\n (index = leftIndex));\n else if (rightIndex < length && 0 > compare(right, last))\n (heap[index] = right),\n (heap[rightIndex] = last),\n (index = rightIndex);\n else break a;\n }\n }\n return first;\n }\n function compare(a, b) {\n var diff = a.sortIndex - b.sortIndex;\n return 0 !== diff ? diff : a.id - b.id;\n Line truncated
+788
View File
@@ -0,0 +1,788 @@
import { t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
//#region node_modules/react/cjs/react.development.js
/**
* @license React
* react.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_react_development = /* @__PURE__ */ __commonJSMin(((exports, module) => {
(function() {
function defineDeprecationWarning(methodName, info) {
Object.defineProperty(Component.prototype, methodName, { get: function() {
console.warn("%s(...) is deprecated in plain JavaScript React classes. %s", info[0], info[1]);
} });
}
function getIteratorFn(maybeIterable) {
if (null === maybeIterable || "object" !== typeof maybeIterable) return null;
maybeIterable = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable["@@iterator"];
return "function" === typeof maybeIterable ? maybeIterable : null;
}
function warnNoop(publicInstance, callerName) {
publicInstance = (publicInstance = publicInstance.constructor) && (publicInstance.displayName || publicInstance.name) || "ReactClass";
var warningKey = publicInstance + "." + callerName;
didWarnStateUpdateForUnmountedComponent[warningKey] || (console.error("Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.", callerName, publicInstance), didWarnStateUpdateForUnmountedComponent[warningKey] = !0);
}
function Component(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
function ComponentDummy() {}
function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
function noop() {}
function testStringCoercion(value) {
return "" + value;
}
function checkKeyStringCoercion(value) {
try {
testStringCoercion(value);
var JSCompiler_inline_result = !1;
} catch (e) {
JSCompiler_inline_result = !0;
}
if (JSCompiler_inline_result) {
JSCompiler_inline_result = console;
var JSCompiler_temp_const = JSCompiler_inline_result.error;
var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
JSCompiler_temp_const.call(JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0);
return testStringCoercion(value);
}
}
function getComponentNameFromType(type) {
if (null == type) return null;
if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
if ("string" === typeof type) return type;
switch (type) {
case REACT_FRAGMENT_TYPE: return "Fragment";
case REACT_PROFILER_TYPE: return "Profiler";
case REACT_STRICT_MODE_TYPE: return "StrictMode";
case REACT_SUSPENSE_TYPE: return "Suspense";
case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList";
case REACT_ACTIVITY_TYPE: return "Activity";
case REACT_VIEW_TRANSITION_TYPE: return "ViewTransition";
}
if ("object" === typeof type) switch ("number" === typeof type.tag && console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), type.$$typeof) {
case REACT_PORTAL_TYPE: return "Portal";
case REACT_CONTEXT_TYPE: return type.displayName || "Context";
case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer";
case REACT_FORWARD_REF_TYPE:
var innerType = type.render;
type = type.displayName;
type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
return type;
case REACT_MEMO_TYPE: return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
case REACT_LAZY_TYPE:
innerType = type._payload;
type = type._init;
try {
return getComponentNameFromType(type(innerType));
} catch (x) {}
}
return null;
}
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) return "<>";
if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE) return "<...>";
try {
var name = getComponentNameFromType(type);
return name ? "<" + name + ">" : "<...>";
} catch (x) {
return "<...>";
}
}
function getOwner() {
var dispatcher = ReactSharedInternals.A;
return null === dispatcher ? null : dispatcher.getOwner();
}
function UnknownOwner() {
return Error("react-stack-top-frame");
}
function hasValidKey(config) {
if (hasOwnProperty.call(config, "key")) {
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
if (getter && getter.isReactWarning) return !1;
}
return void 0 !== config.key;
}
function defineKeyPropWarningGetter(props, displayName) {
function warnAboutAccessingKey() {
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName));
}
warnAboutAccessingKey.isReactWarning = !0;
Object.defineProperty(props, "key", {
get: warnAboutAccessingKey,
configurable: !0
});
}
function elementRefGetterWithDeprecationWarning() {
var componentName = getComponentNameFromType(this.type);
didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = !0, console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));
componentName = this.props.ref;
return void 0 !== componentName ? componentName : null;
}
function ReactElement(type, key, props, owner, debugStack, debugTask) {
var refProp = props.ref;
type = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props,
_owner: owner
};
null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
enumerable: !1,
get: elementRefGetterWithDeprecationWarning
}) : Object.defineProperty(type, "ref", {
enumerable: !1,
value: null
});
type._store = {};
Object.defineProperty(type._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
});
Object.defineProperty(type, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
});
Object.defineProperty(type, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugStack
});
Object.defineProperty(type, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugTask
});
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
return type;
}
function cloneAndReplaceKey(oldElement, newKey) {
newKey = ReactElement(oldElement.type, newKey, oldElement.props, oldElement._owner, oldElement._debugStack, oldElement._debugTask);
oldElement._store && (newKey._store.validated = oldElement._store.validated);
return newKey;
}
function validateChildKeys(node) {
isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
}
function isValidElement(object) {
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
}
function escape(key) {
var escaperLookup = {
"=": "=0",
":": "=2"
};
return "$" + key.replace(/[=:]/g, function(match) {
return escaperLookup[match];
});
}
function getElementKey(element, index) {
return "object" === typeof element && null !== element && null != element.key ? (checkKeyStringCoercion(element.key), escape("" + element.key)) : index.toString(36);
}
function resolveThenable(thenable) {
switch (thenable.status) {
case "fulfilled": return thenable.value;
case "rejected": throw thenable.reason;
default: switch ("string" === typeof thenable.status ? thenable.then(noop, noop) : (thenable.status = "pending", thenable.then(function(fulfilledValue) {
"pending" === thenable.status && (thenable.status = "fulfilled", thenable.value = fulfilledValue);
}, function(error) {
"pending" === thenable.status && (thenable.status = "rejected", thenable.reason = error);
})), thenable.status) {
case "fulfilled": return thenable.value;
case "rejected": throw thenable.reason;
}
}
throw thenable;
}
function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {
var type = typeof children;
if ("undefined" === type || "boolean" === type) children = null;
var invokeCallback = !1;
if (null === children) invokeCallback = !0;
else switch (type) {
case "bigint":
case "string":
case "number":
invokeCallback = !0;
break;
case "object": switch (children.$$typeof) {
case REACT_ELEMENT_TYPE:
case REACT_PORTAL_TYPE:
invokeCallback = !0;
break;
case REACT_LAZY_TYPE: return invokeCallback = children._init, mapIntoArray(invokeCallback(children._payload), array, escapedPrefix, nameSoFar, callback);
}
}
if (invokeCallback) {
invokeCallback = children;
callback = callback(invokeCallback);
var childKey = "" === nameSoFar ? "." + getElementKey(invokeCallback, 0) : nameSoFar;
isArrayImpl(callback) ? (escapedPrefix = "", null != childKey && (escapedPrefix = childKey.replace(userProvidedKeyEscapeRegex, "$&/") + "/"), mapIntoArray(callback, array, escapedPrefix, "", function(c) {
return c;
})) : null != callback && (isValidElement(callback) && (null != callback.key && (invokeCallback && invokeCallback.key === callback.key || checkKeyStringCoercion(callback.key)), escapedPrefix = cloneAndReplaceKey(callback, escapedPrefix + (null == callback.key || invokeCallback && invokeCallback.key === callback.key ? "" : ("" + callback.key).replace(userProvidedKeyEscapeRegex, "$&/") + "/") + childKey), "" !== nameSoFar && null != invokeCallback && isValidElement(invokeCallback) && null == invokeCallback.key && invokeCallback._store && !invokeCallback._store.validated && (escapedPrefix._store.validated = 2), callback = escapedPrefix), array.push(callback));
return 1;
}
invokeCallback = 0;
childKey = "" === nameSoFar ? "." : nameSoFar + ":";
if (isArrayImpl(children)) for (var i = 0; i < children.length; i++) nameSoFar = children[i], type = childKey + getElementKey(nameSoFar, i), invokeCallback += mapIntoArray(nameSoFar, array, escapedPrefix, type, callback);
else if (i = getIteratorFn(children), "function" === typeof i) for (i === children.entries && (didWarnAboutMaps || console.warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."), didWarnAboutMaps = !0), children = i.call(children), i = 0; !(nameSoFar = children.next()).done;) nameSoFar = nameSoFar.value, type = childKey + getElementKey(nameSoFar, i++), invokeCallback += mapIntoArray(nameSoFar, array, escapedPrefix, type, callback);
else if ("object" === type) {
if ("function" === typeof children.then) return mapIntoArray(resolveThenable(children), array, escapedPrefix, nameSoFar, callback);
array = String(children);
throw Error("Objects are not valid as a React child (found: " + ("[object Object]" === array ? "object with keys {" + Object.keys(children).join(", ") + "}" : array) + "). If you meant to render a collection of children, use an array instead.");
}
return invokeCallback;
}
function mapChildren(children, func, context) {
if (null == children) return children;
var result = [], count = 0;
mapIntoArray(children, result, "", "", function(child) {
return func.call(context, child, count++);
});
return result;
}
function lazyInitializer(payload) {
if (-1 === payload._status) {
var resolveDebugValue = null, rejectDebugValue = null, ioInfo = payload._ioInfo;
null != ioInfo && (ioInfo.start = ioInfo.end = performance.now(), ioInfo.value = new Promise(function(resolve, reject) {
resolveDebugValue = resolve;
rejectDebugValue = reject;
}));
ioInfo = payload._result;
var thenable = ioInfo();
thenable.then(function(moduleObject) {
if (0 === payload._status || -1 === payload._status) {
payload._status = 1;
payload._result = moduleObject;
var _ioInfo = payload._ioInfo;
if (null != _ioInfo) {
_ioInfo.end = performance.now();
var debugValue = null == moduleObject ? void 0 : moduleObject.default;
resolveDebugValue(debugValue);
_ioInfo.value.status = "fulfilled";
_ioInfo.value.value = debugValue;
}
void 0 === thenable.status && (thenable.status = "fulfilled", thenable.value = moduleObject);
}
}, function(error) {
if (0 === payload._status || -1 === payload._status) {
payload._status = 2;
payload._result = error;
var _ioInfo2 = payload._ioInfo;
null != _ioInfo2 && (_ioInfo2.end = performance.now(), _ioInfo2.value.then(noop, noop), rejectDebugValue(error), _ioInfo2.value.status = "rejected", _ioInfo2.value.reason = error);
void 0 === thenable.status && (thenable.status = "rejected", thenable.reason = error);
}
});
ioInfo = payload._ioInfo;
if (null != ioInfo) {
var displayName = thenable.displayName;
"string" === typeof displayName && (ioInfo.name = displayName);
}
-1 === payload._status && (payload._status = 0, payload._result = thenable);
}
if (1 === payload._status) return ioInfo = payload._result, void 0 === ioInfo && console.error("lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))\n\nDid you accidentally put curly braces around the import?", ioInfo), "default" in ioInfo || console.error("lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))", ioInfo), ioInfo.default;
throw payload._result;
}
function resolveDispatcher() {
var dispatcher = ReactSharedInternals.H;
null === dispatcher && console.error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.");
return dispatcher;
}
function releaseAsyncTransition() {
ReactSharedInternals.asyncTransitions--;
}
function startTransition(scope) {
var prevTransition = ReactSharedInternals.T, currentTransition = {};
currentTransition.types = null !== prevTransition ? prevTransition.types : null;
currentTransition._updatedFibers = /* @__PURE__ */ new Set();
ReactSharedInternals.T = currentTransition;
try {
var returnValue = scope(), onStartTransitionFinish = ReactSharedInternals.S;
null !== onStartTransitionFinish && onStartTransitionFinish(currentTransition, returnValue);
"object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && (ReactSharedInternals.asyncTransitions++, returnValue.then(releaseAsyncTransition, releaseAsyncTransition), returnValue.then(noop, reportGlobalError));
} catch (error) {
reportGlobalError(error);
} finally {
null === prevTransition && currentTransition._updatedFibers && (scope = currentTransition._updatedFibers.size, currentTransition._updatedFibers.clear(), 10 < scope && console.warn("Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.")), null !== prevTransition && null !== currentTransition.types && (null !== prevTransition.types && prevTransition.types !== currentTransition.types && console.error("We expected inner Transitions to have transferred the outer types set and that you cannot add to the outer Transition while inside the inner.This is a bug in React."), prevTransition.types = currentTransition.types), ReactSharedInternals.T = prevTransition;
}
}
function addTransitionType(type) {
var transition = ReactSharedInternals.T;
if (null !== transition) {
var transitionTypes = transition.types;
null === transitionTypes ? transition.types = [type] : -1 === transitionTypes.indexOf(type) && transitionTypes.push(type);
} else 0 === ReactSharedInternals.asyncTransitions && console.error("addTransitionType can only be called inside a `startTransition()` callback. It must be associated with a specific Transition."), startTransition(addTransitionType.bind(null, type));
}
function enqueueTask(task) {
if (null === enqueueTaskImpl) try {
var requireString = ("require" + Math.random()).slice(0, 7);
enqueueTaskImpl = (module && module[requireString]).call(module, "timers").setImmediate;
} catch (_err) {
enqueueTaskImpl = function(callback) {
!1 === didWarnAboutMessageChannel && (didWarnAboutMessageChannel = !0, "undefined" === typeof MessageChannel && console.error("This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning."));
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage(void 0);
};
}
return enqueueTaskImpl(task);
}
function aggregateErrors(errors) {
return 1 < errors.length && "function" === typeof AggregateError ? new AggregateError(errors) : errors[0];
}
function popActScope(prevActQueue, prevActScopeDepth) {
prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
actScopeDepth = prevActScopeDepth;
}
function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {
var queue = ReactSharedInternals.actQueue;
if (null !== queue) if (0 !== queue.length) try {
flushActQueue(queue);
enqueueTask(function() {
return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
});
return;
} catch (error) {
ReactSharedInternals.thrownErrors.push(error);
}
else ReactSharedInternals.actQueue = null;
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve(returnValue);
}
function flushActQueue(queue) {
if (!isFlushing) {
isFlushing = !0;
var i = 0;
try {
for (; i < queue.length; i++) {
var callback = queue[i];
do {
ReactSharedInternals.didUsePromise = !1;
var continuation = callback(!1);
if (null !== continuation) {
if (ReactSharedInternals.didUsePromise) {
queue[i] = callback;
queue.splice(0, i);
return;
}
callback = continuation;
} else break;
} while (1);
}
queue.length = 0;
} catch (error) {
queue.splice(0, i + 1), ReactSharedInternals.thrownErrors.push(error);
} finally {
isFlushing = !1;
}
}
}
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), MAYBE_ITERATOR_SYMBOL = Symbol.iterator, didWarnStateUpdateForUnmountedComponent = {}, ReactNoopUpdateQueue = {
isMounted: function() {
return !1;
},
enqueueForceUpdate: function(publicInstance) {
warnNoop(publicInstance, "forceUpdate");
},
enqueueReplaceState: function(publicInstance) {
warnNoop(publicInstance, "replaceState");
},
enqueueSetState: function(publicInstance) {
warnNoop(publicInstance, "setState");
}
}, assign = Object.assign, emptyObject = {};
Object.freeze(emptyObject);
Component.prototype.isReactComponent = {};
Component.prototype.setState = function(partialState, callback) {
if ("object" !== typeof partialState && "function" !== typeof partialState && null != partialState) throw Error("takes an object of state variables to update or a function which returns an object of state variables.");
this.updater.enqueueSetState(this, partialState, callback, "setState");
};
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, "forceUpdate");
};
var deprecatedAPIs = {
isMounted: ["isMounted", "Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."],
replaceState: ["replaceState", "Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."]
};
for (fnName in deprecatedAPIs) deprecatedAPIs.hasOwnProperty(fnName) && defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
ComponentDummy.prototype = Component.prototype;
deprecatedAPIs = PureComponent.prototype = new ComponentDummy();
deprecatedAPIs.constructor = PureComponent;
assign(deprecatedAPIs, Component.prototype);
deprecatedAPIs.isPureReactComponent = !0;
var isArrayImpl = Array.isArray, REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = {
H: null,
A: null,
T: null,
S: null,
actQueue: null,
asyncTransitions: 0,
isBatchingLegacy: !1,
didScheduleLegacyUpdate: !1,
didUsePromise: !1,
thrownErrors: [],
getCurrentStack: null,
recentlyCreatedOwnerStacks: 0
}, hasOwnProperty = Object.prototype.hasOwnProperty, createTask = console.createTask ? console.createTask : function() {
return null;
};
deprecatedAPIs = { react_stack_bottom_frame: function(callStackForError) {
return callStackForError();
} };
var specialPropKeyWarningShown, didWarnAboutOldJSXRuntime;
var didWarnAboutElementRef = {};
var unknownOwnerDebugStack = deprecatedAPIs.react_stack_bottom_frame.bind(deprecatedAPIs, UnknownOwner)();
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
var didWarnAboutMaps = !1, userProvidedKeyEscapeRegex = /\/+/g, reportGlobalError = "function" === typeof reportError ? reportError : function(error) {
if ("object" === typeof window && "function" === typeof window.ErrorEvent) {
var event = new window.ErrorEvent("error", {
bubbles: !0,
cancelable: !0,
message: "object" === typeof error && null !== error && "string" === typeof error.message ? String(error.message) : String(error),
error
});
if (!window.dispatchEvent(event)) return;
} else if ("object" === typeof process && "function" === typeof process.emit) {
process.emit("uncaughtException", error);
return;
}
console.error(error);
}, didWarnAboutMessageChannel = !1, enqueueTaskImpl = null, actScopeDepth = 0, didWarnNoAwaitAct = !1, isFlushing = !1, queueSeveralMicrotasks = "function" === typeof queueMicrotask ? function(callback) {
queueMicrotask(function() {
return queueMicrotask(callback);
});
} : enqueueTask;
deprecatedAPIs = Object.freeze({
__proto__: null,
c: function(size) {
return resolveDispatcher().useMemoCache(size);
}
});
var fnName = {
map: mapChildren,
forEach: function(children, forEachFunc, forEachContext) {
mapChildren(children, function() {
forEachFunc.apply(this, arguments);
}, forEachContext);
},
count: function(children) {
var n = 0;
mapChildren(children, function() {
n++;
});
return n;
},
toArray: function(children) {
return mapChildren(children, function(child) {
return child;
}) || [];
},
only: function(children) {
if (!isValidElement(children)) throw Error("React.Children.only expected to receive a single React element child.");
return children;
}
};
exports.Activity = REACT_ACTIVITY_TYPE;
exports.Children = fnName;
exports.Component = Component;
exports.Fragment = REACT_FRAGMENT_TYPE;
exports.Profiler = REACT_PROFILER_TYPE;
exports.PureComponent = PureComponent;
exports.StrictMode = REACT_STRICT_MODE_TYPE;
exports.Suspense = REACT_SUSPENSE_TYPE;
exports.ViewTransition = REACT_VIEW_TRANSITION_TYPE;
exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = ReactSharedInternals;
exports.__COMPILER_RUNTIME = deprecatedAPIs;
exports.act = function(callback) {
var prevActQueue = ReactSharedInternals.actQueue, prevActScopeDepth = actScopeDepth;
actScopeDepth++;
var queue = ReactSharedInternals.actQueue = null !== prevActQueue ? prevActQueue : [], didAwaitActCall = !1;
try {
var result = callback();
} catch (error) {
ReactSharedInternals.thrownErrors.push(error);
}
if (0 < ReactSharedInternals.thrownErrors.length) throw popActScope(prevActQueue, prevActScopeDepth), callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
if (null !== result && "object" === typeof result && "function" === typeof result.then) {
var thenable = result;
queueSeveralMicrotasks(function() {
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = !0, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
});
return { then: function(resolve, reject) {
didAwaitActCall = !0;
thenable.then(function(returnValue) {
popActScope(prevActQueue, prevActScopeDepth);
if (0 === prevActScopeDepth) {
try {
flushActQueue(queue), enqueueTask(function() {
return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
});
} catch (error$0) {
ReactSharedInternals.thrownErrors.push(error$0);
}
if (0 < ReactSharedInternals.thrownErrors.length) {
var _thrownError = aggregateErrors(ReactSharedInternals.thrownErrors);
ReactSharedInternals.thrownErrors.length = 0;
reject(_thrownError);
}
} else resolve(returnValue);
}, function(error) {
popActScope(prevActQueue, prevActScopeDepth);
0 < ReactSharedInternals.thrownErrors.length ? (error = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error)) : reject(error);
});
} };
}
var returnValue$jscomp$0 = result;
popActScope(prevActQueue, prevActScopeDepth);
0 === prevActScopeDepth && (flushActQueue(queue), 0 !== queue.length && queueSeveralMicrotasks(function() {
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = !0, console.error("A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\n\nawait act(() => ...)"));
}), ReactSharedInternals.actQueue = null);
if (0 < ReactSharedInternals.thrownErrors.length) throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
return { then: function(resolve, reject) {
didAwaitActCall = !0;
0 === prevActScopeDepth ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve, reject);
})) : resolve(returnValue$jscomp$0);
} };
};
exports.addTransitionType = addTransitionType;
exports.cache = function(fn) {
return function() {
return fn.apply(null, arguments);
};
};
exports.cacheSignal = function() {
return null;
};
exports.captureOwnerStack = function() {
var getCurrentStack = ReactSharedInternals.getCurrentStack;
return null === getCurrentStack ? null : getCurrentStack();
};
exports.cloneElement = function(element, config, children) {
if (null === element || void 0 === element) throw Error("The argument must be a React element, but you passed " + element + ".");
var props = assign({}, element.props), key = element.key, owner = element._owner;
if (null != config) {
var JSCompiler_inline_result;
a: {
if (hasOwnProperty.call(config, "ref") && (JSCompiler_inline_result = Object.getOwnPropertyDescriptor(config, "ref").get) && JSCompiler_inline_result.isReactWarning) {
JSCompiler_inline_result = !1;
break a;
}
JSCompiler_inline_result = void 0 !== config.ref;
}
JSCompiler_inline_result && (owner = getOwner());
hasValidKey(config) && (checkKeyStringCoercion(config.key), key = "" + config.key);
for (propName in config) !hasOwnProperty.call(config, propName) || "key" === propName || "__self" === propName || "__source" === propName || "ref" === propName && void 0 === config.ref || (props[propName] = config[propName]);
}
var propName = arguments.length - 2;
if (1 === propName) props.children = children;
else if (1 < propName) {
JSCompiler_inline_result = Array(propName);
for (var i = 0; i < propName; i++) JSCompiler_inline_result[i] = arguments[i + 2];
props.children = JSCompiler_inline_result;
}
props = ReactElement(element.type, key, props, owner, element._debugStack, element._debugTask);
for (key = 2; key < arguments.length; key++) validateChildKeys(arguments[key]);
return props;
};
exports.createContext = function(defaultValue) {
defaultValue = {
$$typeof: REACT_CONTEXT_TYPE,
_currentValue: defaultValue,
_currentValue2: defaultValue,
_threadCount: 0,
Provider: null,
Consumer: null
};
defaultValue.Provider = defaultValue;
defaultValue.Consumer = {
$$typeof: REACT_CONSUMER_TYPE,
_context: defaultValue
};
defaultValue._currentRenderer = null;
defaultValue._currentRenderer2 = null;
return defaultValue;
};
exports.createElement = function(type, config, children) {
for (var i = 2; i < arguments.length; i++) validateChildKeys(arguments[i]);
var propName;
i = {};
var key = null;
if (null != config) for (propName in didWarnAboutOldJSXRuntime || !("__self" in config) || "key" in config || (didWarnAboutOldJSXRuntime = !0, console.warn("Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform")), hasValidKey(config) && (checkKeyStringCoercion(config.key), key = "" + config.key), config) hasOwnProperty.call(config, propName) && "key" !== propName && "__self" !== propName && "__source" !== propName && (i[propName] = config[propName]);
var childrenLength = arguments.length - 2;
if (1 === childrenLength) i.children = children;
else if (1 < childrenLength) {
for (var childArray = Array(childrenLength), _i = 0; _i < childrenLength; _i++) childArray[_i] = arguments[_i + 2];
Object.freeze && Object.freeze(childArray);
i.children = childArray;
}
if (type && type.defaultProps) for (propName in childrenLength = type.defaultProps, childrenLength) void 0 === i[propName] && (i[propName] = childrenLength[propName]);
key && defineKeyPropWarningGetter(i, "function" === typeof type ? type.displayName || type.name || "Unknown" : type);
(propName = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++) ? (childArray = Error.stackTraceLimit, Error.stackTraceLimit = 10, childrenLength = Error("react-stack-top-frame"), Error.stackTraceLimit = childArray) : childrenLength = unknownOwnerDebugStack;
return ReactElement(type, key, i, getOwner(), childrenLength, propName ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
};
exports.createRef = function() {
var refObject = { current: null };
Object.seal(refObject);
return refObject;
};
exports.forwardRef = function(render) {
null != render && render.$$typeof === REACT_MEMO_TYPE ? console.error("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...)).") : "function" !== typeof render ? console.error("forwardRef requires a render function but was given %s.", null === render ? "null" : typeof render) : 0 !== render.length && 2 !== render.length && console.error("forwardRef render functions accept exactly two parameters: props and ref. %s", 1 === render.length ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined.");
null != render && null != render.defaultProps && console.error("forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?");
var elementType = {
$$typeof: REACT_FORWARD_REF_TYPE,
render
}, ownName;
Object.defineProperty(elementType, "displayName", {
enumerable: !1,
configurable: !0,
get: function() {
return ownName;
},
set: function(name) {
ownName = name;
render.name || render.displayName || (Object.defineProperty(render, "name", { value: name }), render.displayName = name);
}
});
return elementType;
};
exports.isValidElement = isValidElement;
exports.lazy = function(ctor) {
ctor = {
_status: -1,
_result: ctor
};
var lazyType = {
$$typeof: REACT_LAZY_TYPE,
_payload: ctor,
_init: lazyInitializer
}, ioInfo = {
name: "lazy",
start: -1,
end: -1,
value: null,
owner: null,
debugStack: Error("react-stack-top-frame"),
debugTask: console.createTask ? console.createTask("lazy()") : null
};
ctor._ioInfo = ioInfo;
lazyType._debugInfo = [{ awaited: ioInfo }];
return lazyType;
};
exports.memo = function(type, compare) {
type ?? console.error("memo: The first argument must be a component. Instead received: %s", null === type ? "null" : typeof type);
compare = {
$$typeof: REACT_MEMO_TYPE,
type,
compare: void 0 === compare ? null : compare
};
var ownName;
Object.defineProperty(compare, "displayName", {
enumerable: !1,
configurable: !0,
get: function() {
return ownName;
},
set: function(name) {
ownName = name;
type.name || type.displayName || (Object.defineProperty(type, "name", { value: name }), type.displayName = name);
}
});
return compare;
};
exports.startTransition = startTransition;
exports.unstable_useCacheRefresh = function() {
return resolveDispatcher().useCacheRefresh();
};
exports.use = function(usable) {
return resolveDispatcher().use(usable);
};
exports.useActionState = function(action, initialState, permalink) {
return resolveDispatcher().useActionState(action, initialState, permalink);
};
exports.useCallback = function(callback, deps) {
return resolveDispatcher().useCallback(callback, deps);
};
exports.useContext = function(Context) {
var dispatcher = resolveDispatcher();
Context.$$typeof === REACT_CONSUMER_TYPE && console.error("Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?");
return dispatcher.useContext(Context);
};
exports.useDebugValue = function(value, formatterFn) {
return resolveDispatcher().useDebugValue(value, formatterFn);
};
exports.useDeferredValue = function(value, initialValue) {
return resolveDispatcher().useDeferredValue(value, initialValue);
};
exports.useEffect = function(create, deps) {
create ?? console.warn("React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?");
return resolveDispatcher().useEffect(create, deps);
};
exports.useEffectEvent = function(callback) {
return resolveDispatcher().useEffectEvent(callback);
};
exports.useId = function() {
return resolveDispatcher().useId();
};
exports.useImperativeHandle = function(ref, create, deps) {
return resolveDispatcher().useImperativeHandle(ref, create, deps);
};
exports.useInsertionEffect = function(create, deps) {
create ?? console.warn("React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?");
return resolveDispatcher().useInsertionEffect(create, deps);
};
exports.useLayoutEffect = function(create, deps) {
create ?? console.warn("React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?");
return resolveDispatcher().useLayoutEffect(create, deps);
};
exports.useMemo = function(create, deps) {
return resolveDispatcher().useMemo(create, deps);
};
exports.useOptimistic = function(passthrough, reducer) {
return resolveDispatcher().useOptimistic(passthrough, reducer);
};
exports.useReducer = function(reducer, initialArg, init) {
return resolveDispatcher().useReducer(reducer, initialArg, init);
};
exports.useRef = function(initialValue) {
return resolveDispatcher().useRef(initialValue);
};
exports.useState = function(initialState) {
return resolveDispatcher().useState(initialState);
};
exports.useSyncExternalStore = function(subscribe, getSnapshot, getServerSnapshot) {
return resolveDispatcher().useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
};
exports.useTransition = function() {
return resolveDispatcher().useTransition();
};
exports.version = "19.3.0";
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
})();
}));
//#endregion
//#region node_modules/react/index.js
var require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = require_react_development();
}));
//#endregion
export default require_react();
export { require_react as t };
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"react.js","names":[],"sources":["../../react/cjs/react.development.js","../../react/index.js"],"sourcesContent":["/**\n * @license React\n * react.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function defineDeprecationWarning(methodName, info) {\n Object.defineProperty(Component.prototype, methodName, {\n get: function () {\n console.warn(\n \"%s(...) is deprecated in plain JavaScript React classes. %s\",\n info[0],\n info[1]\n );\n }\n });\n }\n function getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable)\n return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n }\n function warnNoop(publicInstance, callerName) {\n publicInstance =\n ((publicInstance = publicInstance.constructor) &&\n (publicInstance.displayName || publicInstance.name)) ||\n \"ReactClass\";\n var warningKey = publicInstance + \".\" + callerName;\n didWarnStateUpdateForUnmountedComponent[warningKey] ||\n (console.error(\n \"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.\",\n callerName,\n publicInstance\n ),\n (didWarnStateUpdateForUnmountedComponent[warningKey] = !0));\n }\n function Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function ComponentDummy() {}\n function PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function noop() {}\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n case REACT_VIEW_TRANSITION_TYPE:\n return \"ViewTransition\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayNaLine truncated
+210
View File
@@ -0,0 +1,210 @@
import { t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
//#region node_modules/react/cjs/react-jsx-dev-runtime.development.js
/**
* @license React
* react-jsx-dev-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_react_jsx_dev_runtime_development = /* @__PURE__ */ __commonJSMin(((exports) => {
(function() {
function getComponentNameFromType(type) {
if (null == type) return null;
if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
if ("string" === typeof type) return type;
switch (type) {
case REACT_FRAGMENT_TYPE: return "Fragment";
case REACT_PROFILER_TYPE: return "Profiler";
case REACT_STRICT_MODE_TYPE: return "StrictMode";
case REACT_SUSPENSE_TYPE: return "Suspense";
case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList";
case REACT_ACTIVITY_TYPE: return "Activity";
case REACT_VIEW_TRANSITION_TYPE: return "ViewTransition";
}
if ("object" === typeof type) switch ("number" === typeof type.tag && console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), type.$$typeof) {
case REACT_PORTAL_TYPE: return "Portal";
case REACT_CONTEXT_TYPE: return type.displayName || "Context";
case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer";
case REACT_FORWARD_REF_TYPE:
var innerType = type.render;
type = type.displayName;
type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
return type;
case REACT_MEMO_TYPE: return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
case REACT_LAZY_TYPE:
innerType = type._payload;
type = type._init;
try {
return getComponentNameFromType(type(innerType));
} catch (x) {}
}
return null;
}
function testStringCoercion(value) {
return "" + value;
}
function checkKeyStringCoercion(value) {
try {
testStringCoercion(value);
var JSCompiler_inline_result = !1;
} catch (e) {
JSCompiler_inline_result = !0;
}
if (JSCompiler_inline_result) {
JSCompiler_inline_result = console;
var JSCompiler_temp_const = JSCompiler_inline_result.error;
var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
JSCompiler_temp_const.call(JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0);
return testStringCoercion(value);
}
}
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) return "<>";
if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE) return "<...>";
try {
var name = getComponentNameFromType(type);
return name ? "<" + name + ">" : "<...>";
} catch (x) {
return "<...>";
}
}
function getOwner() {
var dispatcher = ReactSharedInternals.A;
return null === dispatcher ? null : dispatcher.getOwner();
}
function UnknownOwner() {
return Error("react-stack-top-frame");
}
function hasValidKey(config) {
if (hasOwnProperty.call(config, "key")) {
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
if (getter && getter.isReactWarning) return !1;
}
return void 0 !== config.key;
}
function defineKeyPropWarningGetter(props, displayName) {
function warnAboutAccessingKey() {
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName));
}
warnAboutAccessingKey.isReactWarning = !0;
Object.defineProperty(props, "key", {
get: warnAboutAccessingKey,
configurable: !0
});
}
function elementRefGetterWithDeprecationWarning() {
var componentName = getComponentNameFromType(this.type);
didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = !0, console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));
componentName = this.props.ref;
return void 0 !== componentName ? componentName : null;
}
function ReactElement(type, key, props, owner, debugStack, debugTask) {
var refProp = props.ref;
type = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props,
_owner: owner
};
null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
enumerable: !1,
get: elementRefGetterWithDeprecationWarning
}) : Object.defineProperty(type, "ref", {
enumerable: !1,
value: null
});
type._store = {};
Object.defineProperty(type._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
});
Object.defineProperty(type, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
});
Object.defineProperty(type, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugStack
});
Object.defineProperty(type, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugTask
});
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
return type;
}
function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
var children = config.children;
if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) {
for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++) validateChildKeys(children[isStaticChildren]);
Object.freeze && Object.freeze(children);
} else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
else validateChildKeys(children);
if (hasOwnProperty.call(config, "key")) {
children = getComponentNameFromType(type);
var keys = Object.keys(config).filter(function(k) {
return "key" !== k;
});
isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}";
didWarnAboutKeySpread[children + isStaticChildren] || (keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}", console.error("A props object containing a \"key\" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />", isStaticChildren, children, keys, children), didWarnAboutKeySpread[children + isStaticChildren] = !0);
}
children = null;
void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
if ("key" in config) {
maybeKey = {};
for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
} else maybeKey = config;
children && defineKeyPropWarningGetter(maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type);
return ReactElement(type, children, maybeKey, getOwner(), debugStack, debugTask);
}
function validateChildKeys(node) {
isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
}
function isValidElement(object) {
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
}
var React = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
return null;
};
React = { react_stack_bottom_frame: function(callStackForError) {
return callStackForError();
} };
var specialPropKeyWarningShown;
var didWarnAboutElementRef = {};
var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(React, UnknownOwner)();
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
var didWarnAboutKeySpread = {};
exports.Fragment = REACT_FRAGMENT_TYPE;
exports.jsxDEV = function(type, config, maybeKey, isStaticChildren) {
var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
if (trackActualOwner) {
var previousStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 10;
var debugStackDEV = Error("react-stack-top-frame");
Error.stackTraceLimit = previousStackTraceLimit;
} else debugStackDEV = unknownOwnerDebugStack;
return jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStackDEV, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
};
})();
}));
//#endregion
//#region node_modules/react/jsx-dev-runtime.js
var require_jsx_dev_runtime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = require_react_jsx_dev_runtime_development();
}));
//#endregion
export default require_jsx_dev_runtime();
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"react_jsx-dev-runtime.js","names":[],"sources":["../../react/cjs/react-jsx-dev-runtime.development.js","../../react/jsx-dev-runtime.js"],"sourcesContent":["/**\n * @license React\n * react-jsx-dev-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n case REACT_VIEW_TRANSITION_TYPE:\n return \"ViewTransition\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in Line truncated
+220
View File
@@ -0,0 +1,220 @@
import { t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
//#region node_modules/react/cjs/react-jsx-runtime.development.js
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_react_jsx_runtime_development = /* @__PURE__ */ __commonJSMin(((exports) => {
(function() {
function getComponentNameFromType(type) {
if (null == type) return null;
if ("function" === typeof type) return type.$$typeof === REACT_CLIENT_REFERENCE ? null : type.displayName || type.name || null;
if ("string" === typeof type) return type;
switch (type) {
case REACT_FRAGMENT_TYPE: return "Fragment";
case REACT_PROFILER_TYPE: return "Profiler";
case REACT_STRICT_MODE_TYPE: return "StrictMode";
case REACT_SUSPENSE_TYPE: return "Suspense";
case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList";
case REACT_ACTIVITY_TYPE: return "Activity";
case REACT_VIEW_TRANSITION_TYPE: return "ViewTransition";
}
if ("object" === typeof type) switch ("number" === typeof type.tag && console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), type.$$typeof) {
case REACT_PORTAL_TYPE: return "Portal";
case REACT_CONTEXT_TYPE: return type.displayName || "Context";
case REACT_CONSUMER_TYPE: return (type._context.displayName || "Context") + ".Consumer";
case REACT_FORWARD_REF_TYPE:
var innerType = type.render;
type = type.displayName;
type || (type = innerType.displayName || innerType.name || "", type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef");
return type;
case REACT_MEMO_TYPE: return innerType = type.displayName || null, null !== innerType ? innerType : getComponentNameFromType(type.type) || "Memo";
case REACT_LAZY_TYPE:
innerType = type._payload;
type = type._init;
try {
return getComponentNameFromType(type(innerType));
} catch (x) {}
}
return null;
}
function testStringCoercion(value) {
return "" + value;
}
function checkKeyStringCoercion(value) {
try {
testStringCoercion(value);
var JSCompiler_inline_result = !1;
} catch (e) {
JSCompiler_inline_result = !0;
}
if (JSCompiler_inline_result) {
JSCompiler_inline_result = console;
var JSCompiler_temp_const = JSCompiler_inline_result.error;
var JSCompiler_inline_result$jscomp$0 = "function" === typeof Symbol && Symbol.toStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object";
JSCompiler_temp_const.call(JSCompiler_inline_result, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", JSCompiler_inline_result$jscomp$0);
return testStringCoercion(value);
}
}
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) return "<>";
if ("object" === typeof type && null !== type && type.$$typeof === REACT_LAZY_TYPE) return "<...>";
try {
var name = getComponentNameFromType(type);
return name ? "<" + name + ">" : "<...>";
} catch (x) {
return "<...>";
}
}
function getOwner() {
var dispatcher = ReactSharedInternals.A;
return null === dispatcher ? null : dispatcher.getOwner();
}
function UnknownOwner() {
return Error("react-stack-top-frame");
}
function hasValidKey(config) {
if (hasOwnProperty.call(config, "key")) {
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
if (getter && getter.isReactWarning) return !1;
}
return void 0 !== config.key;
}
function defineKeyPropWarningGetter(props, displayName) {
function warnAboutAccessingKey() {
specialPropKeyWarningShown || (specialPropKeyWarningShown = !0, console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", displayName));
}
warnAboutAccessingKey.isReactWarning = !0;
Object.defineProperty(props, "key", {
get: warnAboutAccessingKey,
configurable: !0
});
}
function elementRefGetterWithDeprecationWarning() {
var componentName = getComponentNameFromType(this.type);
didWarnAboutElementRef[componentName] || (didWarnAboutElementRef[componentName] = !0, console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."));
componentName = this.props.ref;
return void 0 !== componentName ? componentName : null;
}
function ReactElement(type, key, props, owner, debugStack, debugTask) {
var refProp = props.ref;
type = {
$$typeof: REACT_ELEMENT_TYPE,
type,
key,
props,
_owner: owner
};
null !== (void 0 !== refProp ? refProp : null) ? Object.defineProperty(type, "ref", {
enumerable: !1,
get: elementRefGetterWithDeprecationWarning
}) : Object.defineProperty(type, "ref", {
enumerable: !1,
value: null
});
type._store = {};
Object.defineProperty(type._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
});
Object.defineProperty(type, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
});
Object.defineProperty(type, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugStack
});
Object.defineProperty(type, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugTask
});
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
return type;
}
function jsxDEVImpl(type, config, maybeKey, isStaticChildren, debugStack, debugTask) {
var children = config.children;
if (void 0 !== children) if (isStaticChildren) if (isArrayImpl(children)) {
for (isStaticChildren = 0; isStaticChildren < children.length; isStaticChildren++) validateChildKeys(children[isStaticChildren]);
Object.freeze && Object.freeze(children);
} else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
else validateChildKeys(children);
if (hasOwnProperty.call(config, "key")) {
children = getComponentNameFromType(type);
var keys = Object.keys(config).filter(function(k) {
return "key" !== k;
});
isStaticChildren = 0 < keys.length ? "{key: someKey, " + keys.join(": ..., ") + ": ...}" : "{key: someKey}";
didWarnAboutKeySpread[children + isStaticChildren] || (keys = 0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}", console.error("A props object containing a \"key\" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />", isStaticChildren, children, keys, children), didWarnAboutKeySpread[children + isStaticChildren] = !0);
}
children = null;
void 0 !== maybeKey && (checkKeyStringCoercion(maybeKey), children = "" + maybeKey);
hasValidKey(config) && (checkKeyStringCoercion(config.key), children = "" + config.key);
if ("key" in config) {
maybeKey = {};
for (var propName in config) "key" !== propName && (maybeKey[propName] = config[propName]);
} else maybeKey = config;
children && defineKeyPropWarningGetter(maybeKey, "function" === typeof type ? type.displayName || type.name || "Unknown" : type);
return ReactElement(type, children, maybeKey, getOwner(), debugStack, debugTask);
}
function validateChildKeys(node) {
isValidElement(node) ? node._store && (node._store.validated = 1) : "object" === typeof node && null !== node && node.$$typeof === REACT_LAZY_TYPE && ("fulfilled" === node._payload.status ? isValidElement(node._payload.value) && node._payload.value._store && (node._payload.value._store.validated = 1) : node._store && (node._store.validated = 1));
}
function isValidElement(object) {
return "object" === typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE;
}
var React = require_react(), REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"), REACT_PORTAL_TYPE = Symbol.for("react.portal"), REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"), REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"), REACT_PROFILER_TYPE = Symbol.for("react.profiler"), REACT_CONSUMER_TYPE = Symbol.for("react.consumer"), REACT_CONTEXT_TYPE = Symbol.for("react.context"), REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"), REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"), REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"), REACT_MEMO_TYPE = Symbol.for("react.memo"), REACT_LAZY_TYPE = Symbol.for("react.lazy"), REACT_ACTIVITY_TYPE = Symbol.for("react.activity"), REACT_VIEW_TRANSITION_TYPE = Symbol.for("react.view_transition"), REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"), ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, hasOwnProperty = Object.prototype.hasOwnProperty, isArrayImpl = Array.isArray, createTask = console.createTask ? console.createTask : function() {
return null;
};
React = { react_stack_bottom_frame: function(callStackForError) {
return callStackForError();
} };
var specialPropKeyWarningShown;
var didWarnAboutElementRef = {};
var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(React, UnknownOwner)();
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
var didWarnAboutKeySpread = {};
exports.Fragment = REACT_FRAGMENT_TYPE;
exports.jsx = function(type, config, maybeKey) {
var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
if (trackActualOwner) {
var previousStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 10;
var debugStackDEV = Error("react-stack-top-frame");
Error.stackTraceLimit = previousStackTraceLimit;
} else debugStackDEV = unknownOwnerDebugStack;
return jsxDEVImpl(type, config, maybeKey, !1, debugStackDEV, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
};
exports.jsxs = function(type, config, maybeKey) {
var trackActualOwner = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
if (trackActualOwner) {
var previousStackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 10;
var debugStackDEV = Error("react-stack-top-frame");
Error.stackTraceLimit = previousStackTraceLimit;
} else debugStackDEV = unknownOwnerDebugStack;
return jsxDEVImpl(type, config, maybeKey, !0, debugStackDEV, trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask);
};
})();
}));
//#endregion
//#region node_modules/react/jsx-runtime.js
var require_jsx_runtime = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = require_react_jsx_runtime_development();
}));
//#endregion
export default require_jsx_runtime();
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"react_jsx-runtime.js","names":[],"sources":["../../react/cjs/react-jsx-runtime.development.js","../../react/jsx-runtime.js"],"sourcesContent":["/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n case REACT_VIEW_TRANSITION_TYPE:\n return \"ViewTransition\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` beinLine truncated
+33
View File
@@ -0,0 +1,33 @@
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __exportAll = (all, no_symbols) => {
let target = {};
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
return target;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
export { __exportAll as n, __toESM as r, __commonJSMin as t };
+73
View File
@@ -0,0 +1,73 @@
import { t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
//#region node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js
/**
* @license React
* use-sync-external-store-shim.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var require_use_sync_external_store_shim_development = /* @__PURE__ */ __commonJSMin(((exports) => {
(function() {
function is(x, y) {
return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
}
function useSyncExternalStore$2(subscribe, getSnapshot) {
didWarnOld18Alpha || void 0 === React.startTransition || (didWarnOld18Alpha = !0, console.error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."));
var value = getSnapshot();
if (!didWarnUncachedGetSnapshot) {
var cachedValue = getSnapshot();
objectIs(value, cachedValue) || (console.error("The result of getSnapshot should be cached to avoid an infinite loop"), didWarnUncachedGetSnapshot = !0);
}
cachedValue = useState({ inst: {
value,
getSnapshot
} });
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
useLayoutEffect(function() {
inst.value = value;
inst.getSnapshot = getSnapshot;
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
}, [
subscribe,
value,
getSnapshot
]);
useEffect(function() {
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
return subscribe(function() {
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
});
}, [subscribe]);
useDebugValue(value);
return value;
}
function checkIfSnapshotChanged(inst) {
var latestGetSnapshot = inst.getSnapshot;
inst = inst.value;
try {
var nextValue = latestGetSnapshot();
return !objectIs(inst, nextValue);
} catch (error) {
return !0;
}
}
function useSyncExternalStore$1(subscribe, getSnapshot) {
return getSnapshot();
}
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
var React = require_react(), objectIs = "function" === typeof Object.is ? Object.is : is, useState = React.useState, useEffect = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue = React.useDebugValue, didWarnOld18Alpha = !1, didWarnUncachedGetSnapshot = !1, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
exports.useSyncExternalStore = void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
})();
}));
//#endregion
//#region node_modules/use-sync-external-store/shim/index.js
var require_shim = /* @__PURE__ */ __commonJSMin(((exports, module) => {
module.exports = require_use_sync_external_store_shim_development();
}));
//#endregion
export { require_shim as t };
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"shim-BX6a9SD7.js","names":[],"sources":["../../use-sync-external-store/cjs/use-sync-external-store-shim.development.js","../../use-sync-external-store/shim/index.js"],"sourcesContent":["/**\n * @license React\n * use-sync-external-store-shim.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function is(x, y) {\n return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);\n }\n function useSyncExternalStore$2(subscribe, getSnapshot) {\n didWarnOld18Alpha ||\n void 0 === React.startTransition ||\n ((didWarnOld18Alpha = !0),\n console.error(\n \"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release.\"\n ));\n var value = getSnapshot();\n if (!didWarnUncachedGetSnapshot) {\n var cachedValue = getSnapshot();\n objectIs(value, cachedValue) ||\n (console.error(\n \"The result of getSnapshot should be cached to avoid an infinite loop\"\n ),\n (didWarnUncachedGetSnapshot = !0));\n }\n cachedValue = useState({\n inst: { value: value, getSnapshot: getSnapshot }\n });\n var inst = cachedValue[0].inst,\n forceUpdate = cachedValue[1];\n useLayoutEffect(\n function () {\n inst.value = value;\n inst.getSnapshot = getSnapshot;\n checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });\n },\n [subscribe, value, getSnapshot]\n );\n useEffect(\n function () {\n checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });\n return subscribe(function () {\n checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });\n });\n },\n [subscribe]\n );\n useDebugValue(value);\n return value;\n }\n function checkIfSnapshotChanged(inst) {\n var latestGetSnapshot = inst.getSnapshot;\n inst = inst.value;\n try {\n var nextValue = latestGetSnapshot();\n return !objectIs(inst, nextValue);\n } catch (error) {\n return !0;\n }\n }\n function useSyncExternalStore$1(subscribe, getSnapshot) {\n return getSnapshot();\n }\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());\n var React = require(\"react\"),\n objectIs = \"function\" === typeof Object.is ? Object.is : is,\n useState = React.useState,\n useEffect = React.useEffect,\n useLayoutEffect = React.useLayoutEffect,\n useDebugValue = React.useDebugValue,\n didWarnOld18Alpha = !1,\n didWarnUncachedGetSnapshot = !1,\n shim =\n \"undefined\" === typeof window ||\n \"undefined\" === typeof window.document ||\n \"undefined\" === typeof window.document.createElement\n ? useSyncExternalStore$1\n : useSyncExternalStore$2;\n exports.useSyncExternalStore =\n void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('../cjs/use-sync-external-store-shim.production.js');\n} else {\n module.exports = require('../cjs/use-sync-external-store-shim.development.js');\n}\n"],"mappings":";;;;;;;;;;;;;CAWA,CACG,WAAY;EACX,SAAS,GAAG,GAAG,GAAG;GAChB,OAAQ,MAAM,MAAM,MAAM,KAAK,IAAI,MAAM,IAAI,MAAQ,MAAM,KAAK,MAAM;EACxE;EACA,SAAS,uBAAuB,WAAW,aAAa;GACtD,qBACE,KAAK,MAAM,MAAM,oBACf,oBAAoB,CAAC,GACvB,QAAQ,MACN,gMACF;GACF,IAAI,QAAQ,YAAY;GACxB,IAAI,CAAC,4BAA4B;IAC/B,IAAI,cAAc,YAAY;IAC9B,SAAS,OAAO,WAAW,MACxB,QAAQ,MACP,sEACF,GACC,6BAA6B,CAAC;GACnC;GACA,cAAc,SAAS,EACrB,MAAM;IAAS;IAAoB;GAAY,EACjD,CAAC;GACD,IAAI,OAAO,YAAY,EAAE,CAAC,MACxB,cAAc,YAAY;GAC5B,gBACE,WAAY;IACV,KAAK,QAAQ;IACb,KAAK,cAAc;IACnB,uBAAuB,IAAI,KAAK,YAAY,EAAQ,KAAK,CAAC;GAC5D,GACA;IAAC;IAAW;IAAO;GAAW,CAChC;GACA,UACE,WAAY;IACV,uBAAuB,IAAI,KAAK,YAAY,EAAQ,KAAK,CAAC;IAC1D,OAAO,UAAU,WAAY;KAC3B,uBAAuB,IAAI,KAAK,YAAY,EAAQ,KAAK,CAAC;IAC5D,CAAC;GACH,GACA,CAAC,SAAS,CACZ;GACA,cAAc,KAAK;GACnB,OAAO;EACT;EACA,SAAS,uBAAuB,MAAM;GACpC,IAAI,oBAAoB,KAAK;GAC7B,OAAO,KAAK;GACZ,IAAI;IACF,IAAI,YAAY,kBAAkB;IAClC,OAAO,CAAC,SAAS,MAAM,SAAS;GAClC,SAAS,OAAO;IACd,OAAO,CAAC;GACV;EACF;EACA,SAAS,uBAAuB,WAAW,aAAa;Line truncated
+923
View File
@@ -0,0 +1,923 @@
import { r as __toESM } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
import { t as require_shim } from "./shim-BX6a9SD7.js";
//#region node_modules/dequal/lite/index.mjs
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
var import_shim = require_shim();
var has = Object.prototype.hasOwnProperty;
function dequal(foo, bar) {
var ctor, len;
if (foo === bar) return true;
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
if (ctor === Date) return foo.getTime() === bar.getTime();
if (ctor === RegExp) return foo.toString() === bar.toString();
if (ctor === Array) {
if ((len = foo.length) === bar.length) while (len-- && dequal(foo[len], bar[len]));
return len === -1;
}
if (!ctor || typeof foo === "object") {
len = 0;
for (ctor in foo) {
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
}
return Object.keys(bar).length === len;
}
}
return foo !== foo && bar !== bar;
}
var SWRGlobalState = /* @__PURE__ */ new WeakMap();
var noop = () => {};
var OBJECT = Object;
var isUndefined = (v) => v === void 0;
var isFunction = (v) => typeof v == "function";
var mergeObjects = (a, b) => ({
...a,
...b
});
var isPromiseLike = (x) => isFunction(x.then);
var EMPTY_CACHE = {};
var INITIAL_CACHE = {};
var STR_UNDEFINED = "undefined";
var isWindowDefined = typeof window != STR_UNDEFINED;
var isDocumentDefined = typeof document != STR_UNDEFINED;
var isLegacyDeno = isWindowDefined && "Deno" in window;
var hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED;
var createCacheHelper = (cache, key) => {
const state = SWRGlobalState.get(cache);
return [
() => !isUndefined(key) && cache.get(key) || EMPTY_CACHE,
(info) => {
if (!isUndefined(key)) {
const prev = cache.get(key);
if (!(key in INITIAL_CACHE)) INITIAL_CACHE[key] = prev;
state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);
}
},
state[6],
() => {
if (!isUndefined(key)) {
if (key in INITIAL_CACHE) return INITIAL_CACHE[key];
}
return !isUndefined(key) && cache.get(key) || EMPTY_CACHE;
}
];
};
/**
* Due to the bug https://bugs.chromium.org/p/chromium/issues/detail?id=678075,
* it's not reliable to detect if the browser is currently online or offline
* based on `navigator.onLine`.
* As a workaround, we always assume it's online on the first load, and change
* the status upon `online` or `offline` events.
*/ var online = true;
var isOnline = () => online;
var [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [window.addEventListener.bind(window), window.removeEventListener.bind(window)] : [noop, noop];
var isVisible = () => {
const visibilityState = isDocumentDefined && document.visibilityState;
return isUndefined(visibilityState) || visibilityState !== "hidden";
};
var initFocus = (callback) => {
if (isDocumentDefined) document.addEventListener("visibilitychange", callback);
onWindowEvent("focus", callback);
return () => {
if (isDocumentDefined) document.removeEventListener("visibilitychange", callback);
offWindowEvent("focus", callback);
};
};
var initReconnect = (callback) => {
const onOnline = () => {
online = true;
callback();
};
const onOffline = () => {
online = false;
};
onWindowEvent("online", onOnline);
onWindowEvent("offline", onOffline);
return () => {
offWindowEvent("online", onOnline);
offWindowEvent("offline", onOffline);
};
};
var preset = {
isOnline,
isVisible
};
var defaultConfigOptions = {
initFocus,
initReconnect
};
var IS_REACT_LEGACY = !import_react.useId;
var IS_SERVER = !isWindowDefined || isLegacyDeno;
var rAF = (f) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f) : setTimeout(f, 1);
var useIsomorphicLayoutEffect = IS_SERVER ? import_react.useEffect : import_react.useLayoutEffect;
var navigatorConnection = typeof navigator !== "undefined" && navigator.connection;
var slowConnection = !IS_SERVER && navigatorConnection && (["slow-2g", "2g"].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
var table = /* @__PURE__ */ new WeakMap();
var getTypeName = (value) => OBJECT.prototype.toString.call(value);
var isObjectTypeName = (typeName, type) => typeName === `[object ${type}]`;
var counter = 0;
var stableHash = (arg) => {
const type = typeof arg;
const typeName = getTypeName(arg);
const isDate = isObjectTypeName(typeName, "Date");
const isRegex = isObjectTypeName(typeName, "RegExp");
const isPlainObject = isObjectTypeName(typeName, "Object");
let result;
let index;
if (OBJECT(arg) === arg && !isDate && !isRegex) {
result = table.get(arg);
if (result) return result;
result = ++counter + "~";
table.set(arg, result);
if (Array.isArray(arg)) {
result = "@";
for (index = 0; index < arg.length; index++) result += stableHash(arg[index]) + ",";
table.set(arg, result);
}
if (isPlainObject) {
result = "#";
const keys = OBJECT.keys(arg).sort();
while (!isUndefined(index = keys.pop())) if (!isUndefined(arg[index])) result += index + ":" + stableHash(arg[index]) + ",";
table.set(arg, result);
}
} else result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
return result;
};
var serialize = (key) => {
if (isFunction(key)) try {
key = key();
} catch (err) {
key = "";
}
const args = key;
key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : "";
return [key, args];
};
var __timestamp = 0;
var getTimestamp = () => ++__timestamp;
async function internalMutate(...args) {
const [cache, _key, _data, _opts] = args;
const options = mergeObjects({
populateCache: true,
throwOnError: true
}, typeof _opts === "boolean" ? { revalidate: _opts } : _opts || {});
let populateCache = options.populateCache;
const rollbackOnErrorOption = options.rollbackOnError;
let optimisticData = options.optimisticData;
const rollbackOnError = (error) => {
return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false;
};
const throwOnError = options.throwOnError;
if (isFunction(_key)) {
const keyFilter = _key;
const matchedKeys = [];
const it = cache.keys();
for (const key of it) if (!/^\$(inf|sub)\$/.test(key) && keyFilter(cache.get(key)._k)) matchedKeys.push(key);
return Promise.all(matchedKeys.map(mutateByKey));
}
return mutateByKey(_key);
async function mutateByKey(_k) {
const [key] = serialize(_k);
if (!key) return;
const [get, set] = createCacheHelper(cache, key);
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache);
const startRevalidate = () => {
const revalidators = EVENT_REVALIDATORS[key];
if (isFunction(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false) {
delete FETCH[key];
delete PRELOAD[key];
if (revalidators && revalidators[0]) return revalidators[0](2).then(() => get().data);
}
return get().data;
};
if (args.length < 3) return startRevalidate();
let data = _data;
let error;
let isError = false;
const beforeMutationTs = getTimestamp();
MUTATION[key] = [beforeMutationTs, 0];
const hasOptimisticData = !isUndefined(optimisticData);
const state = get();
const displayedData = state.data;
const currentData = state._c;
const committedData = isUndefined(currentData) ? displayedData : currentData;
if (hasOptimisticData) {
optimisticData = isFunction(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
set({
data: optimisticData,
_c: committedData
});
}
if (isFunction(data)) try {
data = data(committedData);
} catch (err) {
error = err;
isError = true;
}
if (data && isPromiseLike(data)) {
data = await data.catch((err) => {
error = err;
isError = true;
});
if (beforeMutationTs !== MUTATION[key][0]) {
if (isError) throw error;
return data;
} else if (isError && hasOptimisticData && rollbackOnError(error)) {
populateCache = true;
set({
data: committedData,
_c: void 0
});
}
}
if (populateCache) {
if (!isError) {
if (isFunction(populateCache)) set({
data: populateCache(data, committedData),
error: void 0,
_c: void 0
});
else set({
data,
error: void 0,
_c: void 0
});
}
}
MUTATION[key][1] = getTimestamp();
Promise.resolve(startRevalidate()).then(() => {
set({ _c: void 0 });
});
if (isError) {
if (throwOnError) throw error;
return;
}
return data;
}
}
var revalidateAllKeys = (revalidators, type) => {
for (const key in revalidators) if (revalidators[key][0]) revalidators[key][0](type);
};
var initCache = (provider, options) => {
if (!SWRGlobalState.has(provider)) {
const opts = mergeObjects(defaultConfigOptions, options);
const EVENT_REVALIDATORS = Object.create(null);
const mutate = internalMutate.bind(void 0, provider);
let unmount = noop;
const subscriptions = Object.create(null);
const subscribe = (key, callback) => {
const subs = subscriptions[key] || [];
subscriptions[key] = subs;
subs.push(callback);
return () => {
const index = subs.indexOf(callback);
if (index >= 0) {
subs[index] = subs[subs.length - 1];
subs.pop();
}
};
};
const setter = (key, value, prev) => {
provider.set(key, value);
const subs = subscriptions[key];
if (subs) for (const fn of subs) fn(value, prev);
};
const unload = (unloadOptions) => {
const state = SWRGlobalState.get(provider);
const [, MUTATION, FETCH, PRELOAD] = state;
const ts = getTimestamp();
state[8]++;
for (const key in FETCH) delete FETCH[key];
for (const key in PRELOAD) delete PRELOAD[key];
for (const key in MUTATION) MUTATION[key] = [ts, ts];
const emptyState = {};
for (const key of [...provider.keys()]) {
const prev = provider.get(key);
provider.delete(key);
const subs = subscriptions[key];
if (subs) for (const fn of subs) fn(emptyState, prev);
}
const revalidate = !unloadOptions || unloadOptions.revalidate !== false;
for (const key in EVENT_REVALIDATORS) {
const revalidators = EVENT_REVALIDATORS[key];
for (let i = 0; i < revalidators.length; i++) revalidators[i](4, { revalidate: revalidate && !i });
}
};
const initProvider = () => {
if (!SWRGlobalState.has(provider)) {
SWRGlobalState.set(provider, [
EVENT_REVALIDATORS,
Object.create(null),
Object.create(null),
Object.create(null),
mutate,
setter,
subscribe,
unload,
0
]);
if (!IS_SERVER) {
const releaseFocus = opts.initFocus(setTimeout.bind(void 0, revalidateAllKeys.bind(void 0, EVENT_REVALIDATORS, 0)));
const releaseReconnect = opts.initReconnect(setTimeout.bind(void 0, revalidateAllKeys.bind(void 0, EVENT_REVALIDATORS, 1)));
unmount = () => {
releaseFocus && releaseFocus();
releaseReconnect && releaseReconnect();
SWRGlobalState.delete(provider);
};
}
}
};
initProvider();
return [
provider,
mutate,
initProvider,
unmount,
unload
];
}
const state = SWRGlobalState.get(provider);
return [
provider,
state[4],
void 0,
void 0,
state[7]
];
};
var onErrorRetry = (_, __, config, revalidate, opts) => {
const maxRetryCount = config.errorRetryCount;
const currentRetryCount = opts.retryCount;
const timeout = ~~((Math.random() + .5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
if (!isUndefined(maxRetryCount) && currentRetryCount > maxRetryCount) return;
setTimeout(revalidate, timeout, opts);
};
var compare = dequal;
var [cache, mutate, , , unload] = initCache(/* @__PURE__ */ new Map());
var defaultConfig = mergeObjects({
onLoadingSlow: noop,
onSuccess: noop,
onError: noop,
onErrorRetry,
onDiscarded: noop,
revalidateOnFocus: true,
revalidateOnReconnect: true,
revalidateIfStale: true,
shouldRetryOnError: true,
errorRetryInterval: slowConnection ? 1e4 : 5e3,
focusThrottleInterval: 5e3,
dedupingInterval: 2e3,
loadingTimeout: slowConnection ? 5e3 : 3e3,
compare,
isPaused: () => false,
cache,
mutate,
unload,
fallback: {}
}, preset);
var mergeConfigs = (a, b) => {
const v = mergeObjects(a, b);
if (b) {
const { use: u1, fallback: f1, cacheData: c1 } = a;
const { use: u2, fallback: f2, cacheData: c2 } = b;
if (u1 && u2) v.use = u1.concat(u2);
if (f1 && f2) v.fallback = mergeObjects(f1, f2);
if (c1 && c2) v.cacheData = mergeObjects(c1, c2);
}
return v;
};
var SWRConfigContext = (0, import_react.createContext)({});
var SWRConfig$1 = (props) => {
const { value } = props;
const parentConfig = (0, import_react.useContext)(SWRConfigContext);
const isFunctionalConfig = isFunction(value);
const config = (0, import_react.useMemo)(() => isFunctionalConfig ? value(parentConfig) : value, [
isFunctionalConfig,
parentConfig,
value
]);
const extendedConfig = (0, import_react.useMemo)(() => isFunctionalConfig ? config : mergeConfigs(parentConfig, config), [
isFunctionalConfig,
parentConfig,
config
]);
const provider = config && config.provider;
const cacheContextRef = (0, import_react.useRef)(void 0);
if (provider && !cacheContextRef.current) cacheContextRef.current = initCache(provider(extendedConfig.cache || cache), config);
const cacheContext = cacheContextRef.current;
if (cacheContext) {
extendedConfig.cache = cacheContext[0];
extendedConfig.mutate = cacheContext[1];
extendedConfig.unload = cacheContext[4];
}
useIsomorphicLayoutEffect(() => {
if (cacheContext) {
cacheContext[2] && cacheContext[2]();
return cacheContext[3];
}
}, []);
return (0, import_react.createElement)(SWRConfigContext.Provider, mergeObjects(props, { value: extendedConfig }));
};
//#endregion
//#region node_modules/swr/dist/_internal/index.mjs
var enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
var use$1 = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
var setupDevTools = () => {
if (enableDevtools) window.__SWR_DEVTOOLS_REACT__ = import_react.default;
};
var normalize = (args) => {
return isFunction(args[1]) ? [
args[0],
args[1],
args[2] || {}
] : [
args[0],
null,
(args[1] === null ? args[2] : args[1]) || {}
];
};
var useSWRConfig = () => {
const parentConfig = (0, import_react.useContext)(SWRConfigContext);
return (0, import_react.useMemo)(() => mergeObjects(defaultConfig, parentConfig), [parentConfig]);
};
var preload = (key_, fetcher) => {
if (IS_SERVER) return;
const [key, fnArg] = serialize(key_);
const [, , , PRELOAD] = SWRGlobalState.get(cache);
if (PRELOAD[key]) return PRELOAD[key];
const req = fetcher(fnArg);
PRELOAD[key] = req;
return req;
};
var middleware = (useSWRNext) => (key_, fetcher_, config) => {
return useSWRNext(key_, fetcher_ && ((...args) => {
const [key] = serialize(key_);
const [, , , PRELOAD] = SWRGlobalState.get(cache);
if (key.startsWith("$inf$")) return fetcher_(...args);
const req = PRELOAD[key];
if (isUndefined(req)) return fetcher_(...args);
delete PRELOAD[key];
return req;
}), config);
};
var BUILT_IN_MIDDLEWARE = use$1.concat(middleware);
var withArgs = (hook) => {
return function useSWRArgs(...args) {
const fallbackConfig = useSWRConfig();
const [key, fn, _config] = normalize(args);
const config = mergeConfigs(fallbackConfig, _config);
let next = hook;
const { use } = config;
const middleware = (use || []).concat(BUILT_IN_MIDDLEWARE);
for (let i = middleware.length; i--;) next = middleware[i](next);
return next(key, fn || config.fetcher || null, config);
};
};
var subscribeCallback = (key, callbacks, callback) => {
const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
keyedRevalidators.push(callback);
return () => {
const index = keyedRevalidators.indexOf(callback);
if (index >= 0) {
keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
keyedRevalidators.pop();
}
};
};
setupDevTools();
//#endregion
//#region node_modules/swr/dist/use-swr-emll9s78.mjs
var use = import_react.use || ((thenable) => {
switch (thenable.status) {
case "pending": throw thenable;
case "fulfilled": return thenable.value;
case "rejected": throw thenable.reason;
default:
thenable.status = "pending";
thenable.then((v) => {
thenable.status = "fulfilled";
thenable.value = v;
}, (e) => {
thenable.status = "rejected";
thenable.reason = e;
});
throw thenable;
}
});
var WITH_DEDUPE = { dedupe: true };
var isCacheDataConsumed = (consumedCacheData, cacheData, key) => {
var _consumedCacheData_get;
return cacheData ? ((_consumedCacheData_get = consumedCacheData.get(cacheData)) == null ? void 0 : _consumedCacheData_get.has(key)) === true : false;
};
var markCacheDataConsumed = (consumedCacheData, cacheData, key) => {
if (!cacheData) return;
let consumedKeys = consumedCacheData.get(cacheData);
if (!consumedKeys) {
consumedKeys = /* @__PURE__ */ new Set();
consumedCacheData.set(cacheData, consumedKeys);
}
consumedKeys.add(key);
};
var commitCacheData = ({ value, getCacheData, canCommit, setCache }) => {
const commit = (state) => {
if (canCommit() && isUndefined(getCacheData())) setCache(state);
};
Promise.resolve(value).then((data) => {
commit({
data,
error: void 0
});
}, (error) => {
commit({ error });
});
};
var resolvedUndef = Promise.resolve(void 0);
resolvedUndef.status = "fulfilled";
resolvedUndef.value = void 0;
var sub = () => noop;
/**
* The core implementation of the useSWR hook.
*
* This is the main handler function that implements all SWR functionality including
* data fetching, caching, revalidation, error handling, and state management.
* It manages the complete lifecycle of SWR requests from initialization through
* cleanup.
*
* Key responsibilities:
* - Key serialization and normalization
* - Cache state management and synchronization
* - Automatic and manual revalidation
* - Error handling and retry logic
* - Suspense integration
* - Loading state management
* - Effect cleanup and memory management
*
* @template Data - The type of data returned by the fetcher
* @template Error - The type of error that can be thrown
*
* @param _key - The SWR key (string, array, object, function, or falsy)
* @param fetcher - The fetcher function to retrieve data, or null to disable fetching
* @param config - Complete SWR configuration object with both public and internal options
*
* @returns SWRResponse object containing data, error, mutate function, and loading states
*
* @internal This is the internal implementation. Use `useSWR` instead.
*/ var useSWRHandler = (_key, fetcher, config) => {
const { cache, compare, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData, strictServerPrefetchWarning } = config;
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache);
const [key, fnArg] = serialize(_key);
const initialMountedRef = (0, import_react.useRef)(false);
const unmountedRef = (0, import_react.useRef)(false);
const keyRef = (0, import_react.useRef)(key);
const fetcherRef = (0, import_react.useRef)(fetcher);
const configRef = (0, import_react.useRef)(config);
const getConfig = () => configRef.current;
const isActive = () => getConfig().isVisible() && getConfig().isOnline();
const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache, key);
const stateDependencies = (0, import_react.useRef)({}).current;
const fallback = isUndefined(fallbackData) ? isUndefined(config.fallback) ? void 0 : config.fallback[key] : fallbackData;
const serverCacheData = config.cacheData;
const configCacheData = !key ? void 0 : serverCacheData == null ? void 0 : serverCacheData[key];
const req = key ? PRELOAD[key] : void 0;
const hasCacheData = isUndefined(req) && !isUndefined(configCacheData);
const preloadedData = hasCacheData ? configCacheData : req;
const isEqual = (prev, current) => {
for (const _ in stateDependencies) {
const t = _;
if (t === "data") {
if (!compare(prev[t], current[t])) {
if (!isUndefined(prev[t])) return false;
if (!compare(returnedData, current[t])) return false;
}
} else if (current[t] !== prev[t]) return false;
}
return true;
};
const isInitialMount = !initialMountedRef.current;
const getSnapshot = (0, import_react.useMemo)(() => {
const cachedData = getCache();
const initialData = getInitialCache();
const getSelectedCache = (state) => {
const snapshot = mergeObjects(state);
delete snapshot._k;
if (!(() => {
if (!key) return false;
if (!fetcher) return false;
if (getConfig().isPaused()) return false;
if (isInitialMount && !isUndefined(revalidateOnMount)) return revalidateOnMount;
const data = !isUndefined(fallback) ? fallback : snapshot.data;
if (suspense && hasCacheData && isUndefined(data)) return false;
if (suspense) return isUndefined(data) || revalidateIfStale;
return isUndefined(data) || revalidateIfStale;
})()) return snapshot;
return {
isValidating: true,
isLoading: true,
...snapshot
};
};
const clientSnapshot = getSelectedCache(cachedData);
const serverSnapshot = cachedData === initialData ? clientSnapshot : getSelectedCache(initialData);
let memorizedSnapshot = clientSnapshot;
return [() => {
const newSnapshot = getSelectedCache(getCache());
if (isEqual(newSnapshot, memorizedSnapshot)) {
memorizedSnapshot.data = newSnapshot.data;
memorizedSnapshot.isLoading = newSnapshot.isLoading;
memorizedSnapshot.isValidating = newSnapshot.isValidating;
memorizedSnapshot.error = newSnapshot.error;
return memorizedSnapshot;
} else {
memorizedSnapshot = newSnapshot;
return newSnapshot;
}
}, () => serverSnapshot];
}, [cache, key]);
const cached = (0, import_shim.useSyncExternalStore)((0, import_react.useCallback)((callback) => subscribeCache(key, (current, prev) => {
if (!isEqual(prev, current)) callback();
}), [cache, key]), getSnapshot[0], getSnapshot[1]);
const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
const cachedData = cached.data;
let data = isUndefined(cachedData) ? fallback && isPromiseLike(fallback) ? use(fallback) : fallback : cachedData;
const error = cached.error;
const laggyDataRef = (0, import_react.useRef)(data);
const consumedCacheDataRef = (0, import_react.useRef)(void 0);
let consumedCacheData = consumedCacheDataRef.current;
if (!consumedCacheData) {
consumedCacheData = /* @__PURE__ */ new WeakMap();
consumedCacheDataRef.current = consumedCacheData;
}
const preloadCacheRef = (0, import_react.useRef)(null);
let returnedData = keepPreviousData ? isUndefined(cachedData) ? isUndefined(laggyDataRef.current) ? data : laggyDataRef.current : cachedData : data;
const hasKeyButNoData = key && isUndefined(data);
const hydrationRef = (0, import_react.useRef)(null);
!IS_SERVER && (0, import_shim.useSyncExternalStore)(sub, () => {
hydrationRef.current = false;
return hydrationRef;
}, () => {
hydrationRef.current = true;
return hydrationRef;
});
const isHydration = hydrationRef.current;
if (strictServerPrefetchWarning && isHydration && !suspense && hasKeyButNoData) console.warn(`Missing pre-initiated data for serialized key "${key}" during server-side rendering. Data fetching should be initiated on the server and provided to SWR via fallback data. You can set "strictServerPrefetchWarning: false" to disable this warning.`);
const shouldDoInitialRevalidation = (() => {
if (!key || !fetcher) return false;
if (getConfig().isPaused()) return false;
if (hasRevalidator && !isUndefined(error)) return false;
if (isInitialMount && !isUndefined(revalidateOnMount)) return revalidateOnMount;
if (suspense && hasCacheData && hasKeyButNoData) return false;
if (suspense) return isUndefined(data) ? false : revalidateIfStale;
return isUndefined(data) || revalidateIfStale;
})();
const defaultValidatingState = isInitialMount && shouldDoInitialRevalidation;
const isValidating = isUndefined(cached.isValidating) ? defaultValidatingState : cached.isValidating;
const isLoading = isUndefined(cached.isLoading) ? defaultValidatingState : cached.isLoading;
const revalidate = (0, import_react.useCallback)(async (revalidateOpts) => {
const currentFetcher = fetcherRef.current;
if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) return false;
let newData;
let startAt;
let loading = true;
const opts = revalidateOpts || {};
const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
const shouldUseRSCPreload = hasCacheData && !isCacheDataConsumed(consumedCacheData, serverCacheData, key) && !isUndefined(preloadedData) && isUndefined(getCache().data);
const callbackSafeguard = () => {
if (IS_REACT_LEGACY) return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
return key === keyRef.current;
};
const finalState = {
isValidating: false,
isLoading: false
};
const finishRequestAndUpdateState = () => {
setCache(finalState);
};
const cleanupState = () => {
const requestInfo = FETCH[key];
if (requestInfo && requestInfo[1] === startAt) delete FETCH[key];
};
const initialState = { isValidating: true };
if (isUndefined(getCache().data)) initialState.isLoading = true;
try {
if (shouldStartNewRequest) {
setCache(initialState);
if (config.loadingTimeout && isUndefined(getCache().data)) setTimeout(() => {
if (loading && callbackSafeguard()) getConfig().onLoadingSlow(key, config);
}, config.loadingTimeout);
if (shouldUseRSCPreload) markCacheDataConsumed(consumedCacheData, serverCacheData, key);
FETCH[key] = [shouldUseRSCPreload ? preloadedData : currentFetcher(fnArg), getTimestamp()];
if (shouldUseRSCPreload && PRELOAD[key]) delete PRELOAD[key];
}
[newData, startAt] = FETCH[key];
newData = await newData;
if (shouldStartNewRequest) setTimeout(cleanupState, config.dedupingInterval);
if (!FETCH[key] || FETCH[key][1] !== startAt) {
if (shouldStartNewRequest) {
if (callbackSafeguard()) getConfig().onDiscarded(key);
}
return false;
}
finalState.error = void 0;
const mutationInfo = MUTATION[key];
if (!isUndefined(mutationInfo) && (startAt <= mutationInfo[0] || startAt <= mutationInfo[1] || mutationInfo[1] === 0)) {
finishRequestAndUpdateState();
if (shouldStartNewRequest) {
if (callbackSafeguard()) getConfig().onDiscarded(key);
}
return false;
}
const cacheData = getCache().data;
finalState.data = compare(cacheData, newData) ? cacheData : newData;
if (shouldStartNewRequest) {
if (callbackSafeguard()) getConfig().onSuccess(newData, key, config);
}
} catch (err) {
cleanupState();
const currentConfig = getConfig();
const { shouldRetryOnError } = currentConfig;
if (!currentConfig.isPaused()) {
finalState.error = err;
if (shouldStartNewRequest && callbackSafeguard()) {
currentConfig.onError(err, key, currentConfig);
if (shouldRetryOnError === true || isFunction(shouldRetryOnError) && shouldRetryOnError(err)) {
if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => {
const revalidators = EVENT_REVALIDATORS[key];
if (revalidators && revalidators[0]) revalidators[0](3, _opts);
}, {
retryCount: (opts.retryCount || 0) + 1,
dedupe: true
});
}
}
}
}
loading = false;
finishRequestAndUpdateState();
return true;
}, [key, cache]);
const boundMutate = (0, import_react.useCallback)((...args) => {
return internalMutate(cache, keyRef.current, ...args);
}, []);
useIsomorphicLayoutEffect(() => {
const preloaded = preloadCacheRef.current;
if (!preloaded) return;
preloadCacheRef.current = null;
markCacheDataConsumed(consumedCacheData, preloaded.cacheData, preloaded.key);
if (isUndefined(getCache().data)) setCache({
data: preloaded.data,
error: void 0,
_k: preloaded._k
});
if (PRELOAD[preloaded.key]) delete PRELOAD[preloaded.key];
});
useIsomorphicLayoutEffect(() => {
fetcherRef.current = fetcher;
configRef.current = config;
if (!isUndefined(cachedData)) laggyDataRef.current = cachedData;
});
useIsomorphicLayoutEffect(() => {
if (fetcher || !hasCacheData || isUndefined(preloadedData) || isCacheDataConsumed(consumedCacheData, serverCacheData, key) || !isUndefined(getCache().data)) return;
markCacheDataConsumed(consumedCacheData, serverCacheData, key);
const mutation = MUTATION[key];
commitCacheData({
value: preloadedData,
getCacheData: () => getCache().data,
canCommit: () => !unmountedRef.current && key === keyRef.current && MUTATION[key] === mutation,
setCache: (state) => setCache({
...state,
_k: fnArg
})
});
});
useIsomorphicLayoutEffect(() => {
if (!key) return;
const softRevalidate = revalidate.bind(void 0, WITH_DEDUPE);
let nextFocusRevalidatedAt = 0;
if (getConfig().revalidateOnFocus) nextFocusRevalidatedAt = Date.now() + getConfig().focusThrottleInterval;
const onRevalidate = (type, opts = {}) => {
if (type == 0) {
const now = Date.now();
if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) {
nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval;
softRevalidate();
}
} else if (type == 1) {
if (getConfig().revalidateOnReconnect && isActive()) softRevalidate();
} else if (type == 2) return revalidate();
else if (type == 3) return revalidate(opts);
else if (type == 4) {
laggyDataRef.current = void 0;
if (opts.revalidate) return revalidate();
}
};
const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
unmountedRef.current = false;
keyRef.current = key;
initialMountedRef.current = true;
setCache({ _k: fnArg });
if (shouldDoInitialRevalidation) {
if (!FETCH[key]) {
if (isUndefined(data) || IS_SERVER) softRevalidate();
else rAF(softRevalidate);
}
}
return () => {
unmountedRef.current = true;
unsubEvents();
};
}, [key]);
useIsomorphicLayoutEffect(() => {
let timer;
function next() {
const interval = isFunction(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
if (interval && timer !== -1) timer = setTimeout(execute, interval);
}
function execute() {
if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) revalidate(WITH_DEDUPE).then(next);
else next();
}
next();
return () => {
if (timer) {
clearTimeout(timer);
timer = -1;
}
};
}, [
refreshInterval,
refreshWhenHidden,
refreshWhenOffline,
key
]);
(0, import_react.useDebugValue)(returnedData);
if (suspense) {
if (!IS_REACT_LEGACY && IS_SERVER && hasKeyButNoData && isUndefined(preloadedData)) throw new Error("Fallback data is required when using Suspense in SSR.");
if (hasKeyButNoData) {
fetcherRef.current = fetcher;
configRef.current = config;
unmountedRef.current = false;
}
const shouldConsumePreload = !isUndefined(preloadedData) && hasKeyButNoData;
let preloadData = void 0;
if (shouldConsumePreload && hasCacheData) {
preloadData = preloadedData && isPromiseLike(preloadedData) ? use(preloadedData) : preloadedData;
data = preloadData;
returnedData = preloadData;
if (!IS_SERVER) preloadCacheRef.current = {
data: preloadData,
_k: fnArg,
key,
cacheData: serverCacheData
};
} else use(shouldConsumePreload ? boundMutate(preloadedData) : resolvedUndef);
if (!isUndefined(error) && hasKeyButNoData) throw error;
const revalidation = hasKeyButNoData && isUndefined(preloadData) ? revalidate(WITH_DEDUPE) : resolvedUndef;
if (!isUndefined(returnedData) && hasKeyButNoData) {
revalidation.status = "fulfilled";
revalidation.value = true;
}
use(revalidation);
}
return {
mutate: boundMutate,
get data() {
stateDependencies.data = true;
return returnedData;
},
get error() {
stateDependencies.error = true;
return error;
},
get isValidating() {
stateDependencies.isValidating = true;
return isValidating;
},
get isLoading() {
stateDependencies.isLoading = true;
return isLoading;
}
};
};
var SWRConfig = OBJECT.defineProperty(SWRConfig$1, "defaultValue", { value: defaultConfig });
/**
* A hook to fetch data.
*
* @see {@link https://swr.vercel.app}
*
* @example
* ```jsx
* import useSWR from 'swr'
* function Profile() {
* const { data, error, isLoading } = useSWR('/api/user', fetcher)
* if (error) return <div>failed to load</div>
* if (isLoading) return <div>loading...</div>
* return <div>hello {data.name}!</div>
* }
* ```
*/ var useSWR = withArgs(useSWRHandler);
//#endregion
//#region node_modules/swr/dist/index/index.mjs
var unstable_serialize = (key) => serialize(key)[0];
//#endregion
export { SWRConfig, useSWR as default, mutate, preload, unload, unstable_serialize, useSWRConfig };
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"swr.js","names":["useEffect","useLayoutEffect","createContext","SWRConfig","useContext","useMemo","useRef","createElement","use","React","useContext","useMemo","useRef","useMemo","useSyncExternalStore","useCallback"],"sources":["../../dequal/lite/index.mjs","../../swr/dist/config-context-ext53wcz.mjs","../../swr/dist/_internal/constants.mjs","../../swr/dist/_internal/index.mjs","../../swr/dist/use-swr-emll9s78.mjs","../../swr/dist/index/index.mjs"],"sourcesContent":["var has = Object.prototype.hasOwnProperty;\n\nexport function dequal(foo, bar) {\n\tvar ctor, len;\n\tif (foo === bar) return true;\n\n\tif (foo && bar && (ctor=foo.constructor) === bar.constructor) {\n\t\tif (ctor === Date) return foo.getTime() === bar.getTime();\n\t\tif (ctor === RegExp) return foo.toString() === bar.toString();\n\n\t\tif (ctor === Array) {\n\t\t\tif ((len=foo.length) === bar.length) {\n\t\t\t\twhile (len-- && dequal(foo[len], bar[len]));\n\t\t\t}\n\t\t\treturn len === -1;\n\t\t}\n\n\t\tif (!ctor || typeof foo === 'object') {\n\t\t\tlen = 0;\n\t\t\tfor (ctor in foo) {\n\t\t\t\tif (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;\n\t\t\t\tif (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;\n\t\t\t}\n\t\t\treturn Object.keys(bar).length === len;\n\t\t}\n\t}\n\n\treturn foo !== foo && bar !== bar;\n}\n","'use client';\nimport React, { useEffect, useLayoutEffect, createContext, useContext, useMemo, useRef, createElement } from 'react';\nimport { dequal } from 'dequal/lite';\n\nconst FOCUS_EVENT = 0;\nconst RECONNECT_EVENT = 1;\nconst MUTATE_EVENT = 2;\nconst ERROR_REVALIDATE_EVENT = 3;\nconst UNLOAD_EVENT = 4;\n\nvar events = {\n __proto__: null,\n ERROR_REVALIDATE_EVENT: ERROR_REVALIDATE_EVENT,\n FOCUS_EVENT: FOCUS_EVENT,\n MUTATE_EVENT: MUTATE_EVENT,\n RECONNECT_EVENT: RECONNECT_EVENT,\n UNLOAD_EVENT: UNLOAD_EVENT\n};\n\n// Global state used to deduplicate requests and store listeners\nconst SWRGlobalState = new WeakMap();\n\n// Shared state between server components and client components\nconst noop = ()=>{};\n// Using noop() as the undefined value as undefined can be replaced\n// by something else. Prettier ignore and extra parentheses are necessary here\n// to ensure that tsc doesn't remove the __NOINLINE__ comment.\n// prettier-ignore\nconst UNDEFINED = /*#__NOINLINE__*/ noop();\nconst OBJECT = Object;\nconst isUndefined = (v)=>v === UNDEFINED;\nconst isFunction = (v)=>typeof v == 'function';\nconst mergeObjects = (a, b)=>({\n ...a,\n ...b\n });\nconst isPromiseLike = (x)=>isFunction(x.then);\n\nconst EMPTY_CACHE = {};\nconst INITIAL_CACHE = {};\nconst STR_UNDEFINED = 'undefined';\n// NOTE: Use the function to guarantee it's re-evaluated between jsdom and node runtime for tests.\nconst isWindowDefined = typeof window != STR_UNDEFINED;\nconst isDocumentDefined = typeof document != STR_UNDEFINED;\nconst isLegacyDeno = isWindowDefined && 'Deno' in window;\nconst hasRequestAnimationFrame = ()=>isWindowDefined && typeof window['requestAnimationFrame'] != STR_UNDEFINED;\nconst createCacheHelper = (cache, key)=>{\n const state = SWRGlobalState.get(cache);\n return [\n // Getter\n ()=>!isUndefined(key) && cache.get(key) || EMPTY_CACHE,\n // Setter\n (info)=>{\n if (!isUndefined(key)) {\n const prev = cache.get(key);\n // Before writing to the store, we keep the value in the initial cache\n // if it's not there yet.\n if (!(key in INITIAL_CACHE)) {\n INITIAL_CACHE[key] = prev;\n }\n state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);\n }\n },\n // Subscriber\n state[6],\n // Get server cache snapshot\n ()=>{\n if (!isUndefined(key)) {\n // If the cache was updated on the client, we return the stored initial value.\n if (key in INITIAL_CACHE) return INITIAL_CACHE[key];\n }\n // If we haven't done any client-side updates, we return the current value.\n return !isUndefined(key) && cache.get(key) || EMPTY_CACHE;\n }\n ];\n} // export { UNDEFINED, OBJECT, isUndefined, isFunction, mergeObjects, isPromiseLike }\n;\n\n/**\n * Due to the bug https://bugs.chromium.org/p/chromium/issues/detail?id=678075,\n * it's not reliable to detect if the browser is currently online or offline\n * based on `navigator.onLine`.\n * As a workaround, we always assume it's online on the first load, and change\n * the status upon `online` or `offline` events.\n */ let online = true;\nconst isOnline = ()=>online;\n// For node and React Native, `add/removeEventListener` doesn't exist on window.\nconst [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [\n window.addEventListener.bind(window),\n window.removeEventListener.bind(window)\n] : [\n noop,\n noop\n];Line truncated
+259
View File
@@ -0,0 +1,259 @@
import { r as __toESM } from "./rolldown-runtime-DC62tzP2.js";
import { t as require_react } from "./react.js";
import { t as require_shim } from "./shim-BX6a9SD7.js";
//#region node_modules/regexparam/dist/index.mjs
/**
* @param {string|RegExp} input The route pattern
* @param {boolean} [loose] Allow open-ended matching. Ignored with `RegExp` input.
*/
function parse(input, loose) {
if (input instanceof RegExp) return {
keys: false,
pattern: input
};
var c, o, tmp, ext, keys = [], pattern = "", arr = input.split("/");
arr[0] || arr.shift();
while (tmp = arr.shift()) {
c = tmp[0];
if (c === "*") {
keys.push(c);
pattern += tmp[1] === "?" ? "(?:/(.*))?" : "/(.*)";
} else if (c === ":") {
o = tmp.indexOf("?", 1);
ext = tmp.indexOf(".", 1);
keys.push(tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length));
pattern += !!~o && !~ext ? "(?:/([^/]+?))?" : "/([^/]+?)";
if (!!~ext) pattern += (!!~o ? "?" : "") + "\\" + tmp.substring(ext);
} else pattern += "/" + tmp;
}
return {
keys,
pattern: new RegExp("^" + pattern + (loose ? "(?=$|/)" : "/?$"), "i")
};
}
//#endregion
//#region node_modules/wouter/src/use-sync-external-store.js
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
var import_shim = require_shim();
//#endregion
//#region node_modules/wouter/src/react-deps.js
var useBuiltinInsertionEffect = import_react.useInsertionEffect;
var useIsomorphicLayoutEffect = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined") ? import_react.useLayoutEffect : import_react.useEffect;
var useInsertionEffect = useBuiltinInsertionEffect || useIsomorphicLayoutEffect;
var useEvent = (fn) => {
const ref = import_react.useRef([fn, (...args) => ref[0](...args)]).current;
useInsertionEffect(() => {
ref[0] = fn;
});
return ref[1];
};
//#endregion
//#region node_modules/wouter/src/use-browser-location.js
/**
* History API docs @see https://developer.mozilla.org/en-US/docs/Web/API/History
*/
var events = [
"popstate",
"pushState",
"replaceState",
"hashchange"
];
var listeners = [];
var onLocationChange = () => listeners.forEach((callback) => callback());
var subscribeToLocationUpdates = (callback) => {
if (listeners.push(callback) === 1) events.forEach((event) => addEventListener(event, onLocationChange));
return () => {
listeners = listeners.filter((listener) => listener !== callback);
if (!listeners.length) events.forEach((event) => removeEventListener(event, onLocationChange));
};
};
var useLocationProperty = (fn, ssrFn) => (0, import_shim.useSyncExternalStore)(subscribeToLocationUpdates, fn, ssrFn);
var currentSearch = () => location.search;
var useSearch$1 = ({ ssrSearch } = {}) => useLocationProperty(currentSearch, ssrSearch != null ? () => ssrSearch : currentSearch);
var currentPathname = () => location.pathname;
var usePathname = ({ ssrPath } = {}) => useLocationProperty(currentPathname, ssrPath != null ? () => ssrPath : currentPathname);
var navigate = (to, { replace = false, state = null } = {}) => history[replace ? "replaceState" : "pushState"](state, "", to);
var useBrowserLocation = (opts) => [usePathname(opts), navigate];
var patchKey = Symbol.for("wouter_v3");
if (typeof history !== "undefined" && typeof window[patchKey] === "undefined") {
for (const type of ["pushState", "replaceState"]) {
const original = history[type];
history[type] = function() {
const result = original.apply(this, arguments);
const event = new Event(type);
event.arguments = arguments;
dispatchEvent(event);
return result;
};
}
Object.defineProperty(window, patchKey, { value: true });
}
//#endregion
//#region node_modules/wouter/src/paths.js
/**
* When basepath is `undefined` or '/' it is ignored (we assume it's empty string)
*/
var baseDefaults = (base = "") => base === "/" ? "" : base;
var absolutePath = (to, base) => to[0] === "~" ? to.slice(1) : baseDefaults(base) + to;
var relativePath = (base, path) => {
base = unescape(baseDefaults(base));
path = unescape(path);
return !base || !path.toLowerCase().indexOf(base.toLowerCase()) ? path.slice(base.length) || "/" : "~" + path;
};
var unescape = (str) => {
try {
return str.includes("%") ? decodeURI(str) : str;
} catch (_e) {
return str;
}
};
var sanitizeSearch = (search) => unescape(search[0] === "?" ? search.slice(1) : search);
//#endregion
//#region node_modules/wouter/src/index.js
var defaultRouter = {
hook: useBrowserLocation,
searchHook: useSearch$1,
parser: parse,
base: "",
ssrPath: void 0,
ssrSearch: void 0,
ssrContext: void 0,
hrefs: (x) => x,
aroundNav: (n, t, o) => n(t, o)
};
var RouterCtx = (0, import_react.createContext)(defaultRouter);
var useRouter = () => (0, import_react.useContext)(RouterCtx);
/**
* Parameters context. Used by `useParams()` to get the
* matched params from the innermost `Route` component.
*/
var Params0 = {};
var ParamsCtx = (0, import_react.createContext)(Params0);
var useParams = () => (0, import_react.useContext)(ParamsCtx);
var usePathnameFromRouter = (router, base = router.base) => relativePath(base, router.hook(router)[0]);
var useLocationFromRouter = (router) => {
const [location, navigate] = router.hook(router);
return [relativePath(router.base, location), useEvent((to, opts) => router.aroundNav(navigate, absolutePath(to, router.base), opts))];
};
var useLocation = () => useLocationFromRouter(useRouter());
var useSearch = () => {
const router = useRouter();
return sanitizeSearch(router.searchHook(router));
};
var matchRoute = (parser, route, path, loose) => {
const { pattern, keys } = route instanceof RegExp ? { pattern: route } : parser(route || "*", loose);
const result = pattern.exec(path);
if (!result) return [false, null];
const params = {};
for (let i = 1; i < result.length; i++) params[i - 1] = result[i];
if (keys) for (let i = 0; i < keys.length; i++) params[keys[i]] = result[i + 1];
else Object.assign(params, result.groups);
return loose ? [
true,
params,
result[0]
] : [true, params];
};
var useRoute = (pattern) => {
const router = useRouter();
const absolute = /^~\//.test(pattern);
return matchRoute(router.parser, absolute ? pattern.slice(1) : pattern, usePathnameFromRouter(router, absolute ? "" : router.base));
};
var Router = ({ children, ...props }) => {
const parent_ = useRouter();
const parent = props.hook ? defaultRouter : parent_;
let value = parent;
if (props.ssrPath) {
const [path, search = props.ssrSearch ?? ""] = props.ssrPath.split("?");
if (path) props.ssrSearch = search, props.ssrPath = path;
}
props.hrefs = props.hrefs ?? props.hook?.hrefs;
props.searchHook = props.searchHook ?? props.hook?.searchHook;
let ref = (0, import_react.useRef)(parent), prev = ref.current, next = prev;
for (let k in parent) {
const option = k === "base" ? parent[k] + (props[k] ?? "") : props[k] ?? parent[k];
if (option !== next[k]) {
if (prev === next) ref.current = next = { ...next };
next[k] = option;
}
if (option !== parent[k] || option !== value[k]) value = next;
}
return (0, import_react.createElement)(RouterCtx.Provider, { value }, children);
};
var h_route = ({ children, component }, params) => {
if (component) return (0, import_react.createElement)(component, { params });
return typeof children === "function" ? children(params) : children;
};
var useCachedParams = (value) => {
let prev = (0, import_react.useRef)(Params0);
const curr = prev.current, keys = Object.keys(value);
return prev.current = keys.length !== Object.keys(curr).length || keys.some((k) => value[k] !== curr[k]) ? value : curr;
};
function useSearchParams() {
const [location, navigate] = useLocation();
const search = useSearch();
const searchParams = (0, import_react.useMemo)(() => new URLSearchParams(search), [search]);
let tempSearchParams = searchParams;
return [searchParams, useEvent((nextInit, options) => {
tempSearchParams = new URLSearchParams(typeof nextInit === "function" ? nextInit(tempSearchParams) : nextInit);
const paramsStr = tempSearchParams.toString();
navigate(location + (paramsStr ? "?" + paramsStr : ""), options);
})];
}
var Route = ({ path, nest, match, ...renderProps }) => {
const router = useRouter();
const location = usePathnameFromRouter(router);
const [matches, routeParams, base] = match ?? matchRoute(router.parser, path, location, nest);
const params = useCachedParams({
...useParams(),
...routeParams
});
if (!matches) return null;
const children = h_route(renderProps, params);
return (0, import_react.createElement)(ParamsCtx.Provider, { value: params }, base ? (0, import_react.createElement)(Router, { base }, children) : children);
};
var Link = (0, import_react.forwardRef)((props, ref) => {
const router = useRouter();
const [currentPath, navigate] = useLocationFromRouter(router);
const { to = "", href: targetPath = to, onClick: _onClick, asChild, children, className: cls, replace, state, transition, ...linkProps } = props;
linkProps.onClick = useEvent((event) => {
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey || event.button !== 0) return;
_onClick?.(event);
if (!event.defaultPrevented) {
event.preventDefault();
navigate(targetPath, props);
}
});
linkProps.href = router.hrefs(targetPath[0] === "~" ? targetPath.slice(1) : router.base + targetPath, router);
if (cls !== void 0) linkProps.className = cls?.call ? cls(currentPath === targetPath) : cls;
if (ref) linkProps.ref = ref;
return asChild && (0, import_react.isValidElement)(children) ? (0, import_react.cloneElement)(children, linkProps) : (0, import_react.createElement)("a", linkProps, children);
});
var flattenChildren = (children, result = []) => {
if (Array.isArray(children)) for (const c of children) flattenChildren(c && c.type === import_react.Fragment ? c.props.children : c, result);
else result.push(children);
return result;
};
var Switch = ({ children, location }) => {
const router = useRouter();
const originalLocation = usePathnameFromRouter(router);
for (const element of flattenChildren(children)) {
let match = 0;
if ((0, import_react.isValidElement)(element) && (match = matchRoute(router.parser, element.props.path, location || originalLocation, element.props.nest))[0]) return (0, import_react.cloneElement)(element, { match });
}
return null;
};
var Redirect = (props) => {
const { to, href = to } = props;
const router = useRouter();
const [, navigate] = useLocationFromRouter(router);
const redirect = useEvent(() => navigate(to || href, props));
const { ssrContext } = router;
useIsomorphicLayoutEffect(() => {
redirect();
}, []);
if (ssrContext) ssrContext.redirectTo = to;
return null;
};
//#endregion
export { Link, Redirect, Route, Router, Switch, matchRoute, useLocation, useParams, useRoute, useRouter, useSearch, useSearchParams };
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"wouter.js","names":["\"useInsertion\" + \"Effect\"","useSyncExternalStore","useSearch","useBrowserSearch","parsePattern","createContext","useContext","useRef","h","useMemo","forwardRef","isValidElement","cloneElement","Fragment"],"sources":["../../regexparam/dist/index.mjs","../../wouter/src/use-sync-external-store.js","../../wouter/src/react-deps.js","../../wouter/src/use-browser-location.js","../../wouter/src/paths.js","../../wouter/src/index.js"],"sourcesContent":["/**\n * @param {string|RegExp} input The route pattern\n * @param {boolean} [loose] Allow open-ended matching. Ignored with `RegExp` input.\n */\nexport function parse(input, loose) {\n\tif (input instanceof RegExp) return { keys:false, pattern:input };\n\tvar c, o, tmp, ext, keys=[], pattern='', arr = input.split('/');\n\tarr[0] || arr.shift();\n\n\twhile (tmp = arr.shift()) {\n\t\tc = tmp[0];\n\t\tif (c === '*') {\n\t\t\tkeys.push(c);\n\t\t\tpattern += tmp[1] === '?' ? '(?:/(.*))?' : '/(.*)';\n\t\t} else if (c === ':') {\n\t\t\to = tmp.indexOf('?', 1);\n\t\t\text = tmp.indexOf('.', 1);\n\t\t\tkeys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );\n\t\t\tpattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';\n\t\t\tif (!!~ext) pattern += (!!~o ? '?' : '') + '\\\\' + tmp.substring(ext);\n\t\t} else {\n\t\t\tpattern += '/' + tmp;\n\t\t}\n\t}\n\n\treturn {\n\t\tkeys: keys,\n\t\tpattern: new RegExp('^' + pattern + (loose ? '(?=$|\\/)' : '\\/?$'), 'i')\n\t};\n}\n\nvar RGX = /(\\/|^)([:*][^/]*?)(\\?)?(?=[/.]|$)/g;\n\n// error if key missing?\nexport function inject(route, values) {\n\treturn route.replace(RGX, (x, lead, key, optional) => {\n\t\tx = values[key=='*' ? key : key.substring(1)];\n\t\treturn x ? '/'+x : (optional || key=='*') ? '' : '/' + key;\n\t});\n}\n","export { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\n","import * as React from \"react\";\n\n// React.useInsertionEffect is not available in React <18\n// This hack fixes a transpilation issue on some apps\nconst useBuiltinInsertionEffect = React[\"useInsertion\" + \"Effect\"];\n\nexport {\n useMemo,\n useRef,\n useState,\n useContext,\n createContext,\n isValidElement,\n cloneElement,\n createElement,\n Fragment,\n forwardRef,\n} from \"react\";\n\n// To resolve webpack 5 errors, while not presenting problems for native,\n// we copy the approaches from https://github.com/TanStack/query/pull/3561\n// and https://github.com/TanStack/query/pull/3601\n// ~ Show this aging PR some love to remove the need for this hack:\n// https://github.com/facebook/react/pull/25231 ~\nexport { useSyncExternalStore } from \"./use-sync-external-store.js\";\n\n// Copied from:\n// https://github.com/facebook/react/blob/main/packages/shared/ExecutionEnvironment.js\nconst canUseDOM = !!(\n typeof window !== \"undefined\" &&\n typeof window.document !== \"undefined\" &&\n typeof window.document.createElement !== \"undefined\"\n);\n\n// Copied from:\n// https://github.com/reduxjs/react-redux/blob/master/src/utils/useIsomorphicLayoutEffect.ts\n// \"React currently throws a warning when using useLayoutEffect on the server.\n// To get around it, we can conditionally useEffect on the server (no-op) and\n// useLayoutEffect in the browser.\"\nexport const useIsomorphicLayoutEffect = canUseDOM\n ? React.useLayoutEffect\n : React.useEffect;\n\n// useInsertionEffect is already a noop on the server.\n// See: https://github.com/facebook/react/blob/main/packages/react-server/src/ReactFizzHooks.js\nexport const useInsertionEffect =\n useBuiltinInsertionEffect || useIsomorphicLayoutEffect;\n\n// Userland polyfill while we wait for the forthcoming\n// https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md\n// Note: \"A high-fidelity polyfill for useEvent is not possible because\n// there is no lifecycle or Hook in React that we can use to switch\n// .current at the right timing.\"\n// So we will have to make do with this \"close enough\" approach for now.\nexport const useEvent = (fn) => {\n const ref = React.useRef([fn, (...args) => ref[0](...args)]).current;\n // Per Dan Abramov: useInsertionEffect executes marginally closer to the\n // correct timing for ref synchronization than useLayoutEffect on React 18.\n // See: https://github.com/facebook/react/pull/25881#issuecomment-1356244360\n useInsertionEffect(() => {\n ref[0] = fn;\n });\n return ref[1];\n};\n","import { useSyncExternalStore } from \"./react-deps.js\";\n\n/**\n * History API docs @see https://developer.mozilla.org/en-US/docs/Web/API/History\n */\nconst events = [\"popstate\", \"pushState\", \"replaceState\", \"hashchange\"];\n\nlet listeners = [];\nconst onLocationChange = () => listeners.forEach((callback) => callback());\n\n// Native events can run microtasks between listeners. Notify all subscribers\n// together so React can process parent and child updates in the same batch.\nconst subscribeToLocationUpdates = (callback) => {\n if (listeners.push(cLine truncated
@@ -0,0 +1 @@
{"version":"5.0.0","results":[[":tests/auth.test.tsx",{"duration":491.67805499999986,"failed":false}],[":tests/api.test.ts",{"duration":14.961915999999974,"failed":false}],[":tests/overlay.test.tsx",{"duration":728.093953,"failed":false}],[":tests/check-tokens.test.mjs",{"duration":998.8133460000001,"failed":false}],[":tests/routing.test.tsx",{"duration":1758.9155749999995,"failed":false}],[":tests/appState.test.tsx",{"duration":423.0312829999998,"failed":false}],[":tests/icon-registry.test.tsx",{"duration":75.86277799999993,"failed":false}],[":tests/useTimeout.test.tsx",{"duration":43.350607999999966,"failed":false}],[":tests/useItems.test.tsx",{"duration":415.8608149999998,"failed":false}],[":tests/itemsPage.test.tsx",{"duration":698.4244530000001,"failed":false}]]}
+10
View File
@@ -0,0 +1,10 @@
(The MIT License)
Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2022 Jean-Philippe Zolesio <holblin@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+146
View File
@@ -0,0 +1,146 @@
# @adobe/css-tools
> A modern CSS parser and stringifier with TypeScript support
[![npm version](https://badge.fury.io/js/%40adobe%2Fcss-tools.svg)](https://badge.fury.io/js/%40adobe%2Fcss-tools)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
Parse CSS into an Abstract Syntax Tree (AST) and convert it back to CSS with configurable formatting. Built with TypeScript for type safety and modern JavaScript features.
## Install
```bash
npm install @adobe/css-tools
```
## Usage
```js
import { parse, stringify } from '@adobe/css-tools'
// Parse CSS to AST
const ast = parse('body { font-size: 12px; }')
// Stringify AST back to CSS
const css = stringify(ast)
// => "body { font-size: 12px; }"
// Pretty print with custom indentation
const formatted = stringify(ast, { indent: ' ' })
// => "body {\n font-size: 12px;\n}"
// Minify output
const minified = stringify(ast, { compress: true })
// => "body{font-size:12px}"
```
## API
### `parse(code, options?)`
Parses CSS code and returns an Abstract Syntax Tree (AST).
**Parameters:**
- `code` (string) - The CSS code to parse
- `options` (object, optional) - Parsing options
- `silent` (boolean) - Silently fail on parse errors instead of throwing
- `source` (string) - File path for better error reporting
**Returns:** `CssStylesheetAST` - The parsed CSS as an AST
### `stringify(ast, options?)`
Converts a CSS AST back to CSS string with configurable formatting.
**Parameters:**
- `ast` (CssStylesheetAST) - The CSS AST to stringify
- `options` (object, optional) - Stringification options
- `indent` (string) - Indentation string (default: `' '`)
- `compress` (boolean) - Whether to compress/minify the output (default: `false`)
**Returns:** `string` - The formatted CSS string
## Features
- **Complete CSS Support**: All standard CSS features including selectors, properties, values, at-rules, and comments
- **TypeScript Support**: Full type definitions for all AST nodes and functions
- **Error Handling**: Configurable error handling with detailed position information
- **Formatting Options**: Pretty print, minify, or custom formatting
- **Performance Optimized**: Efficient parsing and stringification for large CSS files
- **Source Maps**: Track original source positions for debugging and tooling
### Supported CSS Features
- **Selectors**: Element, class, ID, attribute, pseudo-class, pseudo-element selectors
- **Properties**: All standard CSS properties and custom properties
- **Values**: Colors, lengths, percentages, functions, calc(), etc.
- **At-rules**: @media, @keyframes, @import, @charset, @namespace, @font-face, @page, @document, @supports, @container, @layer, @starting-style, @host, @custom-media
- **Comments**: Both /* */ and // comments
- **Whitespace**: Preserves formatting information
- **Vendor prefixes**: Supports vendor-prefixed at-rules and properties
- **Nested rules**: Media queries, supports, containers, etc.
- **Complex selectors**: Combinators, pseudo-selectors, attribute selectors
## Examples
### Error Handling
```js
import { parse } from '@adobe/css-tools'
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`
// Parse with silent error handling
const result = parse(malformedCss, { silent: true })
// Check for parsing errors
if (result.stylesheet.parsingErrors) {
console.log('Parsing errors:', result.stylesheet.parsingErrors.length)
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`)
})
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length)
```
### Source Tracking
```js
import { parse } from '@adobe/css-tools'
const css = 'body { color: red; }'
const ast = parse(css, { source: 'styles.css' })
// Position information is available
const rule = ast.stylesheet.rules[0]
console.log(rule.position?.source) // "styles.css"
console.log(rule.position?.start) // { line: 1, column: 1 }
console.log(rule.position?.end) // { line: 1, column: 20 }
```
For more examples, see the [Examples documentation](docs/EXAMPLES.md).
## Performance
The library is optimized for performance and can handle large CSS files efficiently. For benchmarking information, see the `benchmark/` directory in the source code.
## Documentation
- [API Reference](docs/API.md) - Complete API documentation
- [AST Structure](docs/AST.md) - Detailed AST node types and structure
- [Examples](docs/EXAMPLES.md) - Comprehensive usage examples
- [Changelog](docs/CHANGELOG.md) - Version history and changes
## Background
This is a fork of the npm `css` package, maintained by Adobe with modern improvements including TypeScript support, enhanced performance, and security updates. It provides a robust foundation for CSS tooling, preprocessing, and analysis.
## License
[MIT](LICENSE)
+2
View File
@@ -0,0 +1,2 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});class t extends Error{reason;filename;line;column;source;constructor(t,s,e,i,n){super(`${t}:${e}:${i}: ${s}`),this.reason=s,this.filename=t,this.line=e,this.column=i,this.source=n}}class s{start;end;source;constructor(t,s,e){this.start=t,this.end=s,this.source=e}}var e;exports.CssTypes=void 0,(e=exports.CssTypes||(exports.CssTypes={})).stylesheet="stylesheet",e.rule="rule",e.declaration="declaration",e.comment="comment",e.atRule="at-rule",e.container="container",e.charset="charset",e.counterStyle="counter-style",e.document="document",e.customMedia="custom-media",e.fontFace="font-face",e.fontFeatureValues="font-feature-values",e.host="host",e.import="import",e.keyframes="keyframes",e.keyframe="keyframe",e.layer="layer",e.media="media",e.namespace="namespace",e.page="page",e.pageMarginBox="page-margin-box",e.positionTry="position-try",e.property="property",e.scope="scope",e.startingStyle="starting-style",e.supports="supports",e.viewTransition="view-transition";const i=(t,s,e)=>{let i=e,n=1e4;do{const e=s.map(s=>t.indexOf(s,i));e.push(t.indexOf("\\",i));const r=e.filter(t=>-1!==t);if(0===r.length)return-1;const o=Math.min(...r);if("\\"!==t[o])return o;i=o+2,n--}while(n>0);throw new Error("Too many escaping")},n=(t,s,e)=>{let r=e,o=1e4;do{const e=s.map(s=>t.indexOf(s,r));e.push(t.indexOf("(",r)),e.push(t.indexOf('"',r)),e.push(t.indexOf("'",r)),e.push(t.indexOf("\\",r));const c=e.filter(t=>-1!==t);if(0===c.length)return-1;const p=Math.min(...c);switch(t[p]){case"\\":r=p+2;break;case"(":{const s=n(t,[")"],p+1);if(-1===s)return-1;r=s+1}break;case'"':{const s=i(t,['"'],p+1);if(-1===s)return-1;r=s+1}break;case"'":{const s=i(t,["'"],p+1);if(-1===s)return-1;r=s+1}break;default:return p}o--}while(o>0);throw new Error("Too many escaping")},r=/\/\*[^]*?(?:\*\/|$)/g;function o(t){return t?t.trim():""}function c(t,s){const e=t&&"string"==typeof t.type,i=e?t:s;for(const s in t){const e=t[s];Array.isArray(e)?e.forEach(t=>{c(t,i)}):e&&"object"==typeof e&&c(e,i)}return e&&Object.defineProperty(t,"parent",{configurable:!0,writable:!0,enumerable:!1,value:s||null}),t}class p{level=0;indentation=" ";compress=!1;constructor(t){"string"==typeof t?.indent&&(this.indentation=t?.indent),t?.compress&&(this.compress=!0)}emit(t,s){return t}indent(t){return this.level=this.level||1,t?(this.level+=t,""):Array(this.level).join(this.indentation)}visit(t){switch(t.type){case exports.CssTypes.stylesheet:return this.stylesheet(t);case exports.CssTypes.rule:return this.rule(t);case exports.CssTypes.declaration:return this.declaration(t);case exports.CssTypes.comment:return this.comment(t);case exports.CssTypes.container:return this.container(t);case exports.CssTypes.charset:return this.charset(t);case exports.CssTypes.counterStyle:return this.counterStyle(t);case exports.CssTypes.document:return this.document(t);case exports.CssTypes.customMedia:return this.customMedia(t);case exports.CssTypes.fontFace:return this.fontFace(t);case exports.CssTypes.fontFeatureValues:return this.fontFeatureValues(t);case exports.CssTypes.host:return this.host(t);case exports.CssTypes.import:return this.import(t);case exports.CssTypes.keyframes:return this.keyframes(t);case exports.CssTypes.keyframe:return this.keyframe(t);case exports.CssTypes.layer:return this.layer(t);case exports.CssTypes.media:return this.media(t);case exports.CssTypes.namespace:return this.namespace(t);case exports.CssTypes.page:return this.page(t);case exports.CssTypes.pageMarginBox:return this.pageMarginBox(t);case exports.CssTypes.positionTry:return this.positionTry(t);case exports.CssTypes.property:return this.property(t);case exports.CssTypes.scope:return this.scope(t);case exports.CssTypes.startingStyle:return this.startingStyle(t);case exports.CssTypes.supports:return this.supports(t);case exports.CssTypes.viewTransition:return this.viewTransition(t);case exports.CssTypes.atRule:return this.genericAtRule(t)}}mapVisit(t,s){let e="";s=s||"";for(let i=0,n=t.length;i<n;i++)e+=this.visit(t[i]),s&&i<n-1&&(e+=this.emit(s));return e}compile(t){return this.compress?t.stylesheet.rules.map(this.visit,this).join(""):this.stylesheet(t)}stylesheet(t){return this.mapVisit(t.stylesheet.rules,"\n\n")}comment(t){return this.compress?this.emit("",t.position):this.emit(`${this.indent()}/*${t.comment}*/`,t.position)}container(t){return this.compress?this.emit(`@container ${t.container}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@container ${t.container}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}layer(t){return this.compress?this.emit(`@layer ${t.layer}`,t.position)+(t.rules?this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):";"):this.emit(`${this.indent()}@layer ${t.layer}`,t.position)+(t.rules?this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indenLine truncated
//# sourceMappingURL=adobe-css-tools.cjs.map
@@ -0,0 +1 @@
{"version":3,"file":"adobe-css-tools.cjs","sources":["../../src/CssParseError.ts","../../src/CssPosition.ts","../../src/type.ts","../../src/utils/stringSearch.ts","../../src/parse/index.ts","../../src/stringify/compiler.ts","../../src/index.ts","../../src/stringify/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["CssParseError","Error","reason","filename","line","column","source","constructor","msg","lineno","css","super","this","Position","start","end","CssTypes","indexOfArrayNonEscaped","string","search","position","currentPosition","maxLoop","all","map","v","indexOf","push","foundAll","filter","length","found","Math","min","indexOfArrayWithBracketAndQuoteSupport","currentSearchPosition","firstMatchPos","endPosition","endQuotePosition","commentRegex","trim","str","addParent","obj","parent","isNode","type","childParent","k","value","Array","isArray","forEach","Object","defineProperty","configurable","writable","enumerable","Compiler","level","indentation","compress","options","indent","emit","_position","join","visit","node","stylesheet","rule","declaration","comment","container","charset","counterStyle","document","customMedia","fontFace","fontFeatureValues","host","import","keyframes","keyframe","layer","media","namespace","page","pageMarginBox","positionTry","property","scope","startingStyle","supports","viewTransition","atRule","genericAtRule","mapVisit","nodes","delim","buf","i","compile","rules","doc","vendor","name","decls","declarations","values","sel","selectors","fontFamily","prelude","hasNestedRules","some","r","s","split","padEnd","parse","whitespace","errorsList","error","err","silent","open","openMatch","exec","processMatch","close","closeMatch","m","lines","match","lastIndexOf","updatePosition","slice","comments","c","pos","charAt","selector","bracePos","selectorStr","substring","result","index","splitWithBracketAndQuoteSupport","replace","propMatch","propValue","separatorMatch","endValuePosition","ret","endMatch","decl","semiPos","looksLikeNestedRule","closePos","ruleBody","items","ar","nestedR","rulesOrDeclarations","vals","res","spacesMatch","pageMarginBoxRegex","RegExp","atImport","_compileAtRule","atCharset","atNamespace","re","m1","m2","frames","frame","concat","atKeyframes","style","atMedia","atCustomMedia","atSupports","atDocument","atPage","atHost","atFontFace","atFontFeatureValues","atContainer","atStartingStyle","atLayer","atProperty","atCounterStyle","atScope","atViewTransition","atPositionTry","atPageMarginBox","preludeEnd","atGeneric","rulesList","parsingErrors","stringify"],"mappings":"oEAAc,MAAOA,UAAsBC,MAChCC,OACAC,SACAC,KACAC,OACAC,OAET,WAAAC,CACEJ,EACAK,EACAC,EACAJ,EACAK,GAEAC,MAAM,GAAGR,KAAYM,KAAUJ,MAAWG,KAC1CI,KAAKV,OAASM,EACdI,KAAKT,SAAWA,EAChBS,KAAKR,KAAOK,EACZG,KAAKP,OAASA,EACdO,KAAKN,OAASI,CAChB,ECjBY,MAAOG,EACnBC,MACAC,IACAT,OAEA,WAAAC,CACEO,EACAC,EACAT,GAEAM,KAAKE,MAAQA,EACbF,KAAKG,IAAMA,EACXH,KAAKN,OAASA,CAChB,ECbF,IAAYU,EAAAA,QAAAA,cAAAA,GAAAA,EAAAA,QAAAA,WAAAA,iBAAQ,CAAA,IAClB,WAAA,aACAA,EAAA,KAAA,OACAA,EAAA,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,OAAA,UACAA,EAAA,UAAA,YACAA,EAAA,QAAA,UACAA,EAAA,aAAA,gBACAA,EAAA,SAAA,WACAA,EAAA,YAAA,eACAA,EAAA,SAAA,YACAA,EAAA,kBAAA,sBACAA,EAAA,KAAA,OACAA,EAAA,OAAA,SACAA,EAAA,UAAA,YACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,MAAA,QACAA,EAAA,UAAA,YACAA,EAAA,KAAA,OACAA,EAAA,cAAA,kBACAA,EAAA,YAAA,eACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,cAAA,iBACAA,EAAA,SAAA,WACAA,EAAA,eAAA,kBC9BK,MAkBMC,EAAyB,CACpCC,EACAC,EACAC,KAEA,IAAIC,EAAkBD,EAClBE,EAxBkB,IAyBtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGJ,IAChDE,EAAII,KAAKT,EAAOQ,QAAQ,KAAML,IAC9B,MAAMO,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMC,EAAQC,KAAKC,OAAOL,GAC1B,GAAsB,OAAlBV,EAAOa,GAIT,OAAOA,EAHPV,EAAkBU,EAAQ,EAC1BT,GAIJ,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBA0BLiC,EAAyC,CACpDhB,EACAC,EACAC,KAEA,IAAIe,EAAwBf,EACxBE,EA1EkB,IA4EtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGU,IAEhDZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,KAAMS,IAE9B,MAAMP,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMM,EAAgBJ,KAAKC,OAAOL,GAElC,OADaV,EAAOkB,IAElB,IAAK,KACHD,EAAwBC,EAAgB,EACxC,MACF,IAAK,IACH,CACE,MAAMC,EAAcH,EAClBhB,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAoB,IAAhBC,EACF,OAAO,EAETF,EAAwBE,EAAc,CACxC,CACA,MACF,IAAK,IACH,CACE,MAAMC,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,IAAK,IACH,CACE,MAAMA,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,QACE,OAAOF,EAEXd,GACF,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBCjGZsC,EAAe,uBAotCrB,SAASC,EAAKC,GACZ,OAAOA,EAAMA,EAAID,OAAS,EAC5B,CAKA,SAASE,EACPC,EACAC,GAEA,MAAMC,EAASF,GAA2B,iBAAbA,EAAIG,KAC3BC,EAAcF,EAASF,EAAMC,EAEnC,IAAK,MAAMI,KAAKL,EAAK,CACnB,MAAMM,EAAQN,EAAIK,GACdE,MAAMC,QAAQF,GAChBA,EAAMG,QAAS3B,IACbiB,EAAUjB,EAAGsB,KAENE,GAA0B,iBAAVA,GACzBP,EAAUO,EAAOF,EAErB,CAWA,OATIF,GACFQ,OAAOC,eAALine truncated
+224
View File
@@ -0,0 +1,224 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
atRule = "at-rule",
container = "container",
charset = "charset",
counterStyle = "counter-style",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
fontFeatureValues = "font-feature-values",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
pageMarginBox = "page-margin-box",
positionTry = "position-try",
property = "property",
scope = "scope",
startingStyle = "starting-style",
supports = "supports",
viewTransition = "view-transition"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCounterStyleAST = CssCommonPositionAST & {
type: CssTypes.counterStyle;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssFontFeatureValuesAST = CssCommonPositionAST & {
type: CssTypes.fontFeatureValues;
fontFamily: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssPositionTryAST = CssCommonPositionAST & {
type: CssTypes.positionTry;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPropertyAST = CssCommonPositionAST & {
type: CssTypes.property;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssScopeAST = CssCommonPositionAST & {
type: CssTypes.scope;
scope: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssViewTransitionAST = CssCommonPositionAST & {
type: CssTypes.viewTransition;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPageMarginBoxAST = CssCommonPositionAST & {
type: CssTypes.pageMarginBox;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssGenericAtRuleAST = CssCommonPositionAST & {
type: CssTypes.atRule;
name: string;
prelude: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCounterStyleAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssFontFeatureValuesAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssPageMarginBoxAST | CssPositionTryAST | CssPropertyAST | CssScopeAST | CssSupportsAST | CssStartingStyleAST | CssViewTransitionAST | CssGenericAtRuleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCounterStyleAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssFontFeatureValuesAST, CssGenericAtRuleAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssPageMarginBoxAST, CssPositionTryAST, CssPropertyAST, CssRuleAST, CssScopeAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST, CssViewTransitionAST };
+224
View File
@@ -0,0 +1,224 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
atRule = "at-rule",
container = "container",
charset = "charset",
counterStyle = "counter-style",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
fontFeatureValues = "font-feature-values",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
pageMarginBox = "page-margin-box",
positionTry = "position-try",
property = "property",
scope = "scope",
startingStyle = "starting-style",
supports = "supports",
viewTransition = "view-transition"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCounterStyleAST = CssCommonPositionAST & {
type: CssTypes.counterStyle;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssFontFeatureValuesAST = CssCommonPositionAST & {
type: CssTypes.fontFeatureValues;
fontFamily: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssPositionTryAST = CssCommonPositionAST & {
type: CssTypes.positionTry;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPropertyAST = CssCommonPositionAST & {
type: CssTypes.property;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssScopeAST = CssCommonPositionAST & {
type: CssTypes.scope;
scope: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssViewTransitionAST = CssCommonPositionAST & {
type: CssTypes.viewTransition;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPageMarginBoxAST = CssCommonPositionAST & {
type: CssTypes.pageMarginBox;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssGenericAtRuleAST = CssCommonPositionAST & {
type: CssTypes.atRule;
name: string;
prelude: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCounterStyleAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssFontFeatureValuesAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssPageMarginBoxAST | CssPositionTryAST | CssPropertyAST | CssScopeAST | CssSupportsAST | CssStartingStyleAST | CssViewTransitionAST | CssGenericAtRuleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCounterStyleAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssFontFeatureValuesAST, CssGenericAtRuleAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssPageMarginBoxAST, CssPositionTryAST, CssPropertyAST, CssRuleAST, CssScopeAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST, CssViewTransitionAST };
+2
View File
@@ -0,0 +1,2 @@
class t extends Error{reason;filename;line;column;source;constructor(t,i,e,s,n){super(`${t}:${e}:${s}: ${i}`),this.reason=i,this.filename=t,this.line=e,this.column=s,this.source=n}}class i{start;end;source;constructor(t,i,e){this.start=t,this.end=i,this.source=e}}var e;!function(t){t.stylesheet="stylesheet",t.rule="rule",t.declaration="declaration",t.comment="comment",t.atRule="at-rule",t.container="container",t.charset="charset",t.counterStyle="counter-style",t.document="document",t.customMedia="custom-media",t.fontFace="font-face",t.fontFeatureValues="font-feature-values",t.host="host",t.import="import",t.keyframes="keyframes",t.keyframe="keyframe",t.layer="layer",t.media="media",t.namespace="namespace",t.page="page",t.pageMarginBox="page-margin-box",t.positionTry="position-try",t.property="property",t.scope="scope",t.startingStyle="starting-style",t.supports="supports",t.viewTransition="view-transition"}(e||(e={}));const s=(t,i,e)=>{let s=e,n=1e4;do{const e=i.map(i=>t.indexOf(i,s));e.push(t.indexOf("\\",s));const r=e.filter(t=>-1!==t);if(0===r.length)return-1;const o=Math.min(...r);if("\\"!==t[o])return o;s=o+2,n--}while(n>0);throw new Error("Too many escaping")},n=(t,i,e)=>{let r=e,o=1e4;do{const e=i.map(i=>t.indexOf(i,r));e.push(t.indexOf("(",r)),e.push(t.indexOf('"',r)),e.push(t.indexOf("'",r)),e.push(t.indexOf("\\",r));const c=e.filter(t=>-1!==t);if(0===c.length)return-1;const h=Math.min(...c);switch(t[h]){case"\\":r=h+2;break;case"(":{const i=n(t,[")"],h+1);if(-1===i)return-1;r=i+1}break;case'"':{const i=s(t,['"'],h+1);if(-1===i)return-1;r=i+1}break;case"'":{const i=s(t,["'"],h+1);if(-1===i)return-1;r=i+1}break;default:return h}o--}while(o>0);throw new Error("Too many escaping")},r=/\/\*[^]*?(?:\*\/|$)/g;function o(t){return t?t.trim():""}function c(t,i){const e=t&&"string"==typeof t.type,s=e?t:i;for(const i in t){const e=t[i];Array.isArray(e)?e.forEach(t=>{c(t,s)}):e&&"object"==typeof e&&c(e,s)}return e&&Object.defineProperty(t,"parent",{configurable:!0,writable:!0,enumerable:!1,value:i||null}),t}class h{level=0;indentation=" ";compress=!1;constructor(t){"string"==typeof t?.indent&&(this.indentation=t?.indent),t?.compress&&(this.compress=!0)}emit(t,i){return t}indent(t){return this.level=this.level||1,t?(this.level+=t,""):Array(this.level).join(this.indentation)}visit(t){switch(t.type){case e.stylesheet:return this.stylesheet(t);case e.rule:return this.rule(t);case e.declaration:return this.declaration(t);case e.comment:return this.comment(t);case e.container:return this.container(t);case e.charset:return this.charset(t);case e.counterStyle:return this.counterStyle(t);case e.document:return this.document(t);case e.customMedia:return this.customMedia(t);case e.fontFace:return this.fontFace(t);case e.fontFeatureValues:return this.fontFeatureValues(t);case e.host:return this.host(t);case e.import:return this.import(t);case e.keyframes:return this.keyframes(t);case e.keyframe:return this.keyframe(t);case e.layer:return this.layer(t);case e.media:return this.media(t);case e.namespace:return this.namespace(t);case e.page:return this.page(t);case e.pageMarginBox:return this.pageMarginBox(t);case e.positionTry:return this.positionTry(t);case e.property:return this.property(t);case e.scope:return this.scope(t);case e.startingStyle:return this.startingStyle(t);case e.supports:return this.supports(t);case e.viewTransition:return this.viewTransition(t);case e.atRule:return this.genericAtRule(t)}}mapVisit(t,i){let e="";i=i||"";for(let s=0,n=t.length;s<n;s++)e+=this.visit(t[s]),i&&s<n-1&&(e+=this.emit(i));return e}compile(t){return this.compress?t.stylesheet.rules.map(this.visit,this).join(""):this.stylesheet(t)}stylesheet(t){return this.mapVisit(t.stylesheet.rules,"\n\n")}comment(t){return this.compress?this.emit("",t.position):this.emit(`${this.indent()}/*${t.comment}*/`,t.position)}container(t){return this.compress?this.emit(`@container ${t.container}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@container ${t.container}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}layer(t){return this.compress?this.emit(`@layer ${t.layer}`,t.position)+(t.rules?this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):";"):this.emit(`${this.indent()}@layer ${t.layer}`,t.position)+(t.rules?this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`):";")}import(t){return this.emit(`@import ${t.import};`,t.position)}media(t){return this.compress?this.emit(`@media ${t.media}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@media ${t.media}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}document(t){const i=`@${t.vendor||""}document ${t.document}`;return this.compress?this.emit(i,t.position)+this.emit("{")+this.mapVisit(t.rulLine truncated
//# sourceMappingURL=adobe-css-tools.mjs.map
@@ -0,0 +1 @@
{"version":3,"file":"adobe-css-tools.mjs","sources":["../../src/CssParseError.ts","../../src/CssPosition.ts","../../src/type.ts","../../src/utils/stringSearch.ts","../../src/parse/index.ts","../../src/stringify/compiler.ts","../../src/index.ts","../../src/stringify/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["CssParseError","Error","reason","filename","line","column","source","constructor","msg","lineno","css","super","this","Position","start","end","CssTypes","indexOfArrayNonEscaped","string","search","position","currentPosition","maxLoop","all","map","v","indexOf","push","foundAll","filter","length","found","Math","min","indexOfArrayWithBracketAndQuoteSupport","currentSearchPosition","firstMatchPos","endPosition","endQuotePosition","commentRegex","trim","str","addParent","obj","parent","isNode","type","childParent","k","value","Array","isArray","forEach","Object","defineProperty","configurable","writable","enumerable","Compiler","level","indentation","compress","options","indent","emit","_position","join","visit","node","stylesheet","rule","declaration","comment","container","charset","counterStyle","document","customMedia","fontFace","fontFeatureValues","host","import","keyframes","keyframe","layer","media","namespace","page","pageMarginBox","positionTry","property","scope","startingStyle","supports","viewTransition","atRule","genericAtRule","mapVisit","nodes","delim","buf","i","compile","rules","doc","vendor","name","decls","declarations","values","sel","selectors","fontFamily","prelude","hasNestedRules","some","r","s","split","padEnd","parse","whitespace","errorsList","error","err","silent","open","openMatch","exec","processMatch","close","closeMatch","m","lines","match","lastIndexOf","updatePosition","slice","comments","c","pos","charAt","selector","bracePos","selectorStr","substring","result","index","splitWithBracketAndQuoteSupport","replace","propMatch","propValue","separatorMatch","endValuePosition","ret","endMatch","decl","semiPos","looksLikeNestedRule","closePos","ruleBody","items","ar","nestedR","rulesOrDeclarations","vals","res","spacesMatch","pageMarginBoxRegex","RegExp","atImport","_compileAtRule","atCharset","atNamespace","re","m1","m2","frames","frame","concat","atKeyframes","style","atMedia","atCustomMedia","atSupports","atDocument","atPage","atHost","atFontFace","atFontFeatureValues","atContainer","atStartingStyle","atLayer","atProperty","atCounterStyle","atScope","atViewTransition","atPositionTry","atPageMarginBox","preludeEnd","atGeneric","rulesList","parsingErrors","stringify"],"mappings":"AAAc,MAAOA,UAAsBC,MAChCC,OACAC,SACAC,KACAC,OACAC,OAET,WAAAC,CACEJ,EACAK,EACAC,EACAJ,EACAK,GAEAC,MAAM,GAAGR,KAAYM,KAAUJ,MAAWG,KAC1CI,KAAKV,OAASM,EACdI,KAAKT,SAAWA,EAChBS,KAAKR,KAAOK,EACZG,KAAKP,OAASA,EACdO,KAAKN,OAASI,CAChB,ECjBY,MAAOG,EACnBC,MACAC,IACAT,OAEA,WAAAC,CACEO,EACAC,EACAT,GAEAM,KAAKE,MAAQA,EACbF,KAAKG,IAAMA,EACXH,KAAKN,OAASA,CAChB,MCbUU,GAAZ,SAAYA,GACVA,EAAA,WAAA,aACAA,EAAA,KAAA,OACAA,EAAA,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,OAAA,UACAA,EAAA,UAAA,YACAA,EAAA,QAAA,UACAA,EAAA,aAAA,gBACAA,EAAA,SAAA,WACAA,EAAA,YAAA,eACAA,EAAA,SAAA,YACAA,EAAA,kBAAA,sBACAA,EAAA,KAAA,OACAA,EAAA,OAAA,SACAA,EAAA,UAAA,YACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,MAAA,QACAA,EAAA,UAAA,YACAA,EAAA,KAAA,OACAA,EAAA,cAAA,kBACAA,EAAA,YAAA,eACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,cAAA,iBACAA,EAAA,SAAA,WACAA,EAAA,eAAA,iBACD,CA5BD,CAAYA,IAAAA,EAAQ,CAAA,ICHb,MAkBMC,EAAyB,CACpCC,EACAC,EACAC,KAEA,IAAIC,EAAkBD,EAClBE,EAxBkB,IAyBtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGJ,IAChDE,EAAII,KAAKT,EAAOQ,QAAQ,KAAML,IAC9B,MAAMO,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMC,EAAQC,KAAKC,OAAOL,GAC1B,GAAsB,OAAlBV,EAAOa,GAIT,OAAOA,EAHPV,EAAkBU,EAAQ,EAC1BT,GAIJ,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBA0BLiC,EAAyC,CACpDhB,EACAC,EACAC,KAEA,IAAIe,EAAwBf,EACxBE,EA1EkB,IA4EtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGU,IAEhDZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,KAAMS,IAE9B,MAAMP,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMM,EAAgBJ,KAAKC,OAAOL,GAElC,OADaV,EAAOkB,IAElB,IAAK,KACHD,EAAwBC,EAAgB,EACxC,MACF,IAAK,IACH,CACE,MAAMC,EAAcH,EAClBhB,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAoB,IAAhBC,EACF,OAAO,EAETF,EAAwBE,EAAc,CACxC,CACA,MACF,IAAK,IACH,CACE,MAAMC,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,IAAK,IACH,CACE,MAAMA,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,QACE,OAAOF,EAEXd,GACF,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBCjGZsC,EAAe,uBAotCrB,SAASC,EAAKC,GACZ,OAAOA,EAAMA,EAAID,OAAS,EAC5B,CAKA,SAASE,EACPC,EACAC,GAEA,MAAMC,EAASF,GAA2B,iBAAbA,EAAIG,KAC3BC,EAAcF,EAASF,EAAMC,EAEnC,IAAK,MAAMI,KAAKL,EAAK,CACnB,MAAMM,EAAQN,EAAIK,GACdE,MAAMC,QAAQF,GAChBA,EAAMG,QAAS3B,IACbiB,EAAUjB,EAAGsB,KAENE,GAA0B,iBAAVA,GACzBP,EAAUO,EAAOF,EAErB,CAWA,OATIF,GACFQ,OAAOC,eAAeX,EAAK,SAALine truncated
+224
View File
@@ -0,0 +1,224 @@
declare class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(filename: string, msg: string, lineno: number, column: number, css: string);
}
/**
* Store position information for a node
*/
declare class Position {
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
source?: string;
constructor(start: {
line: number;
column: number;
}, end: {
line: number;
column: number;
}, source: string);
}
declare enum CssTypes {
stylesheet = "stylesheet",
rule = "rule",
declaration = "declaration",
comment = "comment",
atRule = "at-rule",
container = "container",
charset = "charset",
counterStyle = "counter-style",
document = "document",
customMedia = "custom-media",
fontFace = "font-face",
fontFeatureValues = "font-feature-values",
host = "host",
import = "import",
keyframes = "keyframes",
keyframe = "keyframe",
layer = "layer",
media = "media",
namespace = "namespace",
page = "page",
pageMarginBox = "page-margin-box",
positionTry = "position-try",
property = "property",
scope = "scope",
startingStyle = "starting-style",
supports = "supports",
viewTransition = "view-transition"
}
type CssCommonAST = {
type: CssTypes;
};
type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssCounterStyleAST = CssCommonPositionAST & {
type: CssTypes.counterStyle;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssFontFeatureValuesAST = CssCommonPositionAST & {
type: CssTypes.fontFeatureValues;
fontFamily: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssPositionTryAST = CssCommonPositionAST & {
type: CssTypes.positionTry;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPropertyAST = CssCommonPositionAST & {
type: CssTypes.property;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssScopeAST = CssCommonPositionAST & {
type: CssTypes.scope;
scope: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssViewTransitionAST = CssCommonPositionAST & {
type: CssTypes.viewTransition;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssPageMarginBoxAST = CssCommonPositionAST & {
type: CssTypes.pageMarginBox;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
type CssGenericAtRuleAST = CssCommonPositionAST & {
type: CssTypes.atRule;
name: string;
prelude: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
type CssAtRuleAST = CssRuleAST | CssCommentAST | CssContainerAST | CssCharsetAST | CssCounterStyleAST | CssCustomMediaAST | CssDocumentAST | CssFontFaceAST | CssFontFeatureValuesAST | CssHostAST | CssImportAST | CssKeyframesAST | CssLayerAST | CssMediaAST | CssNamespaceAST | CssPageAST | CssPageMarginBoxAST | CssPositionTryAST | CssPropertyAST | CssScopeAST | CssSupportsAST | CssStartingStyleAST | CssViewTransitionAST | CssGenericAtRuleAST;
type CssAllNodesAST = CssAtRuleAST | CssStylesheetAST | CssDeclarationAST | CssKeyframeAST;
type CompilerOptions = {
indent?: string;
compress?: boolean;
};
declare const parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
declare const stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
declare const _default: {
parse: (css: string, options?: {
source?: string;
silent?: boolean;
}) => CssStylesheetAST;
stringify: (node: CssStylesheetAST, options?: CompilerOptions) => string;
};
export { CssTypes, _default as default, parse, stringify };
export type { CssAllNodesAST, CssAtRuleAST, CssCharsetAST, CssCommentAST, CssCommonAST, CssCommonPositionAST, CssContainerAST, CssCounterStyleAST, CssCustomMediaAST, CssDeclarationAST, CssDocumentAST, CssFontFaceAST, CssFontFeatureValuesAST, CssGenericAtRuleAST, CssHostAST, CssImportAST, CssKeyframeAST, CssKeyframesAST, CssLayerAST, CssMediaAST, CssNamespaceAST, CssPageAST, CssPageMarginBoxAST, CssPositionTryAST, CssPropertyAST, CssRuleAST, CssScopeAST, CssStartingStyleAST, CssStylesheetAST, CssSupportsAST, CssViewTransitionAST };
+2
View File
@@ -0,0 +1,2 @@
!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?s(exports):"function"==typeof define&&define.amd?define(["exports"],s):s((t="undefined"!=typeof globalThis?globalThis:t||self).cssTools={})}(this,function(t){"use strict";class s extends Error{reason;filename;line;column;source;constructor(t,s,e,i,n){super(`${t}:${e}:${i}: ${s}`),this.reason=s,this.filename=t,this.line=e,this.column=i,this.source=n}}class e{start;end;source;constructor(t,s,e){this.start=t,this.end=s,this.source=e}}var i;t.CssTypes=void 0,(i=t.CssTypes||(t.CssTypes={})).stylesheet="stylesheet",i.rule="rule",i.declaration="declaration",i.comment="comment",i.atRule="at-rule",i.container="container",i.charset="charset",i.counterStyle="counter-style",i.document="document",i.customMedia="custom-media",i.fontFace="font-face",i.fontFeatureValues="font-feature-values",i.host="host",i.import="import",i.keyframes="keyframes",i.keyframe="keyframe",i.layer="layer",i.media="media",i.namespace="namespace",i.page="page",i.pageMarginBox="page-margin-box",i.positionTry="position-try",i.property="property",i.scope="scope",i.startingStyle="starting-style",i.supports="supports",i.viewTransition="view-transition";const n=(t,s,e)=>{let i=e,n=1e4;do{const e=s.map(s=>t.indexOf(s,i));e.push(t.indexOf("\\",i));const r=e.filter(t=>-1!==t);if(0===r.length)return-1;const o=Math.min(...r);if("\\"!==t[o])return o;i=o+2,n--}while(n>0);throw new Error("Too many escaping")},r=(t,s,e)=>{let i=e,o=1e4;do{const e=s.map(s=>t.indexOf(s,i));e.push(t.indexOf("(",i)),e.push(t.indexOf('"',i)),e.push(t.indexOf("'",i)),e.push(t.indexOf("\\",i));const c=e.filter(t=>-1!==t);if(0===c.length)return-1;const h=Math.min(...c);switch(t[h]){case"\\":i=h+2;break;case"(":{const s=r(t,[")"],h+1);if(-1===s)return-1;i=s+1}break;case'"':{const s=n(t,['"'],h+1);if(-1===s)return-1;i=s+1}break;case"'":{const s=n(t,["'"],h+1);if(-1===s)return-1;i=s+1}break;default:return h}o--}while(o>0);throw new Error("Too many escaping")},o=/\/\*[^]*?(?:\*\/|$)/g;function c(t){return t?t.trim():""}function h(t,s){const e=t&&"string"==typeof t.type,i=e?t:s;for(const s in t){const e=t[s];Array.isArray(e)?e.forEach(t=>{h(t,i)}):e&&"object"==typeof e&&h(e,i)}return e&&Object.defineProperty(t,"parent",{configurable:!0,writable:!0,enumerable:!1,value:s||null}),t}class a{level=0;indentation=" ";compress=!1;constructor(t){"string"==typeof t?.indent&&(this.indentation=t?.indent),t?.compress&&(this.compress=!0)}emit(t,s){return t}indent(t){return this.level=this.level||1,t?(this.level+=t,""):Array(this.level).join(this.indentation)}visit(s){switch(s.type){case t.CssTypes.stylesheet:return this.stylesheet(s);case t.CssTypes.rule:return this.rule(s);case t.CssTypes.declaration:return this.declaration(s);case t.CssTypes.comment:return this.comment(s);case t.CssTypes.container:return this.container(s);case t.CssTypes.charset:return this.charset(s);case t.CssTypes.counterStyle:return this.counterStyle(s);case t.CssTypes.document:return this.document(s);case t.CssTypes.customMedia:return this.customMedia(s);case t.CssTypes.fontFace:return this.fontFace(s);case t.CssTypes.fontFeatureValues:return this.fontFeatureValues(s);case t.CssTypes.host:return this.host(s);case t.CssTypes.import:return this.import(s);case t.CssTypes.keyframes:return this.keyframes(s);case t.CssTypes.keyframe:return this.keyframe(s);case t.CssTypes.layer:return this.layer(s);case t.CssTypes.media:return this.media(s);case t.CssTypes.namespace:return this.namespace(s);case t.CssTypes.page:return this.page(s);case t.CssTypes.pageMarginBox:return this.pageMarginBox(s);case t.CssTypes.positionTry:return this.positionTry(s);case t.CssTypes.property:return this.property(s);case t.CssTypes.scope:return this.scope(s);case t.CssTypes.startingStyle:return this.startingStyle(s);case t.CssTypes.supports:return this.supports(s);case t.CssTypes.viewTransition:return this.viewTransition(s);case t.CssTypes.atRule:return this.genericAtRule(s)}}mapVisit(t,s){let e="";s=s||"";for(let i=0,n=t.length;i<n;i++)e+=this.visit(t[i]),s&&i<n-1&&(e+=this.emit(s));return e}compile(t){return this.compress?t.stylesheet.rules.map(this.visit,this).join(""):this.stylesheet(t)}stylesheet(t){return this.mapVisit(t.stylesheet.rules,"\n\n")}comment(t){return this.compress?this.emit("",t.position):this.emit(`${this.indent()}/*${t.comment}*/`,t.position)}container(t){return this.compress?this.emit(`@container ${t.container}`,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):this.emit(`${this.indent()}@container ${t.container}`,t.position)+this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`)}layer(t){return this.compress?this.emit(`@layer ${t.layer}`,t.position)+(t.rules?this.emit("{")+this.mapVisit(t.rules)+this.emit("}"):";"):this.emit(`${this.indent()}@layer ${t.layer}`,t.position)+(t.rules?this.emit(` {\n${this.indent(1)}`)+this.mapVisit(t.rules,"\n\n")+this.emit(`\n${this.indent(-1)}${this.indent()}}`):"Line truncated
//# sourceMappingURL=adobe-css-tools.js.map
@@ -0,0 +1 @@
{"version":3,"file":"adobe-css-tools.js","sources":["../../src/CssParseError.ts","../../src/CssPosition.ts","../../src/type.ts","../../src/utils/stringSearch.ts","../../src/parse/index.ts","../../src/stringify/compiler.ts","../../src/index.ts","../../src/stringify/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["CssParseError","Error","reason","filename","line","column","source","constructor","msg","lineno","css","super","this","Position","start","end","CssTypes","indexOfArrayNonEscaped","string","search","position","currentPosition","maxLoop","all","map","v","indexOf","push","foundAll","filter","length","found","Math","min","indexOfArrayWithBracketAndQuoteSupport","currentSearchPosition","firstMatchPos","endPosition","endQuotePosition","commentRegex","trim","str","addParent","obj","parent","isNode","type","childParent","k","value","Array","isArray","forEach","Object","defineProperty","configurable","writable","enumerable","Compiler","level","indentation","compress","options","indent","emit","_position","join","visit","node","stylesheet","rule","declaration","comment","container","charset","counterStyle","document","customMedia","fontFace","fontFeatureValues","host","import","keyframes","keyframe","layer","media","namespace","page","pageMarginBox","positionTry","property","scope","startingStyle","supports","viewTransition","atRule","genericAtRule","mapVisit","nodes","delim","buf","i","compile","rules","doc","vendor","name","decls","declarations","values","sel","selectors","fontFamily","prelude","hasNestedRules","some","r","s","split","padEnd","parse","whitespace","errorsList","error","err","silent","open","openMatch","exec","processMatch","close","closeMatch","m","lines","match","lastIndexOf","updatePosition","slice","comments","c","pos","charAt","selector","bracePos","selectorStr","substring","result","index","splitWithBracketAndQuoteSupport","replace","propMatch","propValue","separatorMatch","endValuePosition","ret","endMatch","decl","semiPos","looksLikeNestedRule","closePos","ruleBody","items","ar","nestedR","rulesOrDeclarations","vals","res","spacesMatch","pageMarginBoxRegex","RegExp","atImport","_compileAtRule","atCharset","atNamespace","re","m1","m2","frames","frame","concat","atKeyframes","style","atMedia","atCustomMedia","atSupports","atDocument","atPage","atHost","atFontFace","atFontFeatureValues","atContainer","atStartingStyle","atLayer","atProperty","atCounterStyle","atScope","atViewTransition","atPositionTry","atPageMarginBox","preludeEnd","atGeneric","rulesList","parsingErrors","stringify"],"mappings":"+OAAc,MAAOA,UAAsBC,MAChCC,OACAC,SACAC,KACAC,OACAC,OAET,WAAAC,CACEJ,EACAK,EACAC,EACAJ,EACAK,GAEAC,MAAM,GAAGR,KAAYM,KAAUJ,MAAWG,KAC1CI,KAAKV,OAASM,EACdI,KAAKT,SAAWA,EAChBS,KAAKR,KAAOK,EACZG,KAAKP,OAASA,EACdO,KAAKN,OAASI,CAChB,ECjBY,MAAOG,EACnBC,MACAC,IACAT,OAEA,WAAAC,CACEO,EACAC,EACAT,GAEAM,KAAKE,MAAQA,EACbF,KAAKG,IAAMA,EACXH,KAAKN,OAASA,CAChB,ECbF,IAAYU,EAAAA,EAAAA,cAAAA,GAAAA,EAAAA,EAAAA,WAAAA,WAAQ,CAAA,IAClB,WAAA,aACAA,EAAA,KAAA,OACAA,EAAA,YAAA,cACAA,EAAA,QAAA,UACAA,EAAA,OAAA,UACAA,EAAA,UAAA,YACAA,EAAA,QAAA,UACAA,EAAA,aAAA,gBACAA,EAAA,SAAA,WACAA,EAAA,YAAA,eACAA,EAAA,SAAA,YACAA,EAAA,kBAAA,sBACAA,EAAA,KAAA,OACAA,EAAA,OAAA,SACAA,EAAA,UAAA,YACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,MAAA,QACAA,EAAA,UAAA,YACAA,EAAA,KAAA,OACAA,EAAA,cAAA,kBACAA,EAAA,YAAA,eACAA,EAAA,SAAA,WACAA,EAAA,MAAA,QACAA,EAAA,cAAA,iBACAA,EAAA,SAAA,WACAA,EAAA,eAAA,kBC9BK,MAkBMC,EAAyB,CACpCC,EACAC,EACAC,KAEA,IAAIC,EAAkBD,EAClBE,EAxBkB,IAyBtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGJ,IAChDE,EAAII,KAAKT,EAAOQ,QAAQ,KAAML,IAC9B,MAAMO,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMC,EAAQC,KAAKC,OAAOL,GAC1B,GAAsB,OAAlBV,EAAOa,GAIT,OAAOA,EAHPV,EAAkBU,EAAQ,EAC1BT,GAIJ,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBA0BLiC,EAAyC,CACpDhB,EACAC,EACAC,KAEA,IAAIe,EAAwBf,EACxBE,EA1EkB,IA4EtB,EAAG,CACD,MAAMC,EAAMJ,EAAOK,IAAKC,GAAMP,EAAOQ,QAAQD,EAAGU,IAEhDZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,IAAKS,IAC7BZ,EAAII,KAAKT,EAAOQ,QAAQ,KAAMS,IAE9B,MAAMP,EAAWL,EAAIM,OAAQJ,QAAMA,GACnC,GAAwB,IAApBG,EAASE,OACX,OAAO,EAGT,MAAMM,EAAgBJ,KAAKC,OAAOL,GAElC,OADaV,EAAOkB,IAElB,IAAK,KACHD,EAAwBC,EAAgB,EACxC,MACF,IAAK,IACH,CACE,MAAMC,EAAcH,EAClBhB,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAoB,IAAhBC,EACF,OAAO,EAETF,EAAwBE,EAAc,CACxC,CACA,MACF,IAAK,IACH,CACE,MAAMC,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,IAAK,IACH,CACE,MAAMA,EAAmBrB,EACvBC,EACA,CAAC,KACDkB,EAAgB,GAElB,IAAyB,IAArBE,EACF,OAAO,EAETH,EAAwBG,EAAmB,CAC7C,CACA,MACF,QACE,OAAOF,EAEXd,GACF,OAASA,EAAU,GAEnB,MAAM,IAAIrB,MAAM,sBCjGZsC,EAAe,uBAotCrB,SAASC,EAAKC,GACZ,OAAOA,EAAMA,EAAID,OAAS,EAC5B,CAKA,SAASE,EACPC,EACAC,GAEA,MAAMC,EAASF,GAA2B,iBAAbA,EAAIG,KAC3BC,EAAcF,EAASF,EAAMC,EAEnC,IAAK,MAAMI,KAAKL,EAAK,CACnB,MAAMM,EAAQN,EAAIK,GACdE,MAAMC,QAAQF,GAChBA,EAAMG,QAAS3B,IACbiB,EAAUjB,EAAGsB,KAENE,GAA0B,iBAAVA,GACzBP,EAAUO,EAAOF,EAErB,CAWA,OATIF,GACFQ,OAAOC,eAAeXLine truncated
+314
View File
@@ -0,0 +1,314 @@
# API Reference
## Overview
`@adobe/css-tools` provides a modern CSS parser and stringifier with comprehensive TypeScript support. It can parse CSS into an Abstract Syntax Tree (AST) and convert the AST back to CSS with various formatting options.
## Installation
```bash
npm install @adobe/css-tools
```
## Core Functions
### `parse(code, options?)`
Parses CSS code and returns an Abstract Syntax Tree (AST).
#### Parameters
- `code` (string) - The CSS code to parse
- `options` (object, optional) - Parsing options
- `silent` (boolean) - Silently fail on parse errors instead of throwing. When `true`, errors are collected in `ast.stylesheet.parsingErrors`
- `source` (string) - File path for better error reporting
#### Returns
- `CssStylesheetAST` - The parsed CSS as an AST
#### Example
```javascript
import { parse } from '@adobe/css-tools';
const css = `
.example {
color: red;
font-size: 16px;
}
`;
const ast = parse(css);
console.log(ast.stylesheet.rules);
```
### `stringify(ast, options?)`
Converts a CSS AST back to CSS string with configurable formatting.
#### Parameters
- `ast` (CssStylesheetAST) - The CSS AST to stringify
- `options` (CompilerOptions, optional) - Stringification options
- `indent` (string) - Indentation string (default: `' '`)
- `compress` (boolean) - Whether to compress/minify the output (default: `false`)
#### Returns
- `string` - The formatted CSS string
#### Example
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = '.example { color: red; }';
const ast = parse(css);
// Pretty print
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// .example {
// color: red;
// }
// Compressed
const minified = stringify(ast, { compress: true });
console.log(minified);
// Output: .example{color:red}
```
## Type Definitions
### Core Types
#### `CssStylesheetAST`
The root AST node representing a complete CSS stylesheet.
```typescript
type CssStylesheetAST = {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: CssRuleAST[];
parsingErrors?: CssParseError[];
};
};
```
#### `CssRuleAST`
Represents a CSS rule (selector + declarations).
```typescript
type CssRuleAST = {
type: CssTypes.rule;
selectors: string[];
declarations: CssDeclarationAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssDeclarationAST`
Represents a CSS property declaration.
```typescript
type CssDeclarationAST = {
type: CssTypes.declaration;
property: string;
value: string;
position?: CssPosition;
parent?: CssRuleAST;
};
```
#### `CssMediaAST`
Represents a CSS @media rule.
```typescript
type CssMediaAST = {
type: CssTypes.media;
media: string;
rules: CssRuleAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssKeyframesAST`
Represents a CSS @keyframes rule.
```typescript
type CssKeyframesAST = {
type: CssTypes.keyframes;
name: string;
keyframes: CssKeyframeAST[];
position?: CssPosition;
parent?: CssStylesheetAST;
};
```
#### `CssPosition`
Represents source position information.
```typescript
type CssPosition = {
source?: string;
start: {
line: number;
column: number;
};
end: {
line: number;
column: number;
};
};
```
#### `CssParseError`
Represents a parsing error.
```typescript
type CssParseError = {
message: string;
reason: string;
filename?: string;
line: number;
column: number;
source?: string;
};
```
### Compiler Options
#### `CompilerOptions`
Options for the stringifier.
```typescript
type CompilerOptions = {
indent?: string; // Default: ' '
compress?: boolean; // Default: false
};
```
## Error Handling
### Silent Parsing
When parsing malformed CSS, you can use the `silent` option to collect errors instead of throwing:
```javascript
import { parse } from '@adobe/css-tools';
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`;
const result = parse(malformedCss, { silent: true });
if (result.stylesheet.parsingErrors) {
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`);
});
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length);
```
### Source Tracking
Enable source tracking for better error reporting:
```javascript
import { parse } from '@adobe/css-tools';
const css = 'body { color: red; }';
const ast = parse(css, { source: 'styles.css' });
const rule = ast.stylesheet.rules[0];
console.log(rule.position?.source); // "styles.css"
console.log(rule.position?.start); // { line: 1, column: 1 }
console.log(rule.position?.end); // { line: 1, column: 20 }
```
## Advanced Usage
### Working with At-Rules
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
@media (max-width: 768px) {
.container {
padding: 10px;
}
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
`;
const ast = parse(css);
// Access media rules
const mediaRule = ast.stylesheet.rules.find(rule => rule.type === 'media');
console.log(mediaRule.media); // "(max-width: 768px)"
// Access keyframes
const keyframesRule = ast.stylesheet.rules.find(rule => rule.type === 'keyframes');
console.log(keyframesRule.name); // "fadeIn"
```
### Custom Formatting
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = '.example{color:red;font-size:16px}';
const ast = parse(css);
// Custom indentation
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// .example {
// color: red;
// font-size: 16px;
// }
// Compressed with no spaces
const compressed = stringify(ast, { compress: true });
console.log(compressed);
// Output: .example{color:red;font-size:16px}
```
## TypeScript Integration
The library provides comprehensive TypeScript support with full type definitions for all AST nodes and functions:
```typescript
import { parse, stringify, type CssStylesheetAST } from '@adobe/css-tools';
const css: string = '.example { color: red; }';
const ast: CssStylesheetAST = parse(css);
const output: string = stringify(ast);
```
## Performance Considerations
- The parser is optimized for large CSS files
- AST nodes are lightweight and memory-efficient
- Stringification is fast and supports streaming for large outputs
- Consider using `compress: true` for production builds to reduce file size
## Browser Support
The library works in all modern browsers and Node.js environments. For older environments, you may need to use a bundler with appropriate polyfills.
+366
View File
@@ -0,0 +1,366 @@
# Abstract Syntax Tree (AST)
## Overview
The AST represents CSS as a tree structure where each node has a specific type and properties. All nodes share common properties and have type-specific properties.
## Common Properties
All AST nodes have these properties:
### `type`
The node type as a string. See [Node Types](#node-types) for all possible values.
### `position` (optional)
Position information for the node in the source code:
```typescript
{
start: { line: number; column: number };
end: { line: number; column: number };
source?: string;
}
```
### `parent` (optional)
Reference to the parent node in the AST.
## Node Types
### `stylesheet`
The root node representing an entire CSS document.
**Properties:**
- `stylesheet.source` (optional): Source file path
- `stylesheet.rules`: Array of top-level rules
- `stylesheet.parsingErrors` (optional): Array of parse errors when `silent` option is used
**Example:**
```json
{
"type": "stylesheet",
"stylesheet": {
"rules": [
// ... other nodes
]
}
}
```
### `rule`
A CSS rule with selectors and declarations.
**Properties:**
- `selectors`: Array of CSS selectors as strings
- `declarations`: Array of declarations and comments
**Example:**
```json
{
"type": "rule",
"selectors": ["body", "html"],
"declarations": [
{
"type": "declaration",
"property": "color",
"value": "red"
}
]
}
```
### `declaration`
A CSS property declaration.
**Properties:**
- `property`: The CSS property name
- `value`: The CSS property value as a string
**Example:**
```json
{
"type": "declaration",
"property": "background-color",
"value": "#ffffff"
}
```
### `comment`
A CSS comment.
**Properties:**
- `comment`: The comment text (without `/*` and `*/`)
**Example:**
```json
{
"type": "comment",
"comment": " This is a comment "
}
```
### `media`
A `@media` rule.
**Properties:**
- `media`: The media query string
- `rules`: Array of rules within the media block
**Example:**
```json
{
"type": "media",
"media": "screen and (max-width: 768px)",
"rules": [
// ... nested rules
]
}
```
### `keyframes`
A `@keyframes` rule.
**Properties:**
- `name`: The keyframes name
- `vendor` (optional): Vendor prefix (e.g., "-webkit-")
- `keyframes`: Array of keyframe rules and comments
**Example:**
```json
{
"type": "keyframes",
"name": "fade",
"keyframes": [
{
"type": "keyframe",
"values": ["from"],
"declarations": [
{
"type": "declaration",
"property": "opacity",
"value": "0"
}
]
}
]
}
```
### `keyframe`
A keyframe within a `@keyframes` rule.
**Properties:**
- `values`: Array of keyframe selectors (e.g., `["from"]`, `["to"]`, `["50%"]`)
- `declarations`: Array of declarations and comments
### `import`
An `@import` rule.
**Properties:**
- `import`: The import string (URL or media query)
**Example:**
```json
{
"type": "import",
"import": "url('styles.css')"
}
```
### `charset`
A `@charset` rule.
**Properties:**
- `charset`: The character encoding
**Example:**
```json
{
"type": "charset",
"charset": "utf-8"
}
```
### `namespace`
A `@namespace` rule.
**Properties:**
- `namespace`: The namespace declaration
**Example:**
```json
{
"type": "namespace",
"namespace": "url(http://www.w3.org/1999/xhtml)"
}
```
### `supports`
A `@supports` rule.
**Properties:**
- `supports`: The supports condition
- `rules`: Array of rules within the supports block
**Example:**
```json
{
"type": "supports",
"supports": "(display: grid)",
"rules": [
// ... nested rules
]
}
```
### `document`
A `@document` rule.
**Properties:**
- `document`: The document condition
- `vendor` (optional): Vendor prefix
- `rules`: Array of rules within the document block
### `page`
A `@page` rule.
**Properties:**
- `selectors`: Array of page selectors
- `declarations`: Array of declarations and comments
### `font-face`
A `@font-face` rule.
**Properties:**
- `declarations`: Array of font declarations and comments
### `host`
A `:host` rule.
**Properties:**
- `rules`: Array of rules within the host block
### `container`
A `@container` rule.
**Properties:**
- `container`: The container query
- `rules`: Array of rules within the container block
### `layer`
A `@layer` rule.
**Properties:**
- `layer`: The layer name
- `rules` (optional): Array of rules within the layer block
### `custom-media`
A `@custom-media` rule.
**Properties:**
- `name`: The custom media query name
- `media`: The media query definition
### `starting-style`
A `@starting-style` rule.
**Properties:**
- `rules`: Array of rules within the starting-style block
## Type Hierarchy
The AST nodes are organized in the following hierarchy:
- `CssStylesheetAST` - Root node
- `CssAtRuleAST` - Union of all at-rule and rule nodes
- `CssAllNodesAST` - Union of all possible node types
## Working with the AST
### Traversing Nodes
```typescript
import { parse, CssStylesheetAST } from '@adobe/css-tools';
const ast: CssStylesheetAST = parse('body { color: red; }');
// Access top-level rules
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule') {
console.log('Selectors:', rule.selectors);
rule.declarations.forEach(decl => {
if (decl.type === 'declaration') {
console.log(`${decl.property}: ${decl.value}`);
}
});
}
});
```
### Modifying Nodes
```typescript
// Add a new declaration
const newDecl = {
type: 'declaration' as const,
property: 'font-size',
value: '16px'
};
// Find a rule and add the declaration
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'rule' && rule.selectors.includes('body')) {
rule.declarations.push(newDecl);
}
});
```
### Error Handling
When parsing with the `silent` option, errors are collected in the AST:
```typescript
const ast = parse('invalid css {', { silent: true });
if (ast.stylesheet.parsingErrors) {
ast.stylesheet.parsingErrors.forEach(error => {
console.error('Parse error:', error.message);
});
}
```
## Position Information
Position information is available on most nodes and includes:
- `start.line` and `start.column`: Beginning of the node
- `end.line` and `end.column`: End of the node
- `source`: Source file path (if provided during parsing)
This is useful for:
- Error reporting
- Source mapping
- Code analysis tools
- IDE integration
+216
View File
@@ -0,0 +1,216 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [4.5.0] - 2026-05-20
### Added
- Add support for CSS Nesting — rules nested inside other rules (#621 by @jogibear9988)
- Add support for `@container` container queries with nested rule body
- Add support for Page Margin Boxes (`@top-left`, `@bottom-right`, `@left-middle`, etc.) inside `@page`
- Add generic at-rule fallback — unknown `@foo { ... }` and `@foo ...;` rules are preserved as `CssGenericAtRuleAST` instead of being dropped
- Add support for `@counter-style`, `@font-feature-values`, `@scope`, `@view-transition`, `@position-try`
- Export new TypeScript types: `CssGenericAtRuleAST`, `CssPageMarginBoxAST`, `CssPositionTryAST`, `CssScopeAST`, `CssViewTransitionAST`, `CssCounterStyleAST`, `CssFontFeatureValuesAST`
### Fixed
- Fix selector parsing for complex nested selectors including `:is()`, `:has()`, `:not()`
- Fix `@page` to correctly accept margin-box at-rule children
- Fix bracket- and quote-aware position tracking for pseudo-functions
### Changed
- Upgrade to TypeScript 6.0.2
- Upgrade to `@rollup/plugin-terser` 1.0.0
- Drop Node 18 from CI (EOL April 2025) — minimum supported runtime is now Node 20
### Security
- Update lodash to 4.18.1
- Update minimatch to 3.1.5
- Update picomatch to 4.0.4
## [4.4.4] - 2025-07-22
### Changed
- Switch from yarn to npm for package management
- Switch from eslint to biome for code formatting and linting
- Reformat codebase to comply with biome recommendations
- Switch from webpack to rollup for bundling
### Fixed
- Fix module exports to ensure proper compatibility with bundlers
- Add validation check to prevent future export issues
## [4.4.3] - 2025-05-15
### Security
- Fix polynomial regular expression vulnerability on uncontrolled data
- Refactor code to enable GitHub security static analysis
### Performance
- Improve parsing performance with minor optimizations
- Replace regex patterns with string search (indexOf-based) for better performance
### Added
- Add new utility functions with comprehensive unit tests
- Add improved formatting for CSS Grid template areas (#283 by @jogibear9988)
### Fixed
- Fix TypeScript error with ConstructorParameters in Parcel bundler (#444)
## [4.4.2] - 2025-02-12
### Fixed
- Fix regular expression for parsing quoted values in parentheses
## [4.4.0] - 2024-06-05
### Added
- Add support for CSS `@starting-style` at-rule (#319)
## [4.3.3] - 2024-01-24
### Changed
- Update package export configuration (#271)
## [4.3.2] - 2023-11-28
### Security
- Fix ReDoS vulnerability with crafted CSS strings - CVE-2023-48631
### Fixed
- Fix parsing issues with `:is()` and nested `:nth-child()` selectors (#211)
## [4.3.1] - 2023-03-14
### Security
- Fix ReDoS vulnerability with crafted CSS strings - CVE-2023-26364
## [4.3.0] - 2023-03-07
### Changed
- Update build toolchain and dependencies
- Update package exports configuration and file structure
## [4.2.0] - 2023-02-21
### Added
- Add support for CSS `@container` at-rule
- Add support for CSS `@layer` at-rule
## [4.1.0] - 2023-01-25
### Added
- Add support for ES Modules (ESM)
## [4.0.2] - 2023-01-12
### Fixed
- Fix `@import` parsing when URL contains semicolons (#71)
- Fix regression in selector parsing for attribute selectors (#77)
## [4.0.1] - 2022-08-03
### Fixed
- Fix `globalThis` configuration for webpack to enable UMD module usage in Node.js environments
## [4.0.0] - 2022-06-09
### Changed
- Fork from original css library to Adobe's `@adobe/css-tools` package
- Convert codebase from JavaScript to TypeScript
- Improve parsing performance by approximately 25%
- Update all dependencies to latest versions
- Remove source map support
---
## Legacy Versions (Pre-Adobe Fork)
## [3.0.0] - 2020-07-01
### Changed
- Bump major version due to major dependency updates and Node.js version requirement changes
## [2.2.1] - 2015-06-17
### Fixed
- Fix parsing of escaped quotes in quoted strings
## [2.2.0] - 2015-02-18
### Added
- Add `parsingErrors` property to list errors when parsing with `silent: true`
- Accept EOL characters and all whitespace characters in at-rules such as `@media`
## [2.1.0] - 2014-08-05
### Added
- Add `inputSourcemaps` option to disable input source map processing
- Add `sourcemap: 'generator'` option to return the `SourceMapGenerator` object
- Use `inherits` package for inheritance (fixes browser compatibility issues)
### Changed
- Change error message format and add `.reason` property to error objects
## [2.0.0] - 2014-06-18
### Added
- Add non-enumerable parent reference to each AST node
- Add support for `@custom-media`, `@host`, and `@font-face` at-rules
- Allow commas inside selector functions
- Allow empty property values
- Add `node.position.content` property
- Integrate css-parse and css-stringify libraries
- Apply original source maps from source files
### Changed
- Change default `options.position` value to `true`
- Remove comments from properties and values
### Removed
- Drop Component(1) support
### Fixed
- Fix assertion errors when selectors are missing
## [1.6.1] - 2014-01-02
### Fixed
- Fix component.json configuration
## [1.6.0] - 2013-12-21
### Changed
- Update dependencies
## [1.5.0] - 2013-12-03
### Changed
- Update dependencies
## [1.1.0] - 2013-04-04
### Changed
- Update dependencies
## [1.0.7] - 2012-11-21
### Fixed
- Fix component.json configuration
## [1.0.4] - 2012-11-15
### Changed
- Update css-stringify dependency
## [1.0.3] - 2012-09-01
### Added
- Add Component support
## [0.0.1] - 2010-01-03
### Added
- Initial release
+450
View File
@@ -0,0 +1,450 @@
# Usage Examples
## Basic Usage
### Parsing CSS
```javascript
import { parse } from '@adobe/css-tools';
// Basic CSS parsing
const css = `
body {
font-size: 12px;
color: #333;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
`;
const ast = parse(css);
console.log(ast);
```
### Stringifying AST
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = 'body { font-size: 12px; color: #333; }';
const ast = parse(css);
// Convert back to CSS
const output = stringify(ast);
console.log(output); // "body { font-size: 12px; color: #333; }"
```
## Advanced Parsing Options
### Source Tracking
```javascript
import { parse } from '@adobe/css-tools';
const css = 'body { color: red; }';
const ast = parse(css, { source: 'styles.css' });
// Position information is available
const rule = ast.stylesheet.rules[0];
console.log(rule.position?.source); // "styles.css"
console.log(rule.position?.start); // { line: 1, column: 1 }
console.log(rule.position?.end); // { line: 1, column: 20 }
```
### Silent Error Handling
```javascript
import { parse } from '@adobe/css-tools';
const malformedCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
`;
// Parse with silent error handling
const result = parse(malformedCss, { silent: true });
// Check for parsing errors
if (result.stylesheet.parsingErrors) {
console.log('Parsing errors:', result.stylesheet.parsingErrors.length);
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error at line ${error.line}: ${error.message}`);
});
}
// Valid rules are still parsed
console.log('Valid rules:', result.stylesheet.rules.length);
```
## AST Structure Examples
### Basic Rule
```javascript
import { parse } from '@adobe/css-tools';
const css = `
.header {
background: #f0f0f0;
padding: 20px;
border-bottom: 1px solid #ccc;
}
`;
const ast = parse(css);
const rule = ast.stylesheet.rules[0];
console.log(rule.type); // "rule"
console.log(rule.selectors); // [".header"]
console.log(rule.declarations.length); // 3
rule.declarations.forEach(decl => {
console.log(`${decl.property}: ${decl.value}`);
});
// Output:
// background: #f0f0f0
// padding: 20px
// border-bottom: 1px solid #ccc
```
### Media Queries
```javascript
import { parse } from '@adobe/css-tools';
const css = `
@media screen and (max-width: 768px) {
.container {
padding: 10px;
}
.sidebar {
display: none;
}
}
`;
const ast = parse(css);
const mediaRule = ast.stylesheet.rules[0];
console.log(mediaRule.type); // "media"
console.log(mediaRule.media); // "screen and (max-width: 768px)"
console.log(mediaRule.rules.length); // 2
```
### Keyframes
```javascript
import { parse } from '@adobe/css-tools';
const css = `
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`;
const ast = parse(css);
const keyframesRule = ast.stylesheet.rules[0];
console.log(keyframesRule.type); // "keyframes"
console.log(keyframesRule.name); // "fadeIn"
console.log(keyframesRule.keyframes.length); // 2
keyframesRule.keyframes.forEach(keyframe => {
console.log(`Keyframe: ${keyframe.values.join(', ')}`);
keyframe.declarations.forEach(decl => {
console.log(` ${decl.property}: ${decl.value}`);
});
});
```
### Comments
```javascript
import { parse } from '@adobe/css-tools';
const css = `
/* Header styles */
.header {
background: red; /* Fallback color */
}
/* Footer styles */
.footer {
background: blue;
}
`;
const ast = parse(css);
ast.stylesheet.rules.forEach(rule => {
if (rule.type === 'comment') {
console.log(`Comment: ${rule.comment}`);
} else if (rule.type === 'rule') {
console.log(`Rule: ${rule.selectors.join(', ')}`);
rule.declarations.forEach(decl => {
if (decl.type === 'comment') {
console.log(` Comment: ${decl.comment}`);
} else {
console.log(` ${decl.property}: ${decl.value}`);
}
});
}
});
```
## Stringifying Options
### Compressed Output
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
`;
const ast = parse(css);
// Compressed output
const compressed = stringify(ast, { compress: true });
console.log(compressed);
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}"
```
### Custom Indentation
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = 'body { font-size: 12px; color: #333; }';
const ast = parse(css);
// Custom indentation
const formatted = stringify(ast, { indent: ' ' });
console.log(formatted);
// Output:
// body {
// font-size: 12px;
// color: #333;
// }
```
## Working with Complex CSS
### Nested Rules and At-Rules
```javascript
import { parse, stringify } from '@adobe/css-tools';
const complexCss = `
@import url('https://fonts.googleapis.com/css2?family=Roboto');
@charset "UTF-8";
@media print {
body {
font-size: 12pt;
}
}
@supports (display: grid) {
.grid {
display: grid;
}
}
@keyframes slideIn {
0% { transform: translateX(-100%); }
100% { transform: translateX(0); }
}
@font-face {
font-family: 'CustomFont';
src: url('custom-font.woff2') format('woff2');
}
`;
const ast = parse(complexCss);
ast.stylesheet.rules.forEach(rule => {
switch (rule.type) {
case 'import':
console.log(`Import: ${rule.import}`);
break;
case 'charset':
console.log(`Charset: ${rule.charset}`);
break;
case 'media':
console.log(`Media query: ${rule.media}`);
break;
case 'supports':
console.log(`Supports: ${rule.supports}`);
break;
case 'keyframes':
console.log(`Keyframes: ${rule.name}`);
break;
case 'font-face':
console.log('Font-face rule');
break;
}
});
```
### Manipulating the AST
```javascript
import { parse, stringify } from '@adobe/css-tools';
const css = `
.button {
background: blue;
color: white;
padding: 10px;
}
`;
const ast = parse(css);
const rule = ast.stylesheet.rules[0];
// Add a new declaration
rule.declarations.push({
type: 'declaration',
property: 'border-radius',
value: '5px'
});
// Modify existing declaration
const backgroundDecl = rule.declarations.find(d => d.property === 'background');
if (backgroundDecl) {
backgroundDecl.value = 'red';
}
// Add a new selector
rule.selectors.push('.btn');
const modifiedCss = stringify(ast);
console.log(modifiedCss);
```
## Error Handling
### Catching Parse Errors
```javascript
import { parse, CssParseError } from '@adobe/css-tools';
try {
const ast = parse('body { color: red; } { invalid }');
} catch (error) {
if (error instanceof CssParseError) {
console.log(`Parse error at line ${error.line}, column ${error.column}:`);
console.log(error.message);
console.log(`Source: ${error.filename}`);
}
}
```
### Working with Silent Errors
```javascript
import { parse } from '@adobe/css-tools';
const problematicCss = `
body { color: red; }
{ color: blue; } /* Missing selector */
.valid { background: green; }
.another { border: 1px solid; } /* Missing closing brace */
`;
const result = parse(problematicCss, {
silent: true,
source: 'problematic.css'
});
// Process valid rules
const validRules = result.stylesheet.rules.filter(rule => rule.type === 'rule');
console.log(`Found ${validRules.length} valid rules`);
// Log errors for debugging
if (result.stylesheet.parsingErrors) {
result.stylesheet.parsingErrors.forEach(error => {
console.log(`Error: ${error.message} at line ${error.line}`);
});
}
```
### CSS Minification
```javascript
import { parse, stringify } from '@adobe/css-tools';
function minifyCSS(css) {
const ast = parse(css);
return stringify(ast, { compress: true });
}
const css = `
body {
font-size: 12px;
color: #333;
margin: 0;
padding: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
`;
const minified = minifyCSS(css);
console.log(minified);
// Output: "body{font-size:12px;color:#333;margin:0;padding:0}.container{max-width:1200px;margin:0 auto}"
```
### CSS Validation
```javascript
import { parse } from '@adobe/css-tools';
function validateCSS(css, filename = 'unknown') {
try {
const ast = parse(css, { source: filename });
return {
valid: true,
rules: ast.stylesheet.rules.length,
errors: []
};
} catch (error) {
return {
valid: false,
rules: 0,
errors: [{
message: error.message,
line: error.line,
column: error.column,
source: error.filename
}]
};
}
}
const result = validateCSS('body { color: red; } { invalid }', 'test.css');
console.log(result);
```
+83
View File
@@ -0,0 +1,83 @@
{
"name": "@adobe/css-tools",
"version": "4.5.0",
"description": "A modern CSS parser and stringifier with TypeScript support",
"source": "src/index.ts",
"main": "./dist/cjs/adobe-css-tools.cjs",
"module": "./dist/esm/adobe-css-tools.mjs",
"browser": "./dist/umd/adobe-css-tools.js",
"sideEffects": false,
"exports": {
".": {
"import": "./dist/esm/adobe-css-tools.mjs",
"require": "./dist/cjs/adobe-css-tools.cjs"
},
"./package.json": "./package.json"
},
"types": "./dist/esm/adobe-css-tools.d.mts",
"type": "module",
"files": [
"dist/cjs",
"dist/esm",
"dist/umd",
"src",
"README.md",
"docs/"
],
"devDependencies": {
"@arethetypeswrong/cli": "^0.18.2",
"@biomejs/biome": "^2.1.2",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^1.0.0",
"@rollup/plugin-typescript": "^12.1.4",
"@types/benchmark": "^2.1.1",
"@types/bytes": "^3.1.5",
"@types/jest": "^30.0.0",
"@types/node": "^25.0.3",
"benchmark": "^2.1.4",
"bytes": "^3.1.0",
"jest": "^30.0.5",
"rollup": "^4.45.1",
"rollup-plugin-dts": "^6.2.1",
"ts-jest": "^29.4.10",
"tslib": "^2.8.1",
"typescript": "^6.0.2"
},
"scripts": {
"benchmark": "npm run build && node benchmark/index.mjs",
"test": "jest",
"clean": "rm -rf ./dist",
"build": "rollup -c",
"fix": "biome check --write",
"check-package-bundle": "attw --pack .",
"lint": "biome check",
"prebuild": "npm run clean",
"prepack": "rollup -c",
"posttest": "npm run lint",
"postbuild": "tar -czf dist/archive.tgz LICENSE README.md dist/cjs dist/esm dist/umd docs package.json && npx attw --format ascii dist/archive.tgz && rm dist/archive.tgz"
},
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Jean-Philippe Zolesio <holblin@gmail.com>"
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/adobe/css-tools.git"
},
"keywords": [
"css",
"parser",
"stringifier",
"stylesheet",
"ast",
"typescript",
"css-parser",
"css-ast",
"css-tools",
"minify",
"format",
"preprocessor"
]
}
+22
View File
@@ -0,0 +1,22 @@
export default class CssParseError extends Error {
readonly reason: string;
readonly filename?: string;
readonly line: number;
readonly column: number;
readonly source: string;
constructor(
filename: string,
msg: string,
lineno: number,
column: number,
css: string,
) {
super(`${filename}:${lineno}:${column}: ${msg}`);
this.reason = msg;
this.filename = filename;
this.line = lineno;
this.column = column;
this.source = css;
}
}
+18
View File
@@ -0,0 +1,18 @@
/**
* Store position information for a node
*/
export default class Position {
start: { line: number; column: number };
end: { line: number; column: number };
source?: string;
constructor(
start: { line: number; column: number },
end: { line: number; column: number },
source: string,
) {
this.start = start;
this.end = end;
this.source = source;
}
}
+8
View File
@@ -0,0 +1,8 @@
import { default as parseFn } from './parse';
import { default as stringifyFn } from './stringify';
export const parse = parseFn;
export const stringify = stringifyFn;
export * from './CssParseError';
export * from './CssPosition';
export * from './type';
export default { parse, stringify };
File diff suppressed because it is too large. Load diff
+698
View File
@@ -0,0 +1,698 @@
import {
type CssAllNodesAST,
type CssCharsetAST,
type CssCommentAST,
type CssCommonPositionAST,
type CssContainerAST,
type CssCounterStyleAST,
type CssCustomMediaAST,
type CssDeclarationAST,
type CssDocumentAST,
type CssFontFaceAST,
type CssFontFeatureValuesAST,
type CssGenericAtRuleAST,
type CssHostAST,
type CssImportAST,
type CssKeyframeAST,
type CssKeyframesAST,
type CssLayerAST,
type CssMediaAST,
type CssNamespaceAST,
type CssPageAST,
type CssPageMarginBoxAST,
type CssPositionTryAST,
type CssPropertyAST,
type CssRuleAST,
type CssScopeAST,
type CssStartingStyleAST,
type CssStylesheetAST,
type CssSupportsAST,
CssTypes,
type CssViewTransitionAST,
} from '../type';
export type CompilerOptions = {
indent?: string;
compress?: boolean;
};
class Compiler {
level = 0;
indentation = ' ';
compress = false;
constructor(options?: CompilerOptions) {
if (typeof options?.indent === 'string') {
this.indentation = options?.indent;
}
if (options?.compress) {
this.compress = true;
}
}
// We disable no-unused-vars for _position. We keep position for potential reintroduction of source-map
// eslint-disable-next-line @typescript-eslint/no-unused-vars
emit(str: string, _position?: CssCommonPositionAST['position']) {
return str;
}
/**
* Increase, decrease or return current indentation.
*/
indent(level?: number) {
this.level = this.level || 1;
if (level) {
this.level += level;
return '';
}
return Array(this.level).join(this.indentation);
}
visit(node: CssAllNodesAST): string {
switch (node.type) {
case CssTypes.stylesheet:
return this.stylesheet(node);
case CssTypes.rule:
return this.rule(node);
case CssTypes.declaration:
return this.declaration(node);
case CssTypes.comment:
return this.comment(node);
case CssTypes.container:
return this.container(node);
case CssTypes.charset:
return this.charset(node);
case CssTypes.counterStyle:
return this.counterStyle(node);
case CssTypes.document:
return this.document(node);
case CssTypes.customMedia:
return this.customMedia(node);
case CssTypes.fontFace:
return this.fontFace(node);
case CssTypes.fontFeatureValues:
return this.fontFeatureValues(node);
case CssTypes.host:
return this.host(node);
case CssTypes.import:
return this.import(node);
case CssTypes.keyframes:
return this.keyframes(node);
case CssTypes.keyframe:
return this.keyframe(node);
case CssTypes.layer:
return this.layer(node);
case CssTypes.media:
return this.media(node);
case CssTypes.namespace:
return this.namespace(node);
case CssTypes.page:
return this.page(node);
case CssTypes.pageMarginBox:
return this.pageMarginBox(node);
case CssTypes.positionTry:
return this.positionTry(node);
case CssTypes.property:
return this.property(node);
case CssTypes.scope:
return this.scope(node);
case CssTypes.startingStyle:
return this.startingStyle(node);
case CssTypes.supports:
return this.supports(node);
case CssTypes.viewTransition:
return this.viewTransition(node);
case CssTypes.atRule:
return this.genericAtRule(node);
}
}
mapVisit(nodes: Array<CssAllNodesAST>, delim?: string) {
let buf = '';
delim = delim || '';
for (let i = 0, length = nodes.length; i < length; i++) {
buf += this.visit(nodes[i]);
if (delim && i < length - 1) {
buf += this.emit(delim);
}
}
return buf;
}
compile(node: CssStylesheetAST) {
if (this.compress) {
return node.stylesheet.rules.map(this.visit, this).join('');
}
return this.stylesheet(node);
}
/**
* Visit stylesheet node.
*/
stylesheet(node: CssStylesheetAST) {
return this.mapVisit(node.stylesheet.rules, '\n\n');
}
/**
* Visit comment node.
*/
comment(node: CssCommentAST) {
if (this.compress) {
return this.emit('', node.position);
}
return this.emit(`${this.indent()}/*${node.comment}*/`, node.position);
}
/**
* Visit container node.
*/
container(node: CssContainerAST) {
if (this.compress) {
return (
this.emit(`@container ${node.container}`, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@container ${node.container}`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit container node.
*/
layer(node: CssLayerAST) {
if (this.compress) {
return (
this.emit(`@layer ${node.layer}`, node.position) +
(node.rules
? this.emit('{') +
this.mapVisit(<CssAllNodesAST[]>node.rules) +
this.emit('}')
: ';')
);
}
return (
this.emit(`${this.indent()}@layer ${node.layer}`, node.position) +
(node.rules
? this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(<CssAllNodesAST[]>node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
: ';')
);
}
/**
* Visit import node.
*/
import(node: CssImportAST) {
return this.emit(`@import ${node.import};`, node.position);
}
/**
* Visit media node.
*/
media(node: CssMediaAST) {
if (this.compress) {
return (
this.emit(`@media ${node.media}`, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@media ${node.media}`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit document node.
*/
document(node: CssDocumentAST) {
const doc = `@${node.vendor || ''}document ${node.document}`;
if (this.compress) {
return (
this.emit(doc, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(doc, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`${this.indent(-1)}\n}`)
);
}
/**
* Visit charset node.
*/
charset(node: CssCharsetAST) {
return this.emit(`@charset ${node.charset};`, node.position);
}
/**
* Visit namespace node.
*/
namespace(node: CssNamespaceAST) {
return this.emit(`@namespace ${node.namespace};`, node.position);
}
/**
* Visit container node.
*/
startingStyle(node: CssStartingStyleAST) {
if (this.compress) {
return (
this.emit('@starting-style', node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@starting-style`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit supports node.
*/
supports(node: CssSupportsAST) {
if (this.compress) {
return (
this.emit(`@supports ${node.supports}`, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@supports ${node.supports}`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit keyframes node.
*/
keyframes(node: CssKeyframesAST) {
if (this.compress) {
return (
this.emit(
`@${node.vendor || ''}keyframes ${node.name}`,
node.position,
) +
this.emit('{') +
this.mapVisit(node.keyframes) +
this.emit('}')
);
}
return (
this.emit(`@${node.vendor || ''}keyframes ${node.name}`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.keyframes, '\n') +
this.emit(`${this.indent(-1)}}`)
);
}
/**
* Visit keyframe node.
*/
keyframe(node: CssKeyframeAST) {
const decls = node.declarations;
if (this.compress) {
return (
this.emit(node.values.join(','), node.position) +
this.emit('{') +
this.mapVisit(decls) +
this.emit('}')
);
}
return (
this.emit(this.indent()) +
this.emit(node.values.join(', '), node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(decls, '\n') +
this.emit(`${this.indent(-1)}\n${this.indent()}}\n`)
);
}
/**
* Visit page node.
*/
page(node: CssPageAST) {
if (this.compress) {
const sel = node.selectors.length ? node.selectors.join(', ') : '';
return (
this.emit(`@page ${sel}`, node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
const sel = node.selectors.length ? `${node.selectors.join(', ')} ` : '';
return (
this.emit(`@page ${sel}`, node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit @page margin box node (@top-left, @bottom-right, etc.).
*/
pageMarginBox(node: CssPageMarginBoxAST) {
if (this.compress) {
return (
this.emit(`@${node.name}`, node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@${node.name} `, node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit(`\n${this.indent()}}`)
);
}
/**
* Visit font-face node.
*/
fontFace(node: CssFontFaceAST) {
if (this.compress) {
return (
this.emit('@font-face', node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit('@font-face ', node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit host node.
*/
host(node: CssHostAST) {
if (this.compress) {
return (
this.emit('@host', node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit('@host', node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`${this.indent(-1)}\n}`)
);
}
/**
* Visit custom-media node.
*/
customMedia(node: CssCustomMediaAST) {
return this.emit(
`@custom-media ${node.name} ${node.media};`,
node.position,
);
}
/**
* Visit @property node.
*/
property(node: CssPropertyAST) {
if (this.compress) {
return (
this.emit(`@property ${node.name}`, node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit(`@property ${node.name} `, node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit @counter-style node.
*/
counterStyle(node: CssCounterStyleAST) {
if (this.compress) {
return (
this.emit(`@counter-style ${node.name}`, node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit(`@counter-style ${node.name} `, node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit @font-feature-values node.
*/
fontFeatureValues(node: CssFontFeatureValuesAST) {
if (this.compress) {
return (
this.emit(`@font-feature-values ${node.fontFamily}`, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(
`${this.indent()}@font-feature-values ${node.fontFamily}`,
node.position,
) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit @scope node.
*/
scope(node: CssScopeAST) {
const prelude = node.scope ? ` ${node.scope}` : '';
if (this.compress) {
return (
this.emit(`@scope${prelude}`, node.position) +
this.emit('{') +
this.mapVisit(node.rules) +
this.emit('}')
);
}
return (
this.emit(`${this.indent()}@scope${prelude}`, node.position) +
this.emit(` {\n${this.indent(1)}`) +
this.mapVisit(node.rules, '\n\n') +
this.emit(`\n${this.indent(-1)}${this.indent()}}`)
);
}
/**
* Visit @view-transition node.
*/
viewTransition(node: CssViewTransitionAST) {
if (this.compress) {
return (
this.emit('@view-transition', node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit('@view-transition ', node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit @position-try node.
*/
positionTry(node: CssPositionTryAST) {
if (this.compress) {
return (
this.emit(`@position-try ${node.name}`, node.position) +
this.emit('{') +
this.mapVisit(node.declarations) +
this.emit('}')
);
}
return (
this.emit(`@position-try ${node.name} `, node.position) +
this.emit('{\n') +
this.emit(this.indent(1)) +
this.mapVisit(node.declarations, '\n') +
this.emit(this.indent(-1)) +
this.emit('\n}')
);
}
/**
* Visit generic at-rule node (fallback for any unrecognized at-rule).
*/
genericAtRule(node: CssGenericAtRuleAST) {
const prelude = node.prelude ? ` ${node.prelude}` : '';
if (this.compress) {
return (
this.emit(`@${node.name}${prelude}`, node.position) +
(node.rules
? this.emit('{') +
this.mapVisit(<CssAllNodesAST[]>node.rules) +
this.emit('}')
: ';')
);
}
if (!node.rules) {
return this.emit(
`${this.indent()}@${node.name}${prelude};`,
node.position,
);
}
const hasNestedRules = node.rules.some(
(r) => r.type !== CssTypes.declaration && r.type !== CssTypes.comment,
);
const delim = hasNestedRules ? '\n\n' : '\n';
return (
this.emit(`${this.indent()}@${node.name}${prelude}`, node.position) +
this.emit(hasNestedRules ? ` {\n${this.indent(1)}` : ' {\n') +
this.emit(hasNestedRules ? '' : this.indent(1)) +
this.mapVisit(<CssAllNodesAST[]>node.rules, delim) +
this.emit(
hasNestedRules
? `\n${this.indent(-1)}${this.indent()}}`
: `${this.indent(-1)}\n${this.indent()}}`,
)
);
}
/**
* Visit rule node.
*/
rule(node: CssRuleAST) {
const decls = node.declarations;
if (!decls.length) {
return '';
}
if (this.compress) {
return (
this.emit(node.selectors.join(','), node.position) +
this.emit('{') +
this.mapVisit(decls) +
this.emit('}')
);
}
const indent = this.indent();
return (
this.emit(
node.selectors
.map((s) => {
return indent + s;
})
.join(',\n'),
node.position,
) +
this.emit(' {\n') +
this.emit(this.indent(1)) +
this.mapVisit(decls, '\n') +
this.emit(this.indent(-1)) +
this.emit(`\n${this.indent()}}`)
);
}
/**
* Visit declaration node.
*/
declaration(node: CssDeclarationAST) {
if (this.compress) {
return (
this.emit(`${node.property}:${node.value}`, node.position) +
this.emit(';')
);
}
if (node.property === 'grid-template-areas')
return (
this.emit(this.indent()) +
this.emit(
node.property +
': ' +
node.value.split('\n').join('\n'.padEnd(22) + this.indent()),
node.position,
) +
this.emit(';')
);
return (
this.emit(this.indent()) +
this.emit(`${node.property}: ${node.value}`, node.position) +
this.emit(';')
);
}
}
export default Compiler;
+7
View File
@@ -0,0 +1,7 @@
import type { CssStylesheetAST } from '../type';
import Compiler, { type CompilerOptions } from './compiler';
export default (node: CssStylesheetAST, options?: CompilerOptions) => {
const compiler = new Compiler(options || {});
return compiler.compile(node);
};
+213
View File
@@ -0,0 +1,213 @@
import type CssParseError from './CssParseError';
import type Position from './CssPosition';
export enum CssTypes {
stylesheet = 'stylesheet',
rule = 'rule',
declaration = 'declaration',
comment = 'comment',
atRule = 'at-rule',
container = 'container',
charset = 'charset',
counterStyle = 'counter-style',
document = 'document',
customMedia = 'custom-media',
fontFace = 'font-face',
fontFeatureValues = 'font-feature-values',
host = 'host',
import = 'import',
keyframes = 'keyframes',
keyframe = 'keyframe',
layer = 'layer',
media = 'media',
namespace = 'namespace',
page = 'page',
pageMarginBox = 'page-margin-box',
positionTry = 'position-try',
property = 'property',
scope = 'scope',
startingStyle = 'starting-style',
supports = 'supports',
viewTransition = 'view-transition',
}
export type CssCommonAST = {
type: CssTypes;
};
export type CssCommonPositionAST = CssCommonAST & {
position?: Position;
parent?: unknown;
};
export type CssStylesheetAST = CssCommonAST & {
type: CssTypes.stylesheet;
stylesheet: {
source?: string;
rules: Array<CssAtRuleAST>;
parsingErrors?: Array<CssParseError>;
};
};
export type CssRuleAST = CssCommonPositionAST & {
type: CssTypes.rule;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
export type CssDeclarationAST = CssCommonPositionAST & {
type: CssTypes.declaration;
property: string;
value: string;
};
export type CssCommentAST = CssCommonPositionAST & {
type: CssTypes.comment;
comment: string;
};
export type CssContainerAST = CssCommonPositionAST & {
type: CssTypes.container;
container: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssCharsetAST = CssCommonPositionAST & {
type: CssTypes.charset;
charset: string;
};
export type CssCustomMediaAST = CssCommonPositionAST & {
type: CssTypes.customMedia;
name: string;
media: string;
};
export type CssDocumentAST = CssCommonPositionAST & {
type: CssTypes.document;
document: string;
vendor?: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssFontFaceAST = CssCommonPositionAST & {
type: CssTypes.fontFace;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssHostAST = CssCommonPositionAST & {
type: CssTypes.host;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssImportAST = CssCommonPositionAST & {
type: CssTypes.import;
import: string;
};
export type CssKeyframesAST = CssCommonPositionAST & {
type: CssTypes.keyframes;
name: string;
vendor?: string;
keyframes: Array<CssKeyframeAST | CssCommentAST>;
};
export type CssKeyframeAST = CssCommonPositionAST & {
type: CssTypes.keyframe;
values: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssLayerAST = CssCommonPositionAST & {
type: CssTypes.layer;
layer: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssMediaAST = CssCommonPositionAST & {
type: CssTypes.media;
media: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssNamespaceAST = CssCommonPositionAST & {
type: CssTypes.namespace;
namespace: string;
};
export type CssPageAST = CssCommonPositionAST & {
type: CssTypes.page;
selectors: Array<string>;
declarations: Array<CssDeclarationAST | CssCommentAST | CssAtRuleAST>;
};
export type CssSupportsAST = CssCommonPositionAST & {
type: CssTypes.supports;
supports: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssStartingStyleAST = CssCommonPositionAST & {
type: CssTypes.startingStyle;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssCounterStyleAST = CssCommonPositionAST & {
type: CssTypes.counterStyle;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssFontFeatureValuesAST = CssCommonPositionAST & {
type: CssTypes.fontFeatureValues;
fontFamily: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssPositionTryAST = CssCommonPositionAST & {
type: CssTypes.positionTry;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssPropertyAST = CssCommonPositionAST & {
type: CssTypes.property;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssScopeAST = CssCommonPositionAST & {
type: CssTypes.scope;
scope: string;
rules: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssViewTransitionAST = CssCommonPositionAST & {
type: CssTypes.viewTransition;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssPageMarginBoxAST = CssCommonPositionAST & {
type: CssTypes.pageMarginBox;
name: string;
declarations: Array<CssDeclarationAST | CssCommentAST>;
};
export type CssGenericAtRuleAST = CssCommonPositionAST & {
type: CssTypes.atRule;
name: string;
prelude: string;
rules?: Array<CssAtRuleAST | CssDeclarationAST>;
};
export type CssAtRuleAST =
| CssRuleAST
| CssCommentAST
| CssContainerAST
| CssCharsetAST
| CssCounterStyleAST
| CssCustomMediaAST
| CssDocumentAST
| CssFontFaceAST
| CssFontFeatureValuesAST
| CssHostAST
| CssImportAST
| CssKeyframesAST
| CssLayerAST
| CssMediaAST
| CssNamespaceAST
| CssPageAST
| CssPageMarginBoxAST
| CssPositionTryAST
| CssPropertyAST
| CssScopeAST
| CssSupportsAST
| CssStartingStyleAST
| CssViewTransitionAST
| CssGenericAtRuleAST;
export type CssAllNodesAST =
| CssAtRuleAST
| CssStylesheetAST
| CssDeclarationAST
| CssKeyframeAST;
+139
View File
@@ -0,0 +1,139 @@
import {
indexOfArrayNonEscaped,
indexOfArrayWithBracketAndQuoteSupport,
MAX_LOOP,
splitWithBracketAndQuoteSupport,
} from './stringSearch';
describe('indexOfArrayNonEscaped', () => {
it('should find first non-escaped occurrence', () => {
expect(indexOfArrayNonEscaped('abc def', ['d'])).toBe(4);
expect(indexOfArrayNonEscaped('abc \\def ghi def', ['d'])).toBe(13);
});
it('should handle multiple search strings', () => {
expect(indexOfArrayNonEscaped('abc def ghi', ['d', 'g'])).toBe(4);
expect(indexOfArrayNonEscaped('abc ghi def', ['d', 'g'])).toBe(4);
});
it('should return -1 when not found', () => {
expect(indexOfArrayNonEscaped('abc def', ['x'])).toBe(-1);
expect(indexOfArrayNonEscaped('abc \\xyz def', ['x'])).toBe(-1);
});
it('should respect start position', () => {
expect(indexOfArrayNonEscaped('abc def def', ['def'], 5)).toBe(8);
});
it('should throw error on too many escapes', () => {
const tooManyEscapes = '\\a\\b\\c\\d'.repeat(MAX_LOOP / 2);
expect(() => indexOfArrayNonEscaped(tooManyEscapes, ['x'])).toThrow(
'Too many escaping',
);
});
});
describe('indexOfArrayWithBracketAndQuoteSupport', () => {
it('should find first non-escaped occurrence', () => {
expect(indexOfArrayWithBracketAndQuoteSupport('abc def', ['d'])).toBe(4);
expect(
indexOfArrayWithBracketAndQuoteSupport('abc \\def ghi def', ['d']),
).toBe(13);
});
it('should handle brackets correctly', () => {
expect(indexOfArrayWithBracketAndQuoteSupport('abc (def) ghi', ['g'])).toBe(
10,
);
expect(
indexOfArrayWithBracketAndQuoteSupport('abc (d(e)f) ghi', ['g']),
).toBe(12);
expect(indexOfArrayWithBracketAndQuoteSupport('abc (def ghi', ['g'])).toBe(
-1,
);
});
it('should handle double quotes correctly', () => {
expect(indexOfArrayWithBracketAndQuoteSupport('abc "def" ghi', ['g'])).toBe(
10,
);
expect(
indexOfArrayWithBracketAndQuoteSupport('abc "d\\"ef" ghi', ['g']),
).toBe(12);
expect(indexOfArrayWithBracketAndQuoteSupport('abc "def ghi', ['g'])).toBe(
-1,
);
});
it('should handle single quotes correctly', () => {
expect(indexOfArrayWithBracketAndQuoteSupport("abc 'def' ghi", ['g'])).toBe(
10,
);
expect(
indexOfArrayWithBracketAndQuoteSupport("abc 'd\\'ef' ghi", ['g']),
).toBe(12);
expect(indexOfArrayWithBracketAndQuoteSupport("abc 'def ghi", ['g'])).toBe(
-1,
);
});
it('should handle multiple search strings', () => {
expect(
indexOfArrayWithBracketAndQuoteSupport('abc def ghi', ['d', 'g']),
).toBe(4);
expect(
indexOfArrayWithBracketAndQuoteSupport('abc (def) ghi', ['d', 'g']),
).toBe(10);
});
it('should throw error on too many escapes or nested structures', () => {
const tooManyEscapes = '\\a\\b\\c\\d'.repeat(MAX_LOOP / 2);
expect(() =>
indexOfArrayWithBracketAndQuoteSupport(tooManyEscapes, ['x']),
).toThrow('Too many escaping');
const tooManyBrackets = '()'.repeat(MAX_LOOP + 1);
expect(() =>
indexOfArrayWithBracketAndQuoteSupport(tooManyBrackets, [')']),
).toThrow('Too many escaping');
});
});
describe('splitWithBracketAndQuoteSupport', () => {
test('splits string by search tokens', () => {
expect(splitWithBracketAndQuoteSupport('a,b', [','])).toEqual(['a', 'b']);
});
test('respects brackets', () => {
expect(splitWithBracketAndQuoteSupport('a,(b,c)', [','])).toEqual([
'a',
'(b,c)',
]);
});
test('respects double quotes', () => {
expect(splitWithBracketAndQuoteSupport('a,"b,c"', [','])).toEqual([
'a',
'"b,c"',
]);
});
test('respects single quotes', () => {
expect(splitWithBracketAndQuoteSupport("a,'b,c'", [','])).toEqual([
'a',
"'b,c'",
]);
});
test('handles multiple search tokens', () => {
expect(splitWithBracketAndQuoteSupport('a;b,c', [';', ','])).toEqual([
'a',
'b',
'c',
]);
});
test('handles empty strings', () => {
expect(splitWithBracketAndQuoteSupport('', [','])).toEqual([]);
});
});
+174
View File
@@ -0,0 +1,174 @@
export const MAX_LOOP = 10000;
/**
* Find the first occurrence of any search string in the input string, ignoring escaped characters
* @param string - The input string to search in
* @param search - Array of strings to search for
* @param position - Optional starting position for the search
* @returns The index of the first match, or -1 if not found
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
* @example
* ```ts
* // Basic search
* indexOfArrayNonEscaped('a,b,c', [',']) // 1
*
* // Handles escaped characters
* indexOfArrayNonEscaped('a\\,b,c', [',']) // 4, the first comma is escaped
* ```
*/
export const indexOfArrayNonEscaped = (
string: string,
search: Array<string>,
position?: number,
): number => {
let currentPosition = position;
let maxLoop = MAX_LOOP;
do {
const all = search.map((v) => string.indexOf(v, currentPosition));
all.push(string.indexOf('\\', currentPosition));
const foundAll = all.filter((v) => v !== -1);
if (foundAll.length === 0) {
return -1;
}
const found = Math.min(...foundAll);
if (string[found] === '\\') {
currentPosition = found + 2;
maxLoop--;
} else {
return found;
}
} while (maxLoop > 0);
throw new Error('Too many escaping');
};
/**
* Find the first occurrence of any search string in the input string, respecting brackets and quotes
* @param string - The input string to search in
* @param search - Array of strings to search for
* @param position - Optional starting position for the search
* @returns The index of the first match, or -1 if not found
* @throws {Error} If too many escape sequences are encountered (> MAX_LOOP)
* @example
* ```ts
* // Basic search
* indexOfArrayWithBracketAndQuoteSupport('a,b,c', [',']) // 1
*
* // Respects brackets - won't match inside ()
* indexOfArrayWithBracketAndQuoteSupport('(a,b),c', [',']) // 4, ignores the comma inside ()
*
* // Respects quotes - won't match inside quotes
* indexOfArrayWithBracketAndQuoteSupport('"a,b",c', [',']) // 4, ignores the comma inside quotes
* indexOfArrayWithBracketAndQuoteSupport("'a,b',c", [',']) // 4, ignores the comma inside quotes
*
* // Handles escaped characters
* indexOfArrayWithBracketAndQuoteSupport('a\\,b,c', [',']) // 4, the first comma is escaped
* ```
*/
export const indexOfArrayWithBracketAndQuoteSupport = (
string: string,
search: Array<string>,
position?: number,
): number => {
let currentSearchPosition = position;
let maxLoop = MAX_LOOP;
do {
const all = search.map((v) => string.indexOf(v, currentSearchPosition));
all.push(string.indexOf('(', currentSearchPosition));
all.push(string.indexOf('"', currentSearchPosition));
all.push(string.indexOf("'", currentSearchPosition));
all.push(string.indexOf('\\', currentSearchPosition));
const foundAll = all.filter((v) => v !== -1);
if (foundAll.length === 0) {
return -1;
}
const firstMatchPos = Math.min(...foundAll);
const char = string[firstMatchPos];
switch (char) {
case '\\':
currentSearchPosition = firstMatchPos + 2;
break;
case '(':
{
const endPosition = indexOfArrayWithBracketAndQuoteSupport(
string,
[')'],
firstMatchPos + 1,
);
if (endPosition === -1) {
return -1;
}
currentSearchPosition = endPosition + 1;
}
break;
case '"':
{
const endQuotePosition = indexOfArrayNonEscaped(
string,
['"'],
firstMatchPos + 1,
);
if (endQuotePosition === -1) {
return -1;
}
currentSearchPosition = endQuotePosition + 1;
}
break;
case "'":
{
const endQuotePosition = indexOfArrayNonEscaped(
string,
["'"],
firstMatchPos + 1,
);
if (endQuotePosition === -1) {
return -1;
}
currentSearchPosition = endQuotePosition + 1;
}
break;
default:
return firstMatchPos;
}
maxLoop--;
} while (maxLoop > 0);
throw new Error('Too many escaping');
};
/**
* Split a string by search tokens, respecting brackets and quotes
* @example
* ```ts
* splitWithBracketAndQuoteSupport('a,b', [',']) // ['a', 'b']
* splitWithBracketAndQuoteSupport('a,(b,c)', [',']) // ['a', '(b,c)']
* splitWithBracketAndQuoteSupport('a,"b,c"', [',']) // ['a', '"b,c"']
* splitWithBracketAndQuoteSupport("a,'b,c'", [',']) // ['a', "'b,c'"]
* ```
*/
export const splitWithBracketAndQuoteSupport = (
string: string,
search: Array<string>,
): Array<string> => {
const result: Array<string> = [];
let currentPosition = 0;
while (currentPosition < string.length) {
const index = indexOfArrayWithBracketAndQuoteSupport(
string,
search,
currentPosition,
);
if (index === -1) {
result.push(string.substring(currentPosition));
return result;
}
result.push(string.substring(currentPosition, index));
currentPosition = index + 1;
}
return result;
};
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 asamuzaK (Kazz)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+128
View File
@@ -0,0 +1,128 @@
# CSS color
[![build](https://github.com/asamuzaK/cssColor/actions/workflows/node.js.yml/badge.svg)](https://github.com/asamuzaK/cssColor/actions/workflows/node.js.yml)
[![CodeQL](https://github.com/asamuzaK/cssColor/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/asamuzaK/cssColor/actions/workflows/github-code-scanning/codeql)
[![npm (scoped)](https://img.shields.io/npm/v/@asamuzakjp/css-color)](https://www.npmjs.com/package/@asamuzakjp/css-color)
A robust and modern library to resolve, parse, and convert CSS colors.
Supports the latest CSS Color Module Level 4 & 5 specifications.
## Features
- **Modern CSS Color Support:** Accurately resolves `color-mix()`, `color()`, modern color spaces (`oklch`, `oklab`, `lch`, `lab`, `hwb`, etc.), and relative colors (`lab(from red l a b)`, `color(from red xyz-d50 x y z)`).
- **Deep Resolution:** Deeply resolves `var()` and `calc()` functions embedded within color values.
- **Gradient Parsing:** Supports parsing and validation for `linear-gradient`, `radial-gradient`, and `conic-gradient`.
- **Comprehensive Color Conversion:** Highly accurate converters between HEX, HSL, HWB, LAB, LCH, Oklab, Oklch, RGB, and XYZ color spaces.
- **Bonus Utilities:** Includes convenient functions to validate colors or gradients, extract CSS variables, and safely split CSS values.
- **Used in jsdom:** Adopted as the CSS color parser and resolver for `jsdom`.
- **Pure ESM with TypeScript Ready:** Native ESM (`type: "module"`) with comprehensive TypeScript definitions.
## Install
```console
npm i @asamuzakjp/css-color
```
## Quick Start
```javascript
import { convert, resolve, utils } from '@asamuzakjp/css-color';
```
### Samples
1. Resolve complex modern CSS colors:
```javascript
const resolvedMix = resolve(
'color-mix(in oklab, lch(67.5345 42.5 258.2), color(srgb 0 0.5 0))'
);
// => 'oklab(0.620754 -0.0931934 -0.00374881)'
```
2. Resolve with Custom Properties and calc():
```javascript
const resolvedVar = resolve('hsl(calc(var(--base-hue) * 3) 100% 50% / .5)', {
customProperty: { '--base-hue': '210deg' }
});
// => 'rgba(128, 0, 255, 0.5)'
```
3. Convert between color spaces:
```javascript
const hex = convert.colorToHex('lab(46.2775% -47.5621 48.5837)');
// => '#008000'
```
4. Validate colors and gradients:
```javascript
const isColor = utils.isColor('light-dark(red, blue)');
// => true
const isGradient = utils.isGradient(
'conic-gradient(from 0.5turn at 50% 50%, red, blue)'
);
// => true
```
## API Reference
### `resolve(color, opt?)`
Resolves a CSS color string into its computed or specified value. System colors are not supported.
- **`color`** `<string>`: The CSS color value to resolve.
- **`opt`** `<object>` _(optional)_:
- `opt.currentColor`: Color to use for the `currentcolor` keyword.
- `opt.customProperty`: Object containing `--` prefixed keys and their values, or a `callback(propertyName)` function to dynamically resolve CSS variables.
- `opt.dimension`: Object mapping units (e.g., `em`, `rem`, `vw`) to pixel numbers, or a `callback(unit)` function for dynamic length resolution.
- `opt.format`: Output format. Options: `computedValue` (default), `specifiedValue`, `hex`, `hexAlpha`.
- `opt.colorScheme`: `normal` (default), `light`, or `dark` (useful for `light-dark()` resolution).
### `convert`
A collection of color conversion utilities.
<!-- prettier-ignore -->
| Function | Returns | Options | Description |
| :-------------- | :-------------- | :-------------- | :-------------- |
| `convert.colorToHex(value, opt?)` | `string \| null` | `opt.alpha` `<boolean>`<br>_(+ see `resolve` options)_ | Returns `#rrggbb` or `#rrggbbaa` (if `opt.alpha` is true). |
| `convert.colorToHsl(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to HSL channels: `[h, s, l, alpha]` |
| `convert.colorToHwb(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to HWB channels: `[h, w, b, alpha]` |
| `convert.colorToLab(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to CIE LAB channels: `[l, a, b, alpha]` |
| `convert.colorToLch(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to CIE LCH channels: `[l, c, h, alpha]` |
| `convert.colorToOklab(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to Oklab channels: `[l, a, b, alpha]` |
| `convert.colorToOklch(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to Oklch channels: `[l, c, h, alpha]` |
| `convert.colorToRgb(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to sRGB channels: `[r, g, b, alpha]` |
| `convert.colorToXyz(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to CIE XYZ channels (defaults to D65): `[x, y, z, alpha]` |
| `convert.colorToXyzD50(value, opt?)` | `number[]` | _See `resolve` options_ | Converts to CIE XYZ channels with D50 white point. |
### `utils`
Helpful internal tools exposed for advanced usage, parsing, and validation.
<!-- prettier-ignore -->
| Function | Returns | Options (`opt`) | Description |
| :-------------- | :-------------- | :-------------- | :-------------- |
| `utils.cssCalc(value, opt?)` | `string` | `opt.dimension`<br>_(+ see `resolve` options)_ | Resolves CSS `calc()` expressions. |
| `utils.cssVar(value, opt?)` | `string` | `opt.customProperty`<br>_(+ see `resolve` options)_ | Resolves CSS `var()` expressions. |
| `utils.extractDashedIdent(value)` | `string[]` | _None_ | Extracts custom property names (dashed-ident tokens) from a value. |
| `utils.isColor(value, opt?)` | `boolean` | _See `resolve` options_ | Returns `true` if the string is a valid CSS color. |
| `utils.isGradient(value, opt?)` | `boolean` | _See `resolve` options_ | Returns `true` if the string is a valid CSS gradient. |
| `utils.resolveGradient(value, opt?)` | `string` | _See `resolve` options_ | Resolves CSS gradient strings. |
| `utils.resolveLengthInPixels(value, unit, opt?)` | `number` | `opt.dimension`<br>_(+ see `resolve` options)_ | Converts an absolute or relative CSS length to pixels. |
| `utils.splitValue(value, opt?)` | `string[]` | `opt.delimiter` `<string>`<br>`opt.preserveComment` `<boolean>` | Safely splits a CSS value by a specified delimiter (` `, `,`, `/`). |
## Acknowledgments
The following resources have been of great help in the development of this library:
- [csstools/postcss-plugins](https://github.com/csstools/postcss-plugins)
- [lru-cache](https://github.com/isaacs/node-lru-cache)
---
Copyright (c) 2024 [asamuzaK (Kazz)](https://github.com/asamuzaK/)
+18
View File
@@ -0,0 +1,18 @@
/*!
* CSS color - Resolve, parse, convert CSS color.
* @license MIT
* @copyright asamuzaK (Kazz)
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
*/
export { convert } from './js/convert.js';
export { resolve } from './js/resolve.js';
export declare const utils: {
cssCalc: (value: string, opt?: import('./js/typedef.js').Options) => string;
cssVar: (value: string, opt?: import('./js/typedef.js').Options) => string;
extractDashedIdent: (value: string) => string[];
isColor: (value: unknown, opt?: import('./js/typedef.js').Options) => boolean;
isGradient: (value: string, opt?: import('./js/typedef.js').Options) => boolean;
resolveGradient: (value: string, opt?: import('./js/typedef.js').Options) => string;
resolveLengthInPixels: (value: number | string, unit: string | undefined, opt?: import('./js/typedef.js').Options) => number;
splitValue: (value: string, opt?: import('./js/typedef.js').Options) => string[];
};
+26
View File
@@ -0,0 +1,26 @@
import { extractDashedIdent, resolveLengthInPixels, splitValue } from "./js/util.js";
import { isColor, resolve } from "./js/resolve.js";
import { cssCalc, cssVar } from "./js/css-calc-var.js";
import { isGradient, resolveGradient } from "./js/css-gradient.js";
import { convert } from "./js/convert.js";
//#region src/index.ts
/*!
* CSS color - Resolve, parse, convert CSS color.
* @license MIT
* @copyright asamuzaK (Kazz)
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
*/
var utils = {
cssCalc,
cssVar,
extractDashedIdent,
isColor,
isGradient,
resolveGradient,
resolveLengthInPixels,
splitValue
};
//#endregion
export { convert, resolve, utils };
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["/*!\n * CSS color - Resolve, parse, convert CSS color.\n * @license MIT\n * @copyright asamuzaK (Kazz)\n * @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}\n */\n\nimport { cssCalc, cssVar } from './js/css-calc-var';\nimport { isGradient, resolveGradient } from './js/css-gradient';\nimport { isColor } from './js/resolve';\nimport {\n extractDashedIdent,\n resolveLengthInPixels,\n splitValue\n} from './js/util';\n\nexport { convert } from './js/convert';\nexport { resolve } from './js/resolve';\n/* utils */\nexport const utils = {\n cssCalc,\n cssVar,\n extractDashedIdent,\n isColor,\n isGradient,\n resolveGradient,\n resolveLengthInPixels,\n splitValue\n};\n"],"mappings":";;;;;;;;;;;;AAmBA,IAAa,QAAQ;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF"}
+31
View File
@@ -0,0 +1,31 @@
import { LRUCache } from 'lru-cache';
import { Options } from './typedef.js';
/**
* CacheItem
*/
export declare class CacheItem {
#private;
constructor(item: unknown);
get item(): unknown;
}
export declare const lruCache: LRUCache<string, CacheItem, unknown>;
/**
* set cache
* @param key - cache key
* @param value - value to cache
* @returns void
*/
export declare const setCache: (key: string, value: unknown) => void;
/**
* get cache
* @param key - cache key
* @returns cached item or false otherwise
*/
export declare const getCache: (key: string) => CacheItem | false;
/**
* create cache key
* @param keyData - key data
* @param [opt] - options
* @returns cache key
*/
export declare const createCacheKey: (keyData: Record<string, string>, opt?: Options) => string;
+72
View File
@@ -0,0 +1,72 @@
import { LRUCache } from "lru-cache";
//#region src/js/cache.ts
/**
* cache
*/
var CACHE_SIZE = 4096;
/**
* CacheItem
*/
var CacheItem = class {
#item;
constructor(item) {
this.#item = item;
}
get item() {
return this.#item;
}
};
var lruCache = new LRUCache({ max: CACHE_SIZE });
/**
* set cache
* @param key - cache key
* @param value - value to cache
* @returns void
*/
var setCache = (key, value) => {
if (!key) return;
if (value instanceof CacheItem) lruCache.set(key, value);
else lruCache.set(key, new CacheItem(value));
};
/**
* get cache
* @param key - cache key
* @returns cached item or false otherwise
*/
var getCache = (key) => {
if (!key) return false;
const item = lruCache.get(key);
if (item !== void 0) return item;
return false;
};
/**
* helper function to sort object keys alphabetically
* @param obj - Object
* @returns stringified JSON
*/
var stringifySorted = (obj) => {
const keys = Object.keys(obj);
if (keys.length === 0) return "";
keys.sort();
let result = "";
for (const key of keys) result += `${key}:${JSON.stringify(obj[key])};`;
return result;
};
/**
* create cache key
* @param keyData - key data
* @param [opt] - options
* @returns cache key
*/
var createCacheKey = (keyData, opt = {}) => {
if (!keyData || opt.customProperty && typeof opt.customProperty.callback === "function" || opt.dimension && typeof opt.dimension.callback === "function") return "";
const namespace = keyData.namespace || "";
const name = keyData.name || "";
const value = keyData.value || "";
if (!namespace && !name && !value) return "";
return `${`${namespace}:${name}:${value}`}::${`${opt.format || ""}|${opt.colorSpace || ""}|${opt.colorScheme || ""}|${opt.currentColor || ""}|${opt.d50 ? "1" : "0"}|${opt.nullable ? "1" : "0"}|${opt.preserveComment ? "1" : "0"}|${opt.delimiter || ""}`}::${opt.customProperty ? stringifySorted(opt.customProperty) : ""}::${opt.dimension ? stringifySorted(opt.dimension) : ""}`;
};
//#endregion
export { CacheItem, createCacheKey, getCache, lruCache, setCache };
//# sourceMappingURL=cache.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"cache.js","names":["#item"],"sources":["../../../src/js/cache.ts"],"sourcesContent":["/**\n * cache\n */\n\nimport { LRUCache } from 'lru-cache';\nimport { Options } from './typedef';\n\n/* constants */\nconst CACHE_SIZE = 4096;\n\n/**\n * CacheItem\n */\nexport class CacheItem {\n /* private */\n #item: unknown;\n\n constructor(item: unknown) {\n this.#item = item;\n }\n\n get item() {\n return this.#item;\n }\n}\n\n/*\n * lru cache instance\n */\nexport const lruCache = new LRUCache<string, CacheItem>({\n max: CACHE_SIZE\n});\n\n/**\n * set cache\n * @param key - cache key\n * @param value - value to cache\n * @returns void\n */\nexport const setCache = (key: string, value: unknown): void => {\n if (!key) {\n return;\n }\n if (value instanceof CacheItem) {\n lruCache.set(key, value);\n } else {\n lruCache.set(key, new CacheItem(value));\n }\n};\n\n/**\n * get cache\n * @param key - cache key\n * @returns cached item or false otherwise\n */\nexport const getCache = (key: string): CacheItem | false => {\n if (!key) {\n return false;\n }\n const item = lruCache.get(key);\n if (item !== undefined) {\n return item as CacheItem;\n }\n return false;\n};\n\n/**\n * helper function to sort object keys alphabetically\n * @param obj - Object\n * @returns stringified JSON\n */\nconst stringifySorted = (obj: Record<string, unknown>): string => {\n const keys = Object.keys(obj);\n if (keys.length === 0) {\n return '';\n }\n keys.sort();\n let result = '';\n for (const key of keys) {\n result += `${key}:${JSON.stringify(obj[key])};`;\n }\n return result;\n};\n\n/**\n * create cache key\n * @param keyData - key data\n * @param [opt] - options\n * @returns cache key\n */\nexport const createCacheKey = (\n keyData: Record<string, string>,\n opt: Options = {}\n): string => {\n if (\n !keyData ||\n (opt.customProperty && typeof opt.customProperty.callback === 'function') ||\n (opt.dimension && typeof opt.dimension.callback === 'function')\n ) {\n return '';\n }\n const namespace = keyData.namespace || '';\n const name = keyData.name || '';\n const value = keyData.value || '';\n if (!namespace && !name && !value) {\n return '';\n }\n const baseKey = `${namespace}:${name}:${value}`;\n const optStr = `${opt.format || ''}|${opt.colorSpace || ''}|${opt.colorScheme || ''}|${opt.currentColor || ''}|${opt.d50 ? '1' : '0'}|${opt.nullable ? '1' : '0'}|${opt.preserveComment ? '1' : '0'}|${opt.delimiter || ''}`;\n const customPropStr = opt.customProperty\n ? stringifySorted(opt.customProperty as Record<string, unknown>)\n : '';\n const dimStr = opt.dimension\n ? stringifySorted(opt.dimension as Record<string, unknown>)\n : '';\n return `${baseKey}::${optStr}::${customPropStr}::${dimStr}`;\n};\n"],"mappings":";;;;;AAQA,IAAM,aAAa;;;;AAKnB,IAAa,YAAb,MAAuB;CAErB;CAEA,YAAY,MAAe;EACzB,KAAKA,QAAQ;CACf;CAEA,IAAI,OAAO;EACT,OAAO,KAAKA;CACd;AACF;AAKA,IAAa,WAAW,IAAI,SAA4B,EACtD,KAAK,WACP,CAAC;;;;;;;AAQD,IAAa,YAAY,KAAa,UAAyB;CAC7D,IAAI,CAAC,KACH;CAEF,IAAI,iBAAiB,WACnB,SAAS,IAAI,KAAK,KAAK;MAEvB,SAAS,IAAI,KAAK,IAAI,UAAU,KAAK,CAAC;AAE1C;;;;;;AAOA,IAAa,YAAY,QAAmC;CAC1D,IAAI,CAAC,KACH,OAAO;CAET,MAAM,OAAO,SAAS,IAAI,GAAG;CAC7B,IAAI,SAAS,KAAA,GACX,OAAO;CAET,OAAO;AACT;;;;;;AAOA,IAAM,mBAAmB,QAAyC;CAChE,MAAM,OAAO,OAAO,KAAK,GAAG;CAC5B,IAAI,KAAK,WAAW,GAClB,OAAO;CAET,KAAK,KAAK;CACV,IAAI,SAAS;CACb,KAAK,MAAM,OAAO,MAChB,UAAU,GAAG,IAAI,GAAG,KAAK,UAAU,IAAI,IAAI,EAAE;CAE/C,OAAO;AACT;;;;;;;AAQA,IAAa,kBACX,SACA,MAAe,CAAC,MACL;CACX,IACE,CAAC,WACA,IAAI,kBAAkB,OAAO,IAAI,eAAe,aAAa,cAC7D,IAAI,aAAa,OAAO,IAAI,UAAU,aAAa,YAEpD,OAAO;CAET,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,OAAO,QAAQ,QAAQ;CAC7B,MAAM,QAAQ,QAAQ,SAAS;CAC/B,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,OAC1B,OAAO;CAUT,OAAO,GAAG,GARS,UAAU,GAAG,KAAK,GAAG,QAQtB,IAAI,GAPJ,IAAI,UAAU,GAAG,GAAG,IAAI,cAAc,GAAG,GAAG,IAAI,eAAe,GAAG,GAAG,IAAI,gBAAgB,GAAG,GAAG,IAAI,MAAM,MAAM,IAAI,GAAG,IAAI,WAAW,MAAM,IAAI,GAAG,IAAI,kBAAkB,MAAM,IAAI,GAAG,IAAI,aAAa,KAO3L,IANP,IAAI,iBACtB,gBAAgB,IAAI,cAAyC,IAC7D,GAI2C,IAHhC,IAAI,YACf,gBAAgB,IAAI,SAAoC,IACxD;AAEN"}
+532
View File
@@ -0,0 +1,532 @@
import { ColorChannels, Options, SpecifiedColorChannels } from './typedef.js';
/**
* @type TriColorChannels - color channels without alpha
*/
type TriColorChannels = [x: number, y: number, z: number];
/**
* @type ColorMatrix - color matrix
*/
type ColorMatrix = [
r1: TriColorChannels,
r2: TriColorChannels,
r3: TriColorChannels
];
/**
* named colors
*/
export declare const NAMED_COLORS: {
readonly aliceblue: [240, 248, 255];
readonly antiquewhite: [250, 235, 215];
readonly aqua: [0, 255, 255];
readonly aquamarine: [127, 255, 212];
readonly azure: [240, 255, 255];
readonly beige: [245, 245, 220];
readonly bisque: [255, 228, 196];
readonly black: [0, 0, 0];
readonly blanchedalmond: [255, 235, 205];
readonly blue: [0, 0, 255];
readonly blueviolet: [138, 43, 226];
readonly brown: [165, 42, 42];
readonly burlywood: [222, 184, 135];
readonly cadetblue: [95, 158, 160];
readonly chartreuse: [127, 255, 0];
readonly chocolate: [210, 105, 30];
readonly coral: [255, 127, 80];
readonly cornflowerblue: [100, 149, 237];
readonly cornsilk: [255, 248, 220];
readonly crimson: [220, 20, 60];
readonly cyan: [0, 255, 255];
readonly darkblue: [0, 0, 139];
readonly darkcyan: [0, 139, 139];
readonly darkgoldenrod: [184, 134, 11];
readonly darkgray: [169, 169, 169];
readonly darkgreen: [0, 100, 0];
readonly darkgrey: [169, 169, 169];
readonly darkkhaki: [189, 183, 107];
readonly darkmagenta: [139, 0, 139];
readonly darkolivegreen: [85, 107, 47];
readonly darkorange: [255, 140, 0];
readonly darkorchid: [153, 50, 204];
readonly darkred: [139, 0, 0];
readonly darksalmon: [233, 150, 122];
readonly darkseagreen: [143, 188, 143];
readonly darkslateblue: [72, 61, 139];
readonly darkslategray: [47, 79, 79];
readonly darkslategrey: [47, 79, 79];
readonly darkturquoise: [0, 206, 209];
readonly darkviolet: [148, 0, 211];
readonly deeppink: [255, 20, 147];
readonly deepskyblue: [0, 191, 255];
readonly dimgray: [105, 105, 105];
readonly dimgrey: [105, 105, 105];
readonly dodgerblue: [30, 144, 255];
readonly firebrick: [178, 34, 34];
readonly floralwhite: [255, 250, 240];
readonly forestgreen: [34, 139, 34];
readonly fuchsia: [255, 0, 255];
readonly gainsboro: [220, 220, 220];
readonly ghostwhite: [248, 248, 255];
readonly gold: [255, 215, 0];
readonly goldenrod: [218, 165, 32];
readonly gray: [128, 128, 128];
readonly green: [0, 128, 0];
readonly greenyellow: [173, 255, 47];
readonly grey: [128, 128, 128];
readonly honeydew: [240, 255, 240];
readonly hotpink: [255, 105, 180];
readonly indianred: [205, 92, 92];
readonly indigo: [75, 0, 130];
readonly ivory: [255, 255, 240];
readonly khaki: [240, 230, 140];
readonly lavender: [230, 230, 250];
readonly lavenderblush: [255, 240, 245];
readonly lawngreen: [124, 252, 0];
readonly lemonchiffon: [255, 250, 205];
readonly lightblue: [173, 216, 230];
readonly lightcoral: [240, 128, 128];
readonly lightcyan: [224, 255, 255];
readonly lightgoldenrodyellow: [250, 250, 210];
readonly lightgray: [211, 211, 211];
readonly lightgreen: [144, 238, 144];
readonly lightgrey: [211, 211, 211];
readonly lightpink: [255, 182, 193];
readonly lightsalmon: [255, 160, 122];
readonly lightseagreen: [32, 178, 170];
readonly lightskyblue: [135, 206, 250];
readonly lightslategray: [119, 136, 153];
readonly lightslategrey: [119, 136, 153];
readonly lightsteelblue: [176, 196, 222];
readonly lightyellow: [255, 255, 224];
readonly lime: [0, 255, 0];
readonly limegreen: [50, 205, 50];
readonly linen: [250, 240, 230];
readonly magenta: [255, 0, 255];
readonly maroon: [128, 0, 0];
readonly mediumaquamarine: [102, 205, 170];
readonly mediumblue: [0, 0, 205];
readonly mediumorchid: [186, 85, 211];
readonly mediumpurple: [147, 112, 219];
readonly mediumseagreen: [60, 179, 113];
readonly mediumslateblue: [123, 104, 238];
readonly mediumspringgreen: [0, 250, 154];
readonly mediumturquoise: [72, 209, 204];
readonly mediumvioletred: [199, 21, 133];
readonly midnightblue: [25, 25, 112];
readonly mintcream: [245, 255, 250];
readonly mistyrose: [255, 228, 225];
readonly moccasin: [255, 228, 181];
readonly navajowhite: [255, 222, 173];
readonly navy: [0, 0, 128];
readonly oldlace: [253, 245, 230];
readonly olive: [128, 128, 0];
readonly olivedrab: [107, 142, 35];
readonly orange: [255, 165, 0];
readonly orangered: [255, 69, 0];
readonly orchid: [218, 112, 214];
readonly palegoldenrod: [238, 232, 170];
readonly palegreen: [152, 251, 152];
readonly paleturquoise: [175, 238, 238];
readonly palevioletred: [219, 112, 147];
readonly papayawhip: [255, 239, 213];
readonly peachpuff: [255, 218, 185];
readonly peru: [205, 133, 63];
readonly pink: [255, 192, 203];
readonly plum: [221, 160, 221];
readonly powderblue: [176, 224, 230];
readonly purple: [128, 0, 128];
readonly rebeccapurple: [102, 51, 153];
readonly red: [255, 0, 0];
readonly rosybrown: [188, 143, 143];
readonly royalblue: [65, 105, 225];
readonly saddlebrown: [139, 69, 19];
readonly salmon: [250, 128, 114];
readonly sandybrown: [244, 164, 96];
readonly seagreen: [46, 139, 87];
readonly seashell: [255, 245, 238];
readonly sienna: [160, 82, 45];
readonly silver: [192, 192, 192];
readonly skyblue: [135, 206, 235];
readonly slateblue: [106, 90, 205];
readonly slategray: [112, 128, 144];
readonly slategrey: [112, 128, 144];
readonly snow: [255, 250, 250];
readonly springgreen: [0, 255, 127];
readonly steelblue: [70, 130, 180];
readonly tan: [210, 180, 140];
readonly teal: [0, 128, 128];
readonly thistle: [216, 191, 216];
readonly tomato: [255, 99, 71];
readonly turquoise: [64, 224, 208];
readonly violet: [238, 130, 238];
readonly wheat: [245, 222, 179];
readonly white: [255, 255, 255];
readonly whitesmoke: [245, 245, 245];
readonly yellow: [255, 255, 0];
readonly yellowgreen: [154, 205, 50];
};
/**
* cache invalid color value
* @param key - cache key
* @param nullable - is nullable
* @returns cached value
*/
export declare const cacheInvalidColorValue: (cacheKey: string, format: string, nullable?: boolean) => SpecifiedColorChannels | string | null;
/**
* resolve invalid color value
* @param format - output format
* @param nullable - is nullable
* @returns resolved value
*/
export declare const resolveInvalidColorValue: (format: string, nullable?: boolean) => SpecifiedColorChannels | string | null;
/**
* validate color components
* @param arr - color components
* @param opt - options
* @param opt.alpha - alpha channel
* @param opt.minLength - min length
* @param opt.maxLength - max length
* @param opt.minRange - min range
* @param opt.maxRange - max range
* @param opt.validateRange - validate range
* @returns result - validated color components
*/
export declare const validateColorComponents: (arr: ColorChannels | TriColorChannels, opt?: {
alpha?: boolean;
minLength?: number;
maxLength?: number;
minRange?: number;
maxRange?: number;
validateRange?: boolean;
}) => ColorChannels | TriColorChannels;
/**
* transform matrix
* @param mtx - 3 * 3 matrix
* @param vct - vector
* @param [skip] - skip validate
* @returns TriColorChannels - [p1, p2, p3]
*/
export declare const transformMatrix: (mtx: ColorMatrix, vct: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* normalize color components
* @param colorA - color components [v1, v2, v3, v4]
* @param colorB - color components [v1, v2, v3, v4]
* @param [skip] - skip validate
* @returns result - [colorA, colorB]
*/
export declare const normalizeColorComponents: (colorA: [number | string, number | string, number | string, number | string], colorB: [number | string, number | string, number | string, number | string], skip?: boolean) => [ColorChannels, ColorChannels];
/**
* number to hex string
* @param value - numeric value
* @returns hex string
*/
export declare const numberToHexString: (value: number) => string;
/**
* angle to deg
* @param angle
* @returns deg: 0..360
*/
export declare const angleToDeg: (angle: string) => number;
/**
* parse alpha
* @param [alpha] - alpha value
* @returns alpha: 0..1
*/
export declare const parseAlpha: (alpha?: string) => number;
/**
* parse hex alpha
* @param value - alpha value in hex string
* @returns alpha: 0..1
*/
export declare const parseHexAlpha: (value: string) => number;
/**
* transform rgb to linear rgb
* @param rgb - [r, g, b] r|g|b: 0..255
* @param [skip] - skip validate
* @returns TriColorChannels - [r, g, b] r|g|b: 0..1
*/
export declare const transformRgbToLinearRgb: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform rgb to xyz
* @param rgb - [r, g, b] r|g|b: 0..255
* @param [skip] - skip validate
* @returns TriColorChannels - [x, y, z]
*/
export declare const transformRgbToXyz: (rgb: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform rgb to xyz-d50
* @param rgb - [r, g, b] r|g|b: 0..255 alpha: 0..1
* @returns TriColorChannels - [x, y, z]
*/
export declare const transformRgbToXyzD50: (rgb: TriColorChannels) => TriColorChannels;
/**
* transform linear rgb to rgb
* @param rgb - [r, g, b] r|g|b: 0..1
* @param [round] - round result
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
*/
export declare const transformLinearRgbToRgb: (rgb: TriColorChannels, round?: boolean) => TriColorChannels;
/**
* transform xyz to rgb
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
*/
export declare const transformXyzToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz to xyz-d50
* @param xyz - [x, y, z]
* @returns TriColorChannels - [x, y, z]
*/
export declare const transformXyzToXyzD50: (xyz: TriColorChannels) => TriColorChannels;
/**
* transform xyz to hsl
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [h, s, l]
*/
export declare const transformXyzToHsl: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz to hwb
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [h, w, b]
*/
export declare const transformXyzToHwb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz to oklab
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [l, a, b]
*/
export declare const transformXyzToOklab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz to oklch
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [l, c, h]
*/
export declare const transformXyzToOklch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz D50 to rgb
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [r, g, b] r|g|b: 0..255
*/
export declare const transformXyzD50ToRgb: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz-d50 to lab
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [l, a, b]
*/
export declare const transformXyzD50ToLab: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* transform xyz-d50 to lch
* @param xyz - [x, y, z]
* @param [skip] - skip validate
* @returns TriColorChannels - [l, c, h]
*/
export declare const transformXyzD50ToLch: (xyz: TriColorChannels, skip?: boolean) => TriColorChannels;
/**
* convert rgb to hex color
* @param rgb - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
* @returns hex color
*/
export declare const convertRgbToHex: (rgb: ColorChannels) => string;
/**
* convert linear rgb to hex color
* @param rgb - [r, g, b, alpha] r|g|b|alpha: 0..1
* @param [skip] - skip validate
* @returns hex color
*/
export declare const convertLinearRgbToHex: (rgb: ColorChannels, skip?: boolean) => string;
/**
* convert xyz to hex color
* @param xyz - [x, y, z, alpha]
* @returns hex color
*/
export declare const convertXyzToHex: (xyz: ColorChannels) => string;
/**
* convert xyz D50 to hex color
* @param xyz - [x, y, z, alpha]
* @returns hex color
*/
export declare const convertXyzD50ToHex: (xyz: ColorChannels) => string;
/**
* convert hex color to rgb
* @param value - hex color value
* @returns ColorChannels - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
*/
export declare const convertHexToRgb: (value: string) => ColorChannels;
/**
* convert hex color to linear rgb
* @param value - hex color value
* @returns ColorChannels - [r, g, b, alpha] r|g|b|alpha: 0..1
*/
export declare const convertHexToLinearRgb: (value: string) => ColorChannels;
/**
* convert hex color to xyz
* @param value - hex color value
* @returns ColorChannels - [x, y, z, alpha]
*/
export declare const convertHexToXyz: (value: string) => ColorChannels;
/**
* parse rgb()
* @param value - rgb color value
* @param opt - options
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', null
*/
export declare const parseRgb: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse hsl()
* @param value - hsl color value
* @param opt - options
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', null
*/
export declare const parseHsl: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse hwb()
* @param value - hwb color value
* @param opt - options
* @returns parsed color - ['rgb', r, g, b, alpha], '(empty)', null
*/
export declare const parseHwb: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse lab()
* @param value - lab color value
* @param opt - options
* @returns parsed color
* - [xyz-d50, x, y, z, alpha], ['lab', l, a, b, alpha], '(empty)', null
*/
export declare const parseLab: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse lch()
* @param value - lch color value
* @param opt - options
* @returns parsed color
* - ['xyz-d50', x, y, z, alpha], ['lch', l, c, h, alpha], '(empty)', null
*/
export declare const parseLch: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse oklab()
* @param value - oklab color value
* @param opt - options
* @returns parsed color
* - ['xyz-d65', x, y, z, alpha], ['oklab', l, a, b, alpha], '(empty)', null
*/
export declare const parseOklab: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse oklch()
* @param value - oklch color value
* @param opt - options
* @returns parsed color
* - ['xyz-d65', x, y, z, alpha], ['oklch', l, c, h, alpha], '(empty)', null
*/
export declare const parseOklch: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse color()
* @param value - color function value
* @param opt - options
* @returns parsed color
* - ['xyz-(d50|d65)', x, y, z, alpha], [cs, r, g, b, alpha], '(empty)', null
*/
export declare const parseColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* parse color value
* @param value - CSS color value
* @param opt - options
* @returns parsed color
* - ['xyz-(d50|d65)', x, y, z, alpha], ['rgb', r, g, b, alpha]
* - value, '(empty)', null
*/
export declare const parseColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* resolve color value
* @param value - CSS color value
* @param opt - options
* @returns resolved color
* - [cs, v1, v2, v3, alpha], value, '(empty)', null
*/
export declare const resolveColorValue: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* resolve color()
* @param value - color function value
* @param opt - options
* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', null
*/
export declare const resolveColorFunc: (value: string, opt?: Options) => SpecifiedColorChannels | string | null;
/**
* convert color value to linear rgb
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [r, g, b, alpha] r|g|b|alpha: 0..1
*/
export declare const convertColorToLinearRgb: (value: string, opt?: {
colorSpace?: string;
format?: string;
}) => ColorChannels | null;
/**
* convert color value to rgb
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [r, g, b, alpha] r|g|b: 0..255 alpha: 0..1
*/
export declare const convertColorToRgb: (value: string, opt?: Options) => ColorChannels | null;
/**
* convert color value to xyz
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [x, y, z, alpha]
*/
export declare const convertColorToXyz: (value: string, opt?: Options) => ColorChannels | null;
/**
* convert color value to hsl
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [h, s, l, alpha], hue may be powerless
*/
export declare const convertColorToHsl: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | null;
/**
* convert color value to hwb
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [h, w, b, alpha], hue may be powerless
*/
export declare const convertColorToHwb: (value: string, opt?: Options) => ColorChannels | [number | string, number, number, number] | null;
/**
* convert color value to lab
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [l, a, b, alpha]
*/
export declare const convertColorToLab: (value: string, opt?: Options) => ColorChannels | null;
/**
* convert color value to lch
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [l, c, h, alpha], hue may be powerless
*/
export declare const convertColorToLch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | null;
/**
* convert color value to oklab
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [l, a, b, alpha]
*/
export declare const convertColorToOklab: (value: string, opt?: Options) => ColorChannels | null;
/**
* convert color value to oklch
* @param value - CSS color value
* @param opt - options
* @returns ColorChannels | null - [l, c, h, alpha], hue may be powerless
*/
export declare const convertColorToOklch: (value: string, opt?: Options) => ColorChannels | [number, number, number | string, number] | null;
/**
* resolve color-mix()
* @param value - color-mix color value
* @param opt - options
* @param resolver - resolver function
* @returns resolved color - [cs, v1, v2, v3, alpha], '(empty)', null
*/
export declare const resolveColorMix: (value: string, opt?: Options, resolver?: (v: string, o?: Options) => string | null) => SpecifiedColorChannels | string | null;
export {};
File diff suppressed because it is too large. Load diff
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"color.js","names":[],"sources":["../../../src/js/color.ts"],"sourcesContent":["/**\n * color\n *\n * Ref: CSS Color Module Level 4\n * Sample code for Color Conversions\n * https://w3c.github.io/csswg-drafts/css-color-4/#color-conversion-code\n */\n\nimport { createCacheKey, getCache, setCache } from './cache';\nimport { isString } from './common';\nimport { interpolateHue, roundToPrecision, splitValue } from './util';\nimport {\n ColorChannels,\n ComputedColorChannels,\n Options,\n MatchedRegExp,\n SpecifiedColorChannels,\n StringColorChannels,\n StringColorSpacedChannels\n} from './typedef';\n\n/* constants */\nimport {\n ANGLE,\n CS_HUE_CAPT,\n CS_MIX,\n CS_RGB,\n CS_XYZ,\n FN_COLOR,\n FN_LIGHT_DARK,\n FN_MIX,\n NONE,\n NUM,\n PCT,\n SYN_COLOR_TYPE,\n SYN_FN_COLOR,\n SYN_HSL,\n SYN_HSL_LV3,\n SYN_LCH,\n SYN_MIX,\n SYN_MIX_CAPT,\n SYN_MIX_PART,\n SYN_MOD,\n SYN_RGB_LV3,\n VAL_COMP,\n VAL_MIX,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'color';\n\n/* numeric constants */\nconst PPTH = 0.001;\nconst HALF = 0.5;\nconst DUO = 2;\nconst TRIA = 3;\nconst QUAD = 4;\nconst OCT = 8;\nconst DEC = 10;\nconst DOZ = 12;\nconst HEX = 16;\nconst SEXA = 60;\nconst DEG_HALF = 180;\nconst DEG = 360;\nconst MAX_PCT = 100;\nconst MAX_RGB = 255;\nconst POW_SQR = 2;\nconst POW_CUBE = 3;\nconst POW_LINEAR = 2.4;\nconst LINEAR_COEF = 12.92;\nconst LINEAR_OFFSET = 0.055;\nconst LAB_L = 116;\nconst LAB_A = 500;\nconst LAB_B = 200;\nconst LAB_EPSILON = 216 / 24389;\nconst LAB_KAPPA = 24389 / 27;\n\n/* type definitions */\n/**\n * @type NumStrColorChannels - string or numeric color channels\n */\ntype NumStrColorChannels = [\n x: number | string,\n y: number | string,\n z: number | string,\n alpha: number | string\n];\n\n/**\n * @type TriColorChannels - color channels without alpha\n */\ntype TriColorChannels = [x: number, y: number, z: number];\n\n/**\n * @type ColorMatrix - color matrix\n */\ntype ColorMatrix = [\n r1: TriColorChannels,\n r2: TriColorChannels,\n r3: TriColorChannels\n];\n\n/* white point */\nconst D50: TriColorChannels = [\n 0.3457 / 0.3585,\n 1.0,\n (1.0 - 0.3457 - 0.3585) / 0.3585\n];\nconst MATRIX_D50_TO_D65: ColorMatrix = [\n [0.955473421488075, -0.02309845494876471, 0.06325924320057072],\n [-0.0283697093338637, 1.0099953980813041, 0.021041441191917323],\n [0.012314014864481998, -0.020507649298898964, 1.330365926242124]\n];\nconst MATRIX_D65_TO_D50: ColorMatrix = [\n [1.0479297925449969, 0.022946870601609652, -0.05019226628920524],\n [0.02962780877005599, 0.9904344267538799, -0.017073799063418826],\n [-0.009243040646204504, 0.015055191490298152, 0.7518742814281371]\n];\n\n/* color space */\nconst MATRIX_L_RGB_TO_XYZ: ColorMatrix = [\n [506752 / 1228815, 87881 / 245763, 12673 / 70218],\n [87098 / 409605, 175762 / 245763, 12673 / 175545],\n [7918 / 409605, 87881 / 737289, 1001167 / 1053270]\n];\nconst MATRIX_XYZ_TO_L_RGB: ColorMatrix = [\n [12831 / 3959, -329 / 214, -1974 / 3959],\n [-851781 / 878810, 1648619 / 878810, 36519 / 878810],\n [705 / 12673, -2585 / 12673, 705 / 667]\n];\nconst MATRIX_XYZ_TO_LMS: ColorMatrix = [\n [0.819022437996703, 0.3619062600528904, -0.1288737815209879],\n [0.0329836539323885, 0.9292868615863434, 0.0361446663506424],\n [0.0481771893596242, 0.2642395317527308, 0.6335478284694309]\n];\nconst MATRIX_LMS_TO_XYZ: ColorMatrix = [\n [1.2268798758459243, -0.5578149944602171, 0.2813910456659647],\n [-0.0405757452148008, 1.112286803280317, -0.0717110580655164],\n [-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]\n];\nconst MATRIX_OKLAB_TO_LMS: ColorMatrix = [\n [1.0, 0.3963377773761749, 0.2158037573099136],\n [1.0, -0.1055613458156586, -0.0638541728258133],\n [1.0, -0.0894841775298119, -1.2914855480194092]\n];\nconst MATRIX_LMS_TO_OKLAB: ColorMatrix = [\n [0.210454268309314, 0.7936177747023054, -0.0040720430116193],\n [1.9779985324311684, -2.4285922420485799, 0.450593709617411],\n [0.0259040424655478, 0.7827717124575296, -0.8086757549230774]\n];\nconst MATRIX_P3_TO_XYZ: ColorMatrix = [\n [608311 / 1250200, 189793 / 714400, 198249 / 1000160],\n [35783 / 156275, 247089 / 357200, 198249 / 2500400],\n [0 / 1, 32229 / 714400, 5220557 / 5000800]\n];\nconst MATRIX_REC2020_TO_XYZ: ColorMatrix = [\n [63426534 / 99577255, 20160776 / 139408157, 47086771 / 278816314],\n [26158966 / 99577255, 472592308 / 697040785, 8267143 / 139408157],\n [0 / 1, 19567812 / 697040785, 295819943 / 278816314]\n];\nconst MATRIX_A98_TO_XYZ: ColorMatrix = [\n [573536 / 994567, 263643 / 1420810, 187206 / 994567],\n [591459 / 1989134, 6239551 / 9945670, 374412 / 4972835],\n [53769 / 1989134, 351524 / 4972835, 4929758 / 4972835]\n];\nconst MATRIX_PROPHOTO_TO_XYZ_D50: ColorMatrix = [\n [0.7977666449006423, 0.13518129740053308, 0.0313477341283922],\n [0.2880748288194013, 0.711835234241873, 0.00008993693872564],\n [0.0, 0.0, 0.8251046025104602]\n];\n\n/* regexp */\nconst REG_COLOR = new RegExp(`^(?:${SYLine truncated
+21
View File
@@ -0,0 +1,21 @@
/**
* common
*/
/**
* get type
* @param o - object to check
* @returns type of object
*/
export declare const getType: (o: unknown) => string;
/**
* is string
* @param o - object to check
* @returns result
*/
export declare const isString: (o: unknown) => o is string;
/**
* is string or number
* @param o - object to check
* @returns result
*/
export declare const isStringOrNumber: (o: unknown) => boolean;
+17
View File
@@ -0,0 +1,17 @@
//#region src/js/common.ts
/**
* is string
* @param o - object to check
* @returns result
*/
var isString = (o) => typeof o === "string" || o instanceof String;
/**
* is string or number
* @param o - object to check
* @returns result
*/
var isStringOrNumber = (o) => isString(o) || typeof o === "number";
//#endregion
export { isString, isStringOrNumber };
//# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
{"version":3,"file":"common.js","names":[],"sources":["../../../src/js/common.ts"],"sourcesContent":["/**\n * common\n */\n\n/* numeric constants */\nconst TYPE_FROM = 8;\nconst TYPE_TO = -1;\n\n/**\n * get type\n * @param o - object to check\n * @returns type of object\n */\nexport const getType = (o: unknown): string =>\n Object.prototype.toString.call(o).slice(TYPE_FROM, TYPE_TO);\n\n/**\n * is string\n * @param o - object to check\n * @returns result\n */\nexport const isString = (o: unknown): o is string =>\n typeof o === 'string' || o instanceof String;\n\n/**\n * is string or number\n * @param o - object to check\n * @returns result\n */\nexport const isStringOrNumber = (o: unknown): boolean =>\n isString(o) || typeof o === 'number';\n"],"mappings":";;;;;;AAqBA,IAAa,YAAY,MACvB,OAAO,MAAM,YAAY,aAAa;;;;;;AAOxC,IAAa,oBAAoB,MAC/B,SAAS,CAAC,KAAK,OAAO,MAAM"}
+43
View File
@@ -0,0 +1,43 @@
/**
* constant
*/
export declare const ANGLE = "deg|g?rad|turn";
export declare const LENGTH = "[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)";
export declare const NUM = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?";
export declare const NUM_POSITIVE = "\\+?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?";
export declare const NONE = "none";
export declare const PCT = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%";
export declare const SYN_FN_CALC = "^(?:calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\(|(?<=[*\\/\\s\\(])(?:calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\(";
export declare const SYN_FN_MATH_START = "^(?:clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\($";
export declare const SYN_FN_VAR = "^var\\(|(?<=[*\\/\\s\\(])var\\(";
export declare const SYN_FN_VAR_START = "^(?:var|calc|clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2)\\(";
export declare const CS_HUE = "(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?";
export declare const CS_HUE_CAPT = "((?:ok)?lch|hsl|hwb)(?:\\s((?:de|in)creasing|longer|shorter)\\shue)?";
export declare const CS_LAB = "(?:ok)?lab";
export declare const CS_LCH = "(?:ok)?lch";
export declare const CS_SRGB = "srgb(?:-linear)?";
export declare const CS_RGB = "(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?";
export declare const CS_XYZ = "xyz(?:-d(?:50|65))?";
export declare const CS_RECT = "(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?";
export declare const CS_MIX = "(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?";
export declare const FN_COLOR = "color(";
export declare const FN_LIGHT_DARK = "light-dark(";
export declare const FN_MIX = "color-mix(";
export declare const FN_REL = "(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+";
export declare const FN_REL_CAPT = "((?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+";
export declare const FN_VAR = "var(";
export declare const SYN_FN_COLOR = "(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?";
export declare const SYN_FN_LIGHT_DARK = "^light-dark\\(";
export declare const SYN_FN_REL = "^(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+|(?<=[\\s])(?:(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?)\\(\\s*from\\s+";
export declare const SYN_HSL = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?";
export declare const SYN_HSL_LV3 = "[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?";
export declare const SYN_LCH = "(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?";
export declare const SYN_MOD = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?";
export declare const SYN_RGB_LV3 = "(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?";
export declare const SYN_COLOR_TYPE = "[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)";
export declare const SYN_MIX_PART = "(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?";
export declare const SYN_MIX = "color-mix\\(\\s*in\\s+(?:(?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)\\s*,\\s*(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?\\s*,\\s*(?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:Line truncated
export declare const SYN_MIX_CAPT = "color-mix\\(\\s*in\\s+((?:(?:ok)?lch|hsl|hwb)(?:\\s(?:(?:de|in)creasing|longer|shorter)\\shue)?|(?:ok)?lab|(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)\\s*,\\s*((?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|color\\(\\s*(?:(?:a98|prophoto)-rgb|display-p3|rec2020|srgb(?:-linear)?|xyz(?:-d(?:50|65))?)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){3}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\))(?:\\s+[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%)?)\\s*,\\s*((?:[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}|hsla?\\(\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2}(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|rgba?\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?){2}|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%(?:\\s*,\\s*[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%){2})(?:\\s*,\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%))?\\s*\\)|(?:hsla?|hwb)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?(?:deg|g?rad|turn)?|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)(?:\\s+(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)){2}(?:\\s*\\/\\s*(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none))?\\s*\\)|(?:ok)?lch\\(\\s*(?:(?:[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?|[+-]?(?:(?:0|[1-9]\\d*)(?:\\.\\d*)?|\\.\\d+)(?:e-?(?:0|[1-9]\\d*))?%|none)\\s+){2}(?:[+Line truncated
export declare const VAL_COMP = "computedValue";
export declare const VAL_MIX = "mixValue";
export declare const VAL_SPEC = "specifiedValue";
+61
View File
@@ -0,0 +1,61 @@
//#region src/js/constant.ts
/**
* constant
*/
var _DIGIT = "(?:0|[1-9]\\d*)";
var _MATH = `clamp|max|min|exp|hypot|log|pow|sqrt|abs|sign|mod|rem|round|a?(?:cos|sin|tan)|atan2`;
var _CALC = `calc|${_MATH}`;
var _VAR = `var|${_CALC}`;
var ANGLE = "deg|g?rad|turn";
var LENGTH = "[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)";
var NUM = `[+-]?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
var NUM_POSITIVE = `\\+?(?:${_DIGIT}(?:\\.\\d*)?|\\.\\d+)(?:e-?${_DIGIT})?`;
var NONE = "none";
var PCT = `${NUM}%`;
var SYN_FN_CALC = `^(?:${_CALC})\\(|(?<=[*\\/\\s\\(])(?:${_CALC})\\(`;
var SYN_FN_MATH_START = `^(?:${_MATH})\\($`;
var SYN_FN_VAR = "^var\\(|(?<=[*\\/\\s\\(])var\\(";
var SYN_FN_VAR_START = `^(?:${_VAR})\\(`;
var _ALPHA = `(?:\\s*\\/\\s*(?:${NUM}|${PCT}|${NONE}))?`;
var _ALPHA_LV3 = `(?:\\s*,\\s*(?:${NUM}|${PCT}))?`;
var _COLOR_FUNC = "(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?";
var _COLOR_KEY = "[a-z]+|#[\\da-f]{3}|#[\\da-f]{4}|#[\\da-f]{6}|#[\\da-f]{8}";
var _CS_HUE = "(?:ok)?lch|hsl|hwb";
var _CS_HUE_ARC = "(?:de|in)creasing|longer|shorter";
var _NUM_ANGLE = `${NUM}(?:${ANGLE})?`;
var _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`;
var _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`;
var CS_HUE = `(?:${_CS_HUE})(?:\\s(?:${_CS_HUE_ARC})\\shue)?`;
var CS_HUE_CAPT = `(${_CS_HUE})(?:\\s(${_CS_HUE_ARC})\\shue)?`;
var CS_LAB = "(?:ok)?lab";
var CS_LCH = "(?:ok)?lch";
var CS_SRGB = "srgb(?:-linear)?";
var CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`;
var CS_XYZ = "xyz(?:-d(?:50|65))?";
var CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`;
var CS_MIX = `${CS_HUE}|${CS_RECT}`;
var FN_COLOR = "color(";
var FN_LIGHT_DARK = "light-dark(";
var FN_MIX = "color-mix(";
var FN_REL = `(?:${_COLOR_FUNC})\\(\\s*from\\s+`;
var FN_REL_CAPT = `(${_COLOR_FUNC})\\(\\s*from\\s+`;
var FN_VAR = "var(";
var SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`;
var SYN_FN_LIGHT_DARK = "^light-dark\\(";
var SYN_FN_REL = `^${FN_REL}|(?<=[\\s])${FN_REL}`;
var SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
var SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\s*,\\s*${PCT}){2}${_ALPHA_LV3}`;
var SYN_LCH = `(?:${_NUM_PCT_NONE}\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`;
var SYN_MOD = `${_NUM_PCT_NONE}(?:\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;
var SYN_RGB_LV3 = `(?:${NUM}(?:\\s*,\\s*${NUM}){2}|${PCT}(?:\\s*,\\s*${PCT}){2})${_ALPHA_LV3}`;
var SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\(\\s*${SYN_HSL_LV3}\\s*\\)|rgba?\\(\\s*${SYN_RGB_LV3}\\s*\\)|(?:hsla?|hwb)\\(\\s*${SYN_HSL}\\s*\\)|(?:(?:ok)?lab|rgba?)\\(\\s*${SYN_MOD}\\s*\\)|(?:ok)?lch\\(\\s*${SYN_LCH}\\s*\\)|color\\(\\s*${SYN_FN_COLOR}\\s*\\)`;
var SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\s+${PCT})?`;
var SYN_MIX = `color-mix\\(\\s*in\\s+(?:${CS_MIX})\\s*,\\s*${SYN_MIX_PART}\\s*,\\s*${SYN_MIX_PART}\\s*\\)`;
var SYN_MIX_CAPT = `color-mix\\(\\s*in\\s+(${CS_MIX})\\s*,\\s*(${SYN_MIX_PART})\\s*,\\s*(${SYN_MIX_PART})\\s*\\)`;
var VAL_COMP = "computedValue";
var VAL_MIX = "mixValue";
var VAL_SPEC = "specifiedValue";
//#endregion
export { ANGLE, CS_HUE, CS_HUE_CAPT, CS_LAB, CS_LCH, CS_MIX, CS_RECT, CS_RGB, CS_SRGB, CS_XYZ, FN_COLOR, FN_LIGHT_DARK, FN_MIX, FN_REL, FN_REL_CAPT, FN_VAR, LENGTH, NONE, NUM, NUM_POSITIVE, PCT, SYN_COLOR_TYPE, SYN_FN_CALC, SYN_FN_COLOR, SYN_FN_LIGHT_DARK, SYN_FN_MATH_START, SYN_FN_REL, SYN_FN_VAR, SYN_FN_VAR_START, SYN_HSL, SYN_HSL_LV3, SYN_LCH, SYN_MIX, SYN_MIX_CAPT, SYN_MIX_PART, SYN_MOD, SYN_RGB_LV3, VAL_COMP, VAL_MIX, VAL_SPEC };
//# sourceMappingURL=constant.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constant.js","names":[],"sources":["../../../src/js/constant.ts"],"sourcesContent":["/**\n * constant\n */\n\n/* values and units */\nconst _DIGIT = '(?:0|[1-9]\\\\d*)';\nconst _COMPARE = 'clamp|max|min';\nconst _EXPO = 'exp|hypot|log|pow|sqrt';\nconst _SIGN = 'abs|sign';\nconst _STEP = 'mod|rem|round';\nconst _TRIG = 'a?(?:cos|sin|tan)|atan2';\nconst _MATH = `${_COMPARE}|${_EXPO}|${_SIGN}|${_STEP}|${_TRIG}`;\nconst _CALC = `calc|${_MATH}`;\nconst _VAR = `var|${_CALC}`;\nexport const ANGLE = 'deg|g?rad|turn';\nexport const LENGTH =\n '[cm]m|[dls]?v(?:[bhiw]|max|min)|in|p[ctx]|q|r?(?:[cl]h|cap|e[mx]|ic)';\nexport const NUM = `[+-]?(?:${_DIGIT}(?:\\\\.\\\\d*)?|\\\\.\\\\d+)(?:e-?${_DIGIT})?`;\nexport const NUM_POSITIVE = `\\\\+?(?:${_DIGIT}(?:\\\\.\\\\d*)?|\\\\.\\\\d+)(?:e-?${_DIGIT})?`;\nexport const NONE = 'none';\nexport const PCT = `${NUM}%`;\nexport const SYN_FN_CALC = `^(?:${_CALC})\\\\(|(?<=[*\\\\/\\\\s\\\\(])(?:${_CALC})\\\\(`;\nexport const SYN_FN_MATH_START = `^(?:${_MATH})\\\\($`;\nexport const SYN_FN_VAR = '^var\\\\(|(?<=[*\\\\/\\\\s\\\\(])var\\\\(';\nexport const SYN_FN_VAR_START = `^(?:${_VAR})\\\\(`;\n\n/* colors */\nconst _ALPHA = `(?:\\\\s*\\\\/\\\\s*(?:${NUM}|${PCT}|${NONE}))?`;\nconst _ALPHA_LV3 = `(?:\\\\s*,\\\\s*(?:${NUM}|${PCT}))?`;\nconst _COLOR_FUNC = '(?:ok)?l(?:ab|ch)|color|hsla?|hwb|rgba?';\nconst _COLOR_KEY = '[a-z]+|#[\\\\da-f]{3}|#[\\\\da-f]{4}|#[\\\\da-f]{6}|#[\\\\da-f]{8}';\nconst _CS_HUE = '(?:ok)?lch|hsl|hwb';\nconst _CS_HUE_ARC = '(?:de|in)creasing|longer|shorter';\nconst _NUM_ANGLE = `${NUM}(?:${ANGLE})?`;\nconst _NUM_ANGLE_NONE = `(?:${NUM}(?:${ANGLE})?|${NONE})`;\nconst _NUM_PCT_NONE = `(?:${NUM}|${PCT}|${NONE})`;\nexport const CS_HUE = `(?:${_CS_HUE})(?:\\\\s(?:${_CS_HUE_ARC})\\\\shue)?`;\nexport const CS_HUE_CAPT = `(${_CS_HUE})(?:\\\\s(${_CS_HUE_ARC})\\\\shue)?`;\nexport const CS_LAB = '(?:ok)?lab';\nexport const CS_LCH = '(?:ok)?lch';\nexport const CS_SRGB = 'srgb(?:-linear)?';\nexport const CS_RGB = `(?:a98|prophoto)-rgb|display-p3|rec2020|${CS_SRGB}`;\nexport const CS_XYZ = 'xyz(?:-d(?:50|65))?';\nexport const CS_RECT = `${CS_LAB}|${CS_RGB}|${CS_XYZ}`;\nexport const CS_MIX = `${CS_HUE}|${CS_RECT}`;\nexport const FN_COLOR = 'color(';\nexport const FN_LIGHT_DARK = 'light-dark(';\nexport const FN_MIX = 'color-mix(';\nexport const FN_REL = `(?:${_COLOR_FUNC})\\\\(\\\\s*from\\\\s+`;\nexport const FN_REL_CAPT = `(${_COLOR_FUNC})\\\\(\\\\s*from\\\\s+`;\nexport const FN_VAR = 'var(';\nexport const SYN_FN_COLOR = `(?:${CS_RGB}|${CS_XYZ})(?:\\\\s+${_NUM_PCT_NONE}){3}${_ALPHA}`;\nexport const SYN_FN_LIGHT_DARK = '^light-dark\\\\(';\nexport const SYN_FN_REL = `^${FN_REL}|(?<=[\\\\s])${FN_REL}`;\nexport const SYN_HSL = `${_NUM_ANGLE_NONE}(?:\\\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;\nexport const SYN_HSL_LV3 = `${_NUM_ANGLE}(?:\\\\s*,\\\\s*${PCT}){2}${_ALPHA_LV3}`;\nexport const SYN_LCH = `(?:${_NUM_PCT_NONE}\\\\s+){2}${_NUM_ANGLE_NONE}${_ALPHA}`;\nexport const SYN_MOD = `${_NUM_PCT_NONE}(?:\\\\s+${_NUM_PCT_NONE}){2}${_ALPHA}`;\nexport const SYN_RGB_LV3 = `(?:${NUM}(?:\\\\s*,\\\\s*${NUM}){2}|${PCT}(?:\\\\s*,\\\\s*${PCT}){2})${_ALPHA_LV3}`;\nexport const SYN_COLOR_TYPE = `${_COLOR_KEY}|hsla?\\\\(\\\\s*${SYN_HSL_LV3}\\\\s*\\\\)|rgba?\\\\(\\\\s*${SYN_RGB_LV3}\\\\s*\\\\)|(?:hsla?|hwb)\\\\(\\\\s*${SYN_HSL}\\\\s*\\\\)|(?:(?:ok)?lab|rgba?)\\\\(\\\\s*${SYN_MOD}\\\\s*\\\\)|(?:ok)?lch\\\\(\\\\s*${SYN_LCH}\\\\s*\\\\)|color\\\\(\\\\s*${SYN_FN_COLOR}\\\\s*\\\\)`;\nexport const SYN_MIX_PART = `(?:${SYN_COLOR_TYPE})(?:\\\\s+${PCT})?`;\nexport const SYN_MIX = `color-mix\\\\(\\\\s*in\\\\s+(?:${CS_MIX})\\\\s*,\\\\s*${SYN_MIX_PART}\\\\s*,\\\\s*${SYN_MIX_PART}\\\\s*\\\\)`;\nexport const SYN_MIX_CAPT = `color-mix\\\\(\\\\s*in\\\\s+(${CS_MIX})\\\\s*,\\\\s*(${SYN_MIX_PART})\\\\s*,\\\\s*(${SYN_MIX_PART})\\\\s*\\\\)`;\n\n/* formats */\nexport const VAL_COMP = 'computedValue';\nexport const VAL_MIX = 'mixValue';\nexport const VAL_SPEC = 'specifiedValue';\n"],"mappings":";;;;AAKA,IAAM,SAAS;AAMf,IAAM,QAAQ;AACd,IAAM,QAAQ,QAAQ;AACtB,IAAM,OAAO,OAAO;AACpB,IAAa,QAAQ;AACrB,IAAa,SACX;AACF,IAAa,MAAM,WAAW,OAAO,6BAA6B,OAAO;AACzE,IAAa,eAAe,UAAU,OAAO,6BAA6B,OAAO;AACjF,IAAa,OAAO;AACpB,IAAa,MAAM,GAAG,IAAI;AAC1B,IAAa,cAAc,OAAO,MAAM,2BAA2B,MAAM;AACzE,IAAa,oBAAoB,OAAO,MAAM;AAC9C,IAAa,aAAa;AAC1B,IAAa,mBAAmB,OAAO,KAAK;AAG5C,IAAM,SAAS,oBAAoB,IAAI,GAAG,IAAI,GAAG,KAAK;AACtD,IAAM,aAAa,kBAAkB,IAAI,GAAG,IAAI;AAChD,IAAM,cAAc;AACpB,IAAM,aAAa;AACnB,IAAM,UAAU;AAChB,IAAM,cAAc;AACpB,IAAM,aAAa,GAAG,IAAI,KAAK,MAAM;AACrC,IAAM,kBAAkB,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK;AACvD,IAAM,gBAAgB,MAAM,IAAI,GAAG,IAAI,GAAG,KAAK;AAC/C,IAAa,SAAS,MAAM,QAAQ,YAAY,YAAY;AAC5D,IAAa,cAAc,IAAI,QAAQ,UAAU,YAAY;AAC7D,IAAa,SAAS;AACtB,IAAa,SAAS;AACtB,IAAa,UAAU;AACvB,IAAa,SAAS,2CAA2C;AACjE,IAAa,SAAS;AACtB,IAAa,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG;AAC9C,IAAa,SAAS,GAAG,OAAO,GAAG;AACnC,IAAa,WAAW;AACxB,IAAa,gBAAgB;AAC7B,IAAa,SAAS;AACtB,IAAa,SAAS,MAAM,YAAY;AACxC,IAAa,cAAc,IAAI,YAAY;AAC3C,IAAa,SAAS;AACtB,IAAa,eAAe,MAAM,OAAO,GAAG,OAAO,UAAU,cAAc,MAAM;AACjF,IAAa,oBAAoB;AACLine truncated
+98
View File
@@ -0,0 +1,98 @@
import { ColorChannels, Options } from './typedef.js';
/**
* pre process
* @param value - CSS color value
* @param [opt] - options
* @returns value
*/
export declare const preProcess: (value: string, opt?: Options) => string | null;
/**
* convert number to hex string
* @param value - numeric value
* @returns hex string: 00..ff
*/
export declare const numberToHex: (value: number) => string;
/**
* convert color to hex
* @param value - CSS color value
* @param [opt] - options
* @param [opt.alpha] - enable alpha channel
* @returns #rrggbb | #rrggbbaa | null
*/
export declare const colorToHex: (value: string, opt?: Options) => string | null;
/**
* convert color to hsl
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [h, s, l, alpha]
*/
export declare const colorToHsl: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to hwb
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [h, w, b, alpha]
*/
export declare const colorToHwb: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to lab
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, a, b, alpha]
*/
export declare const colorToLab: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to lch
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, c, h, alpha]
*/
export declare const colorToLch: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to oklab
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, a, b, alpha]
*/
export declare const colorToOklab: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to oklch
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, c, h, alpha]
*/
export declare const colorToOklch: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to rgb
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [r, g, b, alpha]
*/
export declare const colorToRgb: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to xyz
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [x, y, z, alpha]
*/
export declare const colorToXyz: (value: string, opt?: Options) => ColorChannels;
/**
* convert color to xyz-d50
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [x, y, z, alpha]
*/
export declare const colorToXyzD50: (value: string, opt?: Options) => ColorChannels;
export declare const convert: {
colorToHex: (value: string, opt?: Options) => string | null;
colorToHsl: (value: string, opt?: Options) => ColorChannels;
colorToHwb: (value: string, opt?: Options) => ColorChannels;
colorToLab: (value: string, opt?: Options) => ColorChannels;
colorToLch: (value: string, opt?: Options) => ColorChannels;
colorToOklab: (value: string, opt?: Options) => ColorChannels;
colorToOklch: (value: string, opt?: Options) => ColorChannels;
colorToRgb: (value: string, opt?: Options) => ColorChannels;
colorToXyz: (value: string, opt?: Options) => ColorChannels;
colorToXyzD50: (value: string, opt?: Options) => ColorChannels;
numberToHex: (value: number) => string;
};
+241
View File
@@ -0,0 +1,241 @@
import { createCacheKey, getCache, setCache } from "./cache.js";
import { isString } from "./common.js";
import { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from "./constant.js";
import { convertColorToHsl, convertColorToHwb, convertColorToLab, convertColorToLch, convertColorToOklab, convertColorToOklch, convertColorToRgb, numberToHexString, parseColorFunc, parseColorValue } from "./color.js";
import { resolveRelativeColor } from "./relative-color.js";
import { resolveColor } from "./resolve.js";
import { cssCalc, resolveVar } from "./css-calc-var.js";
//#region src/js/convert.ts
/**
* convert
*/
var NAMESPACE = "convert";
var REG_FN_CALC = new RegExp(SYN_FN_CALC);
var REG_FN_REL = new RegExp(SYN_FN_REL);
var REG_FN_VAR = new RegExp(SYN_FN_VAR);
/**
* pre process
* @param value - CSS color value
* @param [opt] - options
* @returns value
*/
var preProcess = (value, opt = {}) => {
if (!isString(value)) return null;
value = value.trim();
if (!value) return null;
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "preProcess",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
let res = value;
if (REG_FN_VAR.test(value)) {
const resolved = resolveVar(value, opt);
if (isString(resolved)) res = resolved;
else {
setCache(cacheKey, null);
return null;
}
}
if (isString(res)) {
if (REG_FN_REL.test(res)) {
const resolved = resolveRelativeColor(res, opt);
if (isString(resolved)) res = resolved;
else {
setCache(cacheKey, null);
return null;
}
} else if (REG_FN_CALC.test(res)) res = cssCalc(res, opt);
}
if (isString(res)) {
if (res.startsWith("color-mix")) {
const resolvedColorMix = resolveColor(res, {
...opt,
format: VAL_COMP,
nullable: true
});
res = typeof resolvedColorMix === "string" ? resolvedColorMix : null;
}
}
setCache(cacheKey, res);
return res;
};
/**
* converter factory to reduce boilerplate
* @param name - function name for cache
* @param format - color format
* @param convertFn - conversion function
* @returns color converter function
*/
var createColorConverter = (name, format, convertFn) => {
const colorConverterFn = (value, opt = {}) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
const resolved = preProcess(value, opt);
if (resolved === null) return [
0,
0,
0,
0
];
const val = resolved.toLowerCase();
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name,
value: val
}, opt);
const cached = getCache(cacheKey);
if (cached !== false) return cached.item;
const result = convertFn(val, {
...opt,
format
});
setCache(cacheKey, result);
return result;
};
return colorConverterFn;
};
/**
* convert number to hex string
* @param value - numeric value
* @returns hex string: 00..ff
*/
var numberToHex = (value) => numberToHexString(value);
/**
* convert color to hex
* @param value - CSS color value
* @param [opt] - options
* @param [opt.alpha] - enable alpha channel
* @returns #rrggbb | #rrggbbaa | null
*/
var colorToHex = (value, opt = {}) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
const resolved = preProcess(value, opt);
if (resolved === null) return null;
const val = resolved.toLowerCase();
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "colorToHex",
value: val
}, opt);
const cached = getCache(cacheKey);
if (cached !== false) return cached.item;
const hex = resolveColor(val, {
...opt,
nullable: true,
format: opt.alpha ? "hexAlpha" : "hex"
});
if (isString(hex)) {
setCache(cacheKey, hex);
return hex;
}
setCache(cacheKey, null);
return null;
};
/**
* convert color to hsl
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [h, s, l, alpha]
*/
var colorToHsl = createColorConverter("colorToHsl", "hsl", convertColorToHsl);
/**
* convert color to hwb
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [h, w, b, alpha]
*/
var colorToHwb = createColorConverter("colorToHwb", "hwb", convertColorToHwb);
/**
* convert color to lab
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, a, b, alpha]
*/
var colorToLab = createColorConverter("colorToLab", "lab", convertColorToLab);
/**
* convert color to lch
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, c, h, alpha]
*/
var colorToLch = createColorConverter("colorToLch", "lch", convertColorToLch);
/**
* convert color to oklab
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, a, b, alpha]
*/
var colorToOklab = createColorConverter("colorToOklab", "oklab", convertColorToOklab);
/**
* convert color to oklch
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [l, c, h, alpha]
*/
var colorToOklch = createColorConverter("colorToOklch", "oklch", convertColorToOklch);
/**
* convert color to rgb
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [r, g, b, alpha]
*/
var colorToRgb = createColorConverter("colorToRgb", "rgb", convertColorToRgb);
/**
* convert color to xyz
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [x, y, z, alpha]
*/
var colorToXyz = (value, opt = {}) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
const resolved = preProcess(value, opt);
if (resolved === null) return [
0,
0,
0,
0
];
const val = resolved.toLowerCase();
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "colorToXyz",
value: val
}, opt);
const cached = getCache(cacheKey);
if (cached !== false) return cached.item;
let parsed;
if (val.startsWith("color(")) parsed = parseColorFunc(val, opt);
else parsed = parseColorValue(val, opt);
const [, ...xyz] = parsed;
setCache(cacheKey, xyz);
return xyz;
};
/**
* convert color to xyz-d50
* @param value - CSS color value
* @param [opt] - options
* @returns ColorChannels - [x, y, z, alpha]
*/
var colorToXyzD50 = (value, opt = {}) => {
opt.d50 = true;
return colorToXyz(value, opt);
};
var convert = {
colorToHex,
colorToHsl,
colorToHwb,
colorToLab,
colorToLch,
colorToOklab,
colorToOklch,
colorToRgb,
colorToXyz,
colorToXyzD50,
numberToHex
};
//#endregion
export { colorToHex, colorToHsl, colorToHwb, colorToLab, colorToLch, colorToOklab, colorToOklch, colorToRgb, colorToXyz, colorToXyzD50, convert, numberToHex, preProcess };
//# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
{"version":3,"file":"convert.js","names":[],"sources":["../../../src/js/convert.ts"],"sourcesContent":["/**\n * convert\n */\n\nimport { createCacheKey, getCache, setCache } from './cache';\nimport {\n convertColorToHsl,\n convertColorToHwb,\n convertColorToLab,\n convertColorToLch,\n convertColorToOklab,\n convertColorToOklch,\n convertColorToRgb,\n numberToHexString,\n parseColorFunc,\n parseColorValue\n} from './color';\nimport { isString } from './common';\nimport { cssCalc, resolveVar } from './css-calc-var';\nimport { resolveRelativeColor } from './relative-color';\nimport { resolveColor } from './resolve';\nimport { ColorChannels, ComputedColorChannels, Options } from './typedef';\n\n/* constants */\nimport { SYN_FN_CALC, SYN_FN_REL, SYN_FN_VAR, VAL_COMP } from './constant';\nconst NAMESPACE = 'convert';\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_REL = new RegExp(SYN_FN_REL);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * pre process\n * @param value - CSS color value\n * @param [opt] - options\n * @returns value\n */\nexport const preProcess = (value: string, opt: Options = {}): string | null => {\n if (!isString(value)) {\n return null;\n }\n value = value.trim();\n if (!value) {\n return null;\n }\n const cacheKey: string = createCacheKey(\n { namespace: NAMESPACE, name: 'preProcess', value },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult !== false) {\n return cachedResult.item as string | null;\n }\n let res: string | null = value;\n if (REG_FN_VAR.test(value)) {\n const resolved = resolveVar(value, opt);\n if (isString(resolved)) {\n res = resolved;\n } else {\n setCache(cacheKey, null);\n return null;\n }\n }\n if (isString(res)) {\n if (REG_FN_REL.test(res)) {\n const resolved = resolveRelativeColor(res, opt);\n if (isString(resolved)) {\n res = resolved;\n } else {\n setCache(cacheKey, null);\n return null;\n }\n } else if (REG_FN_CALC.test(res)) {\n res = cssCalc(res, opt);\n }\n }\n if (isString(res)) {\n if (res.startsWith('color-mix')) {\n const resolvedColorMix = resolveColor(res, {\n ...opt,\n format: VAL_COMP,\n nullable: true\n });\n res = typeof resolvedColorMix === 'string' ? resolvedColorMix : null;\n }\n }\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * converter factory to reduce boilerplate\n * @param name - function name for cache\n * @param format - color format\n * @param convertFn - conversion function\n * @returns color converter function\n */\nconst createColorConverter = (\n name: string,\n format: string,\n convertFn: Function\n) => {\n const colorConverterFn = (\n value: string,\n opt: Options = {}\n ): ColorChannels => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const resolved = preProcess(value, opt);\n if (resolved === null) {\n return [0, 0, 0, 0];\n }\n const val = resolved.toLowerCase();\n const cacheKey = createCacheKey(\n { namespace: NAMESPACE, name, value: val },\n opt\n );\n const cached = getCache(cacheKey);\n if (cached !== false) {\n return cached.item as ColorChannels;\n }\n const result = convertFn(val, { ...opt, format }) as ColorChannels;\n setCache(cacheKey, result);\n return result;\n };\n return colorConverterFn;\n};\n\n/**\n * convert number to hex string\n * @param value - numeric value\n * @returns hex string: 00..ff\n */\nexport const numberToHex = (value: number): string => numberToHexString(value);\n\n/**\n * convert color to hex\n * @param value - CSS color value\n * @param [opt] - options\n * @param [opt.alpha] - enable alpha channel\n * @returns #rrggbb | #rrggbbaa | null\n */\nexport const colorToHex = (value: string, opt: Options = {}): string | null => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const resolved = preProcess(value, opt);\n if (resolved === null) {\n return null;\n }\n const val = resolved.toLowerCase();\n const cacheKey = createCacheKey(\n { namespace: NAMESPACE, name: 'colorToHex', value: val },\n opt\n );\n const cached = getCache(cacheKey);\n if (cached !== false) {\n return cached.item as string | null;\n }\n const hex = resolveColor(val, {\n ...opt,\n nullable: true,\n format: opt.alpha ? 'hexAlpha' : 'hex'\n });\n if (isString(hex)) {\n setCache(cacheKey, hex);\n return hex;\n }\n setCache(cacheKey, null);\n return null;\n};\n\n/**\n * convert color to hsl\n * @param value - CSS color value\n * @param [opt] - options\n * @returns ColorChannels - [h, s, l, alpha]\n */\nexport const colorToHsl = createColorConverter(\n 'colorToHsl',\n 'hsl',\n convertColorToHsl\n);\n\n/**\n * convert color to hwb\n * @param value - CSS color value\n * @param [opt] - options\n * @returnLine truncated
@@ -0,0 +1,122 @@
import { CSSToken } from '@csstools/css-tokenizer';
import { Options } from './typedef.js';
/**
* Calclator
*/
export declare class Calculator {
#private;
/**
* constructor
*/
constructor();
get hasNum(): boolean;
set hasNum(value: boolean);
get numSum(): number[];
get numMul(): number[];
get hasPct(): boolean;
set hasPct(value: boolean);
get pctSum(): number[];
get pctMul(): number[];
get hasDim(): boolean;
set hasDim(value: boolean);
get dimSum(): string[];
get dimSub(): string[];
get dimMul(): string[];
get dimDiv(): string[];
get hasEtc(): boolean;
set hasEtc(value: boolean);
get etcSum(): string[];
get etcSub(): string[];
get etcMul(): string[];
get etcDiv(): string[];
/**
* clear values
* @returns void
*/
clear(): void;
/**
* sort values
* @param values - values
* @returns sorted values
*/
sort(values?: string[]): string[];
/**
* multiply values
* @returns resolved value
*/
multiply(): string;
/**
* sum values
* @returns resolved value
*/
sum(): string;
}
/**
* sort calc values
* @param values - values to sort
* @param [finalize] - finalize values
* @returns sorted values
*/
export declare const sortCalcValues: (values?: (number | string)[], finalize?: boolean) => string;
/**
* sort math function terms
* @param expr - unwrapped calc expression
* @returns sorted expression
*/
export declare const sortMathFnTerms: (expr: string) => string;
/**
* serialize calc
* @param value - CSS value
* @param [opt] - options
* @returns serialized value
*/
export declare const serializeCalc: (value: string, opt?: Options) => string;
/**
* resolve dimension
* @param token - CSS token
* @param [opt] - options
* @returns resolved value
*/
export declare const resolveDimension: (token: CSSToken, opt?: Options) => string | null;
/**
* parse CSS calc() tokens
* @param tokens - CSS tokens
* @param [opt] - options
* @returns parsed tokens
*/
export declare const parseCalcTokens: (tokens: CSSToken[], opt?: Options) => string[];
/**
* CSS calc()
* @param value - CSS value including calc()
* @param [opt] - options
* @returns resolved value
*/
export declare const cssCalc: (value: string, opt?: Options) => string;
/**
* resolve custom property
* @param tokens - CSS tokens
* @param [opt] - options
* @returns result - [tokens, resolvedValue]
*/
export declare function resolveCustomProperty(tokens: CSSToken[], opt?: Options): [CSSToken[], string];
/**
* parse CSS var() tokens
* @param tokens - CSS tokens
* @param [opt] - options
* @returns parsed tokens
*/
export declare function parseVarTokens(tokens: CSSToken[], opt?: Options): string[] | null;
/**
* resolve CSS var()
* @param value - CSS value including var()
* @param [opt] - options
* @returns resolved value
*/
export declare function resolveVar(value: string, opt?: Options): string | null;
/**
* CSS var()
* @param value - CSS value including var()
* @param [opt] - options
* @returns resolved value
*/
export declare const cssVar: (value: string, opt?: Options) => string;
+859
View File
@@ -0,0 +1,859 @@
import { createCacheKey, getCache, setCache } from "./cache.js";
import { isString, isStringOrNumber } from "./common.js";
import { resolveLengthInPixels, roundToPrecision } from "./util.js";
import { ANGLE, LENGTH, NUM, SYN_FN_CALC, SYN_FN_MATH_START, SYN_FN_VAR, SYN_FN_VAR_START } from "./constant.js";
import { isColor } from "./resolve.js";
import { calc } from "@csstools/css-calc";
import { TokenType, tokenize } from "@csstools/css-tokenizer";
//#region src/js/css-calc-var.ts
/**
* css-calc-var
*/
var { CloseParen: PAREN_CLOSE, Comment: COMMENT, Dimension: DIM, EOF, Function: FUNC, Ident: IDENT, OpenParen: PAREN_OPEN, Whitespace: W_SPACE } = TokenType;
var NAMESPACE = "css-calc-var";
var TRIA = 3;
var HEX = 16;
var REG_FN_CALC = new RegExp(SYN_FN_CALC);
var REG_FN_CALC_NUM = new RegExp(`^calc\\((${NUM})\\)$`);
var REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
var REG_FN_VAR = new RegExp(SYN_FN_VAR);
var REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);
var REG_OPERATOR = /\s[*+/-]\s/;
var REG_PAREN_OPEN = /\($/;
var REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);
var REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);
var REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);
var REG_CSS_WIDE_KEYWORD = /^(?:inherit|initial|revert(?:-layer)?|unset)$/;
/**
* Calclator
*/
var Calculator = class {
#hasNum;
#numSum;
#numMul;
#hasPct;
#pctSum;
#pctMul;
#hasDim;
#dimSum;
#dimSub;
#dimMul;
#dimDiv;
#hasEtc;
#etcSum;
#etcSub;
#etcMul;
#etcDiv;
#calcOpts;
/**
* constructor
*/
constructor() {
this.#hasNum = false;
this.#numSum = [];
this.#numMul = [];
this.#hasPct = false;
this.#pctSum = [];
this.#pctMul = [];
this.#hasDim = false;
this.#dimSum = [];
this.#dimSub = [];
this.#dimMul = [];
this.#dimDiv = [];
this.#hasEtc = false;
this.#etcSum = [];
this.#etcSub = [];
this.#etcMul = [];
this.#etcDiv = [];
this.#calcOpts = { toCanonicalUnits: true };
}
get hasNum() {
return this.#hasNum;
}
set hasNum(value) {
this.#hasNum = !!value;
}
get numSum() {
return this.#numSum;
}
get numMul() {
return this.#numMul;
}
get hasPct() {
return this.#hasPct;
}
set hasPct(value) {
this.#hasPct = !!value;
}
get pctSum() {
return this.#pctSum;
}
get pctMul() {
return this.#pctMul;
}
get hasDim() {
return this.#hasDim;
}
set hasDim(value) {
this.#hasDim = !!value;
}
get dimSum() {
return this.#dimSum;
}
get dimSub() {
return this.#dimSub;
}
get dimMul() {
return this.#dimMul;
}
get dimDiv() {
return this.#dimDiv;
}
get hasEtc() {
return this.#hasEtc;
}
set hasEtc(value) {
this.#hasEtc = !!value;
}
get etcSum() {
return this.#etcSum;
}
get etcSub() {
return this.#etcSub;
}
get etcMul() {
return this.#etcMul;
}
get etcDiv() {
return this.#etcDiv;
}
/**
* clear values
* @returns void
*/
clear() {
this.#hasNum = false;
this.#numSum.length = 0;
this.#numMul.length = 0;
this.#hasPct = false;
this.#pctSum.length = 0;
this.#pctMul.length = 0;
this.#hasDim = false;
this.#dimSum.length = 0;
this.#dimSub.length = 0;
this.#dimMul.length = 0;
this.#dimDiv.length = 0;
this.#hasEtc = false;
this.#etcSum.length = 0;
this.#etcSub.length = 0;
this.#etcMul.length = 0;
this.#etcDiv.length = 0;
}
/**
* sort values
* @param values - values
* @returns sorted values
*/
sort(values = []) {
const arr = [...values];
if (arr.length > 1) arr.sort((a, b) => {
let res;
if (REG_TYPE_DIM_PCT.test(a) && REG_TYPE_DIM_PCT.test(b)) {
const [, valA, unitA] = a.match(REG_TYPE_DIM_PCT);
const [, valB, unitB] = b.match(REG_TYPE_DIM_PCT);
if (unitA === unitB) {
if (Number(valA) === Number(valB)) res = 0;
else if (Number(valA) > Number(valB)) res = 1;
else res = -1;
} else if (unitA > unitB) res = 1;
else res = -1;
} else if (a === b) res = 0;
else if (a > b) res = 1;
else res = -1;
return res;
});
return arr;
}
/**
* multiply values
* @returns resolved value
*/
multiply() {
const value = [];
let num;
if (this.#hasNum) {
num = 1;
for (const i of this.#numMul) {
num *= i;
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) break;
}
if (!this.#hasPct && !this.#hasDim && !this.hasEtc) {
if (Number.isFinite(num)) num = roundToPrecision(num, HEX);
value.push(num);
}
}
if (this.#hasPct) {
if (typeof num !== "number") num = 1;
for (const i of this.#pctMul) {
num *= i;
if (num === 0 || !Number.isFinite(num) || Number.isNaN(num)) break;
}
if (Number.isFinite(num)) num = `${roundToPrecision(num, HEX)}%`;
if (!this.#hasDim && !this.hasEtc) value.push(num);
}
if (this.#hasDim) {
let dim = "";
let mul = "";
let div = "";
if (this.#dimMul.length) {
if (this.#dimMul.length === 1) [mul] = this.#dimMul;
else mul = `${this.sort(this.#dimMul).join(" * ")}`;
}
if (this.#dimDiv.length) {
if (this.#dimDiv.length === 1) [div] = this.#dimDiv;
else div = `${this.sort(this.#dimDiv).join(" * ")}`;
}
if (Number.isFinite(num)) {
if (mul) {
if (div) {
if (div.includes("*")) dim = calc(`calc(${num} * ${mul} / (${div}))`, this.#calcOpts);
else dim = calc(`calc(${num} * ${mul} / ${div})`, this.#calcOpts);
} else dim = calc(`calc(${num} * ${mul})`, this.#calcOpts);
} else if (div.includes("*")) dim = calc(`calc(${num} / (${div}))`, this.#calcOpts);
else dim = calc(`calc(${num} / ${div})`, this.#calcOpts);
value.push(dim.replace(/^calc/, ""));
} else {
if (!value.length && num !== void 0) value.push(num);
if (mul) {
if (div) {
if (div.includes("*")) dim = calc(`calc(${mul} / (${div}))`, this.#calcOpts);
else dim = calc(`calc(${mul} / ${div})`, this.#calcOpts);
} else dim = calc(`calc(${mul})`, this.#calcOpts);
if (value.length) value.push("*", dim.replace(/^calc/, ""));
else value.push(dim.replace(/^calc/, ""));
} else {
dim = calc(`calc(${div})`, this.#calcOpts);
if (value.length) value.push("/", dim.replace(/^calc/, ""));
else value.push("1", "/", dim.replace(/^calc/, ""));
}
}
}
if (this.#hasEtc) {
if (this.#etcMul.length) {
if (!value.length && num !== void 0) value.push(num);
const mul = this.sort(this.#etcMul).join(" * ");
if (value.length) value.push(`* ${mul}`);
else value.push(`${mul}`);
}
if (this.#etcDiv.length) {
const div = this.sort(this.#etcDiv).join(" * ");
if (div.includes("*")) {
if (value.length) value.push(`/ (${div})`);
else value.push(`1 / (${div})`);
} else if (value.length) value.push(`/ ${div}`);
else value.push(`1 / ${div}`);
}
}
if (value.length) return value.join(" ");
return "";
}
/**
* sum values
* @returns resolved value
*/
sum() {
const value = [];
if (this.#hasNum) {
let num = 0;
for (const i of this.#numSum) {
num += i;
if (!Number.isFinite(num) || Number.isNaN(num)) break;
}
value.push(num);
}
if (this.#hasPct) {
let num = 0;
for (const i of this.#pctSum) {
num += i;
if (!Number.isFinite(num)) break;
}
if (Number.isFinite(num)) num = `${num}%`;
if (value.length) value.push(`+ ${num}`);
else value.push(num);
}
if (this.#hasDim) {
let dim, sum, sub;
if (this.#dimSum.length) sum = this.sort(this.#dimSum).join(" + ");
if (this.#dimSub.length) sub = this.sort(this.#dimSub).join(" + ");
if (sum) {
if (sub) {
if (sub.includes("-")) dim = calc(`calc(${sum} - (${sub}))`, this.#calcOpts);
else dim = calc(`calc(${sum} - ${sub})`, this.#calcOpts);
} else dim = calc(`calc(${sum})`, this.#calcOpts);
} else dim = calc(`calc(-1 * (${sub}))`, this.#calcOpts);
if (value.length) value.push("+", dim.replace(/^calc/, ""));
else value.push(dim.replace(/^calc/, ""));
}
if (this.#hasEtc) {
if (this.#etcSum.length) {
const sum = this.sort(this.#etcSum).map((item) => {
let res;
if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) res = `(${item})`;
else res = item;
return res;
}).join(" + ");
if (value.length) {
if (this.#etcSum.length > 1) value.push(`+ (${sum})`);
else value.push(`+ ${sum}`);
} else value.push(`${sum}`);
}
if (this.#etcSub.length) {
const sub = this.sort(this.#etcSub).map((item) => {
let res;
if (REG_OPERATOR.test(item) && !item.startsWith("(") && !item.endsWith(")")) res = `(${item})`;
else res = item;
return res;
}).join(" + ");
if (value.length) {
if (this.#etcSub.length > 1) value.push(`- (${sub})`);
else value.push(`- ${sub}`);
} else if (this.#etcSub.length > 1) value.push(`-1 * (${sub})`);
else value.push(`-1 * ${sub}`);
}
}
if (value.length) return value.join(" ");
return "";
}
};
/**
* sort calc values
* @param values - values to sort
* @param [finalize] - finalize values
* @returns sorted values
*/
var sortCalcValues = (values = [], finalize = false) => {
if (values.length < TRIA) throw new Error(`Unexpected array length ${values.length}.`);
const start = values.shift();
if (!isString(start) || !start.endsWith("(")) throw new Error(`Unexpected token ${start}.`);
const end = values.pop();
if (end !== ")") throw new Error(`Unexpected token ${end}.`);
if (values.length === 1) {
const [value] = values;
if (!isStringOrNumber(value)) throw new Error(`Unexpected token ${value}.`);
return `${start}${value}${end}`;
}
const sortedValues = [];
const cal = new Calculator();
let operator = "";
const l = values.length;
let hasAddSub = false;
for (let i = 0; i < l; i++) {
const value = values[i];
if (!isStringOrNumber(value)) throw new Error(`Unexpected token ${value}.`);
if (value === "*" || value === "/") operator = value;
else if (value === "+" || value === "-") {
const sortedValue = cal.multiply();
if (sortedValue) sortedValues.push(sortedValue, value);
hasAddSub = true;
cal.clear();
operator = "";
} else {
const numValue = Number(value);
const strValue = `${value}`;
switch (operator) {
case "/":
if (Number.isFinite(numValue)) {
cal.hasNum = true;
cal.numMul.push(1 / numValue);
} else if (REG_TYPE_PCT.test(strValue)) {
const [, val] = strValue.match(REG_TYPE_PCT);
cal.hasPct = true;
cal.pctMul.push(1e4 / Number(val));
} else if (REG_TYPE_DIM.test(strValue)) {
cal.hasDim = true;
cal.dimDiv.push(strValue);
} else {
cal.hasEtc = true;
cal.etcDiv.push(strValue);
}
break;
default: if (Number.isFinite(numValue)) {
cal.hasNum = true;
cal.numMul.push(numValue);
} else if (REG_TYPE_PCT.test(strValue)) {
const [, val] = strValue.match(REG_TYPE_PCT);
cal.hasPct = true;
cal.pctMul.push(Number(val));
} else if (REG_TYPE_DIM.test(strValue)) {
cal.hasDim = true;
cal.dimMul.push(strValue);
} else {
cal.hasEtc = true;
cal.etcMul.push(strValue);
}
}
}
if (i === l - 1) {
const sortedValue = cal.multiply();
if (sortedValue) sortedValues.push(sortedValue);
cal.clear();
operator = "";
}
}
let resolvedValue = "";
if (finalize && hasAddSub) {
const finalizedValues = [];
cal.clear();
operator = "";
const l = sortedValues.length;
for (let i = 0; i < l; i++) {
const value = sortedValues[i];
if (isStringOrNumber(value)) {
if (value === "+" || value === "-") operator = value;
else {
const numValue = Number(value);
const strValue = `${value}`;
switch (operator) {
case "-":
if (Number.isFinite(numValue)) {
cal.hasNum = true;
cal.numSum.push(-1 * numValue);
} else if (REG_TYPE_PCT.test(strValue)) {
const [, val] = strValue.match(REG_TYPE_PCT);
cal.hasPct = true;
cal.pctSum.push(-1 * Number(val));
} else if (REG_TYPE_DIM.test(strValue)) {
cal.hasDim = true;
cal.dimSub.push(strValue);
} else {
cal.hasEtc = true;
cal.etcSub.push(strValue);
}
break;
default: if (Number.isFinite(numValue)) {
cal.hasNum = true;
cal.numSum.push(numValue);
} else if (REG_TYPE_PCT.test(strValue)) {
const [, val] = strValue.match(REG_TYPE_PCT);
cal.hasPct = true;
cal.pctSum.push(Number(val));
} else if (REG_TYPE_DIM.test(strValue)) {
cal.hasDim = true;
cal.dimSum.push(strValue);
} else {
cal.hasEtc = true;
cal.etcSum.push(strValue);
}
}
}
}
if (i === l - 1) {
const sortedValue = cal.sum();
if (sortedValue) finalizedValues.push(sortedValue);
cal.clear();
operator = "";
}
}
resolvedValue = finalizedValues.join(" ").replace(/\+\s-/g, "- ");
} else resolvedValue = sortedValues.join(" ").replace(/\+\s-/g, "- ");
if (resolvedValue.startsWith("(") && resolvedValue.endsWith(")") && resolvedValue.lastIndexOf("(") === 0 && resolvedValue.indexOf(")") === resolvedValue.length - 1) resolvedValue = resolvedValue.substring(1, resolvedValue.length - 1);
return `${start}${resolvedValue}${end}`;
};
/**
* sort math function terms
* @param expr - unwrapped calc expression
* @returns sorted expression
*/
var sortMathFnTerms = (expr) => {
const tokens = tokenize({ css: expr });
const terms = [];
let currentTerm = "";
let currentSign = "";
let depth = 0;
for (const token of tokens) {
const [type, value] = token;
if (type === PAREN_OPEN || type === FUNC) depth++;
else if (type === PAREN_CLOSE) depth--;
if (depth === 0 && (value === "+" || value === "-")) {
if (currentTerm.trim()) terms.push((currentSign === "-" ? "-" : "") + currentTerm.trim());
currentTerm = "";
currentSign = value;
continue;
}
currentTerm += value;
}
if (currentTerm.trim()) terms.push((currentSign === "-" ? "-" : "") + currentTerm.trim());
terms.sort((a, b) => {
const reg = /^(-?(?:\d+(?:\.\d+)?|\.\d+))([a-z%]*)$/i;
const matchA = a.match(reg);
const matchB = b.match(reg);
if (matchA && matchB) {
const numA = Number(matchA[1] || "0");
const numB = Number(matchB[1] || "0");
const unitA = matchA[2] || "";
const unitB = matchB[2] || "";
if (unitA === unitB) return numA - numB;
return unitA > unitB ? 1 : -1;
}
if (a === b) return 0;
return a > b ? 1 : -1;
});
const firstTerm = terms[0];
if (firstTerm === void 0) return expr;
let res = firstTerm;
for (let i = 1; i < terms.length; i++) {
const term = terms[i];
if (term !== void 0) {
if (term.startsWith("-")) res += " - " + term.substring(1);
else res += " + " + term;
}
}
return res;
};
/**
* resolve AST node
* @param node - AST node
* @param isRoot - is root node
* @returns resolved value
*/
var resolveNode = (node, isRoot) => {
const firstItemRaw = node[0];
const isCommaMathFnNode = isString(firstItemRaw) && REG_FN_MATH_START.test(firstItemRaw);
const flatItems = [];
for (const item of node) if (Array.isArray(item)) flatItems.push(resolveNode(item, isCommaMathFnNode));
else flatItems.push(item);
const hasComma = flatItems.includes(",");
const firstItem = flatItems[0] || "";
const isCommaMathFn = isString(firstItem) && REG_FN_MATH_START.test(firstItem);
if (hasComma && isCommaMathFn && flatItems[flatItems.length - 1] === ")") {
const fnName = flatItems.shift();
const fnEnd = flatItems.pop();
const args = [];
let currentArg = [];
for (const item of flatItems) if (item === ",") {
args.push(currentArg);
currentArg = [];
} else currentArg.push(item);
if (currentArg.length) args.push(currentArg);
return `${fnName}${args.map((argNodes) => {
if (argNodes.length >= TRIA) {
const sorted = sortCalcValues([
"calc(",
...argNodes,
")"
], true);
return sortMathFnTerms(sorted.substring(5, sorted.length - 1));
} else if (argNodes.length === 1) {
const item = argNodes[0];
if (isString(item) && item.startsWith("calc(") && item.endsWith(")")) return sortMathFnTerms(item.substring(5, item.length - 1));
}
return argNodes.join("");
}).join(", ")}${fnEnd}`;
}
if (isRoot) {
if (!hasComma) {
if (flatItems.length >= TRIA) return sortCalcValues(flatItems, true);
const first = flatItems[0] || "";
if (isString(first) && first.endsWith("(")) {
const joined = flatItems.join("");
return joined.startsWith("calc(") || /^[a-z-]+\(/.test(joined) ? joined : `calc(${joined})`;
}
return isString(first) && (first.startsWith("calc(") || /^[a-z-]+\(/.test(first)) ? first : `calc(${first})`;
}
return flatItems.join("").replace(/,\s*/g, ", ");
}
if (flatItems.length >= TRIA && !hasComma) {
let serialized = sortCalcValues(flatItems, false);
if (REG_FN_VAR_START.test(serialized)) serialized = calc(serialized, { toCanonicalUnits: true });
return serialized;
}
return flatItems.join("").replace(/,\s*/g, ", ");
};
/**
* serialize calc
* @param value - CSS value
* @param [opt] - options
* @returns serialized value
*/
var serializeCalc = (value, opt = {}) => {
const { format = "" } = opt;
if (isString(value)) {
if (!REG_FN_VAR_START.test(value) || format !== "specifiedValue") return value;
value = value.toLowerCase().trim();
} else throw new TypeError(`${value} is not a string.`);
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "serializeCalc",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
const items = tokenize({ css: value }).map((token) => {
const [type, val] = token;
let res = "";
if (type !== W_SPACE && type !== COMMENT) res = val;
return res;
}).filter((v) => v);
const stack = [[]];
for (const item of items) if (REG_PAREN_OPEN.test(item)) {
const newNode = [item];
const parent = stack[stack.length - 1];
if (parent) parent.push(newNode);
stack.push(newNode);
} else if (item === ")") {
if (stack.length > 1) {
const currentLevel = stack.pop();
if (currentLevel) currentLevel.push(item);
} else {
const root = stack[0];
if (root) root.push(item);
}
} else {
const parent = stack[stack.length - 1];
if (parent) parent.push(item);
}
let serializedCalc = "";
const rootItems = stack[0];
if (rootItems) {
if (rootItems.length === 1 && Array.isArray(rootItems[0])) serializedCalc = resolveNode(rootItems[0], true);
else serializedCalc = resolveNode(rootItems, true);
}
setCache(cacheKey, serializedCalc);
return serializedCalc;
};
/**
* resolve dimension
* @param token - CSS token
* @param [opt] - options
* @returns resolved value
*/
var resolveDimension = (token, opt = {}) => {
if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`);
const [, , , , detail = {}] = token;
const { unit, value } = detail;
if (unit === "px") return `${value}${unit}`;
const pixelValue = resolveLengthInPixels(Number(value), unit, opt);
if (Number.isFinite(pixelValue)) return `${roundToPrecision(pixelValue, HEX)}px`;
return null;
};
/**
* parse CSS calc() tokens
* @param tokens - CSS tokens
* @param [opt] - options
* @returns parsed tokens
*/
var parseCalcTokens = (tokens, opt = {}) => {
if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`);
const { format = "" } = opt;
const mathFunc = /* @__PURE__ */ new Set();
let nest = 0;
const res = [];
for (const token of tokens) {
if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`);
const [type = "", value = ""] = token;
switch (type) {
case DIM:
if (format === "specifiedValue" && !mathFunc.has(nest)) res.push(value);
else {
const resolvedValue = resolveDimension(token, opt);
if (isString(resolvedValue)) res.push(resolvedValue);
else res.push(value);
}
break;
case FUNC:
case PAREN_OPEN:
res.push(value);
nest++;
if (REG_FN_MATH_START.test(value)) mathFunc.add(nest);
break;
case PAREN_CLOSE:
if (res.length) {
if (res[res.length - 1] === " ") res.splice(-1, 1, value);
else res.push(value);
} else res.push(value);
if (mathFunc.has(nest)) mathFunc.delete(nest);
nest--;
break;
case W_SPACE:
if (res.length) {
const lastValue = res[res.length - 1];
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") res.push(value);
}
break;
default: if (type !== COMMENT && type !== EOF) res.push(value);
}
}
return res;
};
/**
* CSS calc()
* @param value - CSS value including calc()
* @param [opt] - options
* @returns resolved value
*/
var cssCalc = (value, opt = {}) => {
const { format = "" } = opt;
if (isString(value)) {
if (REG_FN_VAR.test(value)) {
if (format === "specifiedValue") return value;
else {
const resolvedValue = resolveVar(value, opt);
if (isString(resolvedValue)) return resolvedValue;
else return "";
}
} else if (!REG_FN_CALC.test(value)) return value;
value = value.toLowerCase().trim();
} else throw new TypeError(`${value} is not a string.`);
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "cssCalc",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
const values = parseCalcTokens(tokenize({ css: value }), opt);
let resolvedValue = calc(values.join(""), { toCanonicalUnits: true });
if (REG_FN_VAR_START.test(value)) {
if (REG_TYPE_DIM_PCT.test(resolvedValue)) {
const [, val, unit] = resolvedValue.match(REG_TYPE_DIM_PCT);
resolvedValue = `${roundToPrecision(Number(val), HEX)}${unit}`;
}
if (resolvedValue && !REG_FN_VAR_START.test(resolvedValue) && format === "specifiedValue") resolvedValue = `calc(${resolvedValue})`;
}
if (format === "specifiedValue") {
if (/\s[-+*/]\s/.test(resolvedValue) && !resolvedValue.includes("NaN")) resolvedValue = serializeCalc(resolvedValue, opt);
else if (REG_FN_CALC_NUM.test(resolvedValue)) {
const [, val] = resolvedValue.match(REG_FN_CALC_NUM);
resolvedValue = `calc(${roundToPrecision(Number(val), HEX)})`;
}
}
setCache(cacheKey, resolvedValue);
return resolvedValue;
};
/**
* resolve custom property
* @param tokens - CSS tokens
* @param [opt] - options
* @returns result - [tokens, resolvedValue]
*/
function resolveCustomProperty(tokens, opt = {}) {
if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`);
const { customProperty = {} } = opt;
const items = [];
while (tokens.length) {
const token = tokens.shift();
if (!token) break;
if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`);
const [type, value] = token;
if (type === PAREN_CLOSE) break;
if (value === "var(") {
const [, item] = resolveCustomProperty(tokens, opt);
if (item) items.push(item);
} else if (type === IDENT) {
if (value.startsWith("--")) {
let item;
if (Object.hasOwn(customProperty, value)) item = customProperty[value];
else if (typeof customProperty.callback === "function") item = customProperty.callback(value);
if (item) items.push(item);
} else if (value) items.push(value);
}
}
let resolveAsColor = false;
if (items.length > 1) resolveAsColor = isColor(items[items.length - 1]);
let resolvedValue = "";
for (let item of items) {
item = item.trim();
if (REG_FN_VAR.test(item)) {
const resolvedItem = resolveVar(item, opt);
if (isString(resolvedItem)) {
if (!resolveAsColor || isColor(resolvedItem)) resolvedValue = resolvedItem;
}
} else if (REG_FN_CALC.test(item)) {
item = cssCalc(item, opt);
if (!resolveAsColor || isColor(item)) resolvedValue = item;
} else if (item && !REG_CSS_WIDE_KEYWORD.test(item)) {
if (!resolveAsColor || isColor(item)) resolvedValue = item;
}
if (resolvedValue) break;
}
return [tokens, resolvedValue];
}
/**
* parse CSS var() tokens
* @param tokens - CSS tokens
* @param [opt] - options
* @returns parsed tokens
*/
function parseVarTokens(tokens, opt = {}) {
const res = [];
while (tokens.length) {
const token = tokens.shift();
if (!token) break;
const [type = "", value = ""] = token;
if (value === "var(") {
const [, resolvedValue] = resolveCustomProperty(tokens, opt);
if (!resolvedValue) return null;
res.push(resolvedValue);
} else switch (type) {
case PAREN_CLOSE:
if (res.length) {
if (res[res.length - 1] === " ") res[res.length - 1] = value;
else res.push(value);
} else res.push(value);
break;
case W_SPACE:
if (res.length) {
const lastValue = res[res.length - 1];
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") res.push(value);
}
break;
default: if (type !== COMMENT && type !== EOF) res.push(value);
}
}
return res;
}
/**
* resolve CSS var()
* @param value - CSS value including var()
* @param [opt] - options
* @returns resolved value
*/
function resolveVar(value, opt = {}) {
const { format = "" } = opt;
if (isString(value)) {
if (!REG_FN_VAR.test(value) || format === "specifiedValue") return value;
value = value.trim();
} else throw new TypeError(`${value} is not a string.`);
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "resolveVar",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
const values = parseVarTokens(tokenize({ css: value }), opt);
if (Array.isArray(values)) {
let color = values.join("");
if (REG_FN_CALC.test(color)) color = cssCalc(color, opt);
setCache(cacheKey, color);
return color;
} else {
setCache(cacheKey, null);
return null;
}
}
/**
* CSS var()
* @param value - CSS value including var()
* @param [opt] - options
* @returns resolved value
*/
var cssVar = (value, opt = {}) => {
const resolvedValue = resolveVar(value, opt);
if (isString(resolvedValue)) return resolvedValue;
return "";
};
//#endregion
export { Calculator, cssCalc, cssVar, parseCalcTokens, parseVarTokens, resolveCustomProperty, resolveDimension, resolveVar, serializeCalc, sortCalcValues, sortMathFnTerms };
//# sourceMappingURL=css-calc-var.js.map
@@ -0,0 +1 @@
{"version":3,"file":"css-calc-var.js","names":["#hasNum","#numSum","#numMul","#hasPct","#pctSum","#pctMul","#hasDim","#dimSum","#dimSub","#dimMul","#dimDiv","#hasEtc","#etcSum","#etcSub","#etcMul","#etcDiv","#calcOpts"],"sources":["../../../src/js/css-calc-var.ts"],"sourcesContent":["/**\n * css-calc-var\n */\n\nimport { calc, conversionOptions as CalcOptions } from '@csstools/css-calc';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport { createCacheKey, getCache, setCache } from './cache';\nimport { isString, isStringOrNumber } from './common';\nimport { isColor } from './resolve';\nimport { resolveLengthInPixels, roundToPrecision } from './util';\nimport { MatchedRegExp, Options } from './typedef';\n\n/* constants */\nimport {\n ANGLE,\n FN_VAR,\n LENGTH,\n NUM,\n SYN_FN_CALC,\n SYN_FN_MATH_START,\n SYN_FN_VAR,\n SYN_FN_VAR_START,\n VAL_SPEC\n} from './constant';\n\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n Dimension: DIM,\n EOF,\n Function: FUNC,\n Ident: IDENT,\n OpenParen: PAREN_OPEN,\n Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'css-calc-var';\n\n/* numeric constants */\nconst TRIA = 3;\nconst HEX = 16;\nconst MAX_PCT = 100;\n\n/* regexp */\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_CALC_NUM = new RegExp(`^calc\\\\((${NUM})\\\\)$`);\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\nconst REG_FN_VAR_START = new RegExp(SYN_FN_VAR_START);\nconst REG_OPERATOR = /\\s[*+/-]\\s/;\nconst REG_PAREN_OPEN = /\\($/;\nconst REG_TYPE_DIM = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH})$`);\nconst REG_TYPE_DIM_PCT = new RegExp(`^(${NUM})(${ANGLE}|${LENGTH}|%)$`);\nconst REG_TYPE_PCT = new RegExp(`^(${NUM})%$`);\nconst REG_CSS_WIDE_KEYWORD = /^(?:inherit|initial|revert(?:-layer)?|unset)$/;\n\n/**\n * @type CalcASTNode - AST node for calc()\n */\ntype CalcASTNode = string | CalcASTNode[];\n\n/**\n * Calclator\n */\nexport class Calculator {\n /* private */\n // number\n #hasNum: boolean;\n #numSum: number[];\n #numMul: number[];\n // percentage\n #hasPct: boolean;\n #pctSum: number[];\n #pctMul: number[];\n // dimension\n #hasDim: boolean;\n #dimSum: string[];\n #dimSub: string[];\n #dimMul: string[];\n #dimDiv: string[];\n // et cetra\n #hasEtc: boolean;\n #etcSum: string[];\n #etcSub: string[];\n #etcMul: string[];\n #etcDiv: string[];\n // calc options\n #calcOpts: CalcOptions;\n\n /**\n * constructor\n */\n constructor() {\n // number\n this.#hasNum = false;\n this.#numSum = [];\n this.#numMul = [];\n // percentage\n this.#hasPct = false;\n this.#pctSum = [];\n this.#pctMul = [];\n // dimension\n this.#hasDim = false;\n this.#dimSum = [];\n this.#dimSub = [];\n this.#dimMul = [];\n this.#dimDiv = [];\n // et cetra\n this.#hasEtc = false;\n this.#etcSum = [];\n this.#etcSub = [];\n this.#etcMul = [];\n this.#etcDiv = [];\n // calc options\n this.#calcOpts = {\n toCanonicalUnits: true\n };\n }\n\n get hasNum() {\n return this.#hasNum;\n }\n\n set hasNum(value: boolean) {\n this.#hasNum = !!value;\n }\n\n get numSum() {\n return this.#numSum;\n }\n\n get numMul() {\n return this.#numMul;\n }\n\n get hasPct() {\n return this.#hasPct;\n }\n\n set hasPct(value: boolean) {\n this.#hasPct = !!value;\n }\n\n get pctSum() {\n return this.#pctSum;\n }\n\n get pctMul() {\n return this.#pctMul;\n }\n\n get hasDim() {\n return this.#hasDim;\n }\n\n set hasDim(value: boolean) {\n this.#hasDim = !!value;\n }\n\n get dimSum() {\n return this.#dimSum;\n }\n\n get dimSub() {\n return this.#dimSub;\n }\n\n get dimMul() {\n return this.#dimMul;\n }\n\n get dimDiv() {\n return this.#dimDiv;\n }\n\n get hasEtc() {\n return this.#hasEtc;\n }\n\n set hasEtc(value: boolean) {\n this.#hasEtc = !!value;\n }\n\n get etcSum() {\n return this.#etcSum;\n }\n\n get etcSub() {\n return this.#etcSub;\n }\n\n get etcMul() {\n return this.#etcMul;\n }\n\n get etcDiv() {\n return this.#etcDiv;\n }\n\n /**\n * clear values\n * @returns void\n */\n clear() {\n // number\n this.#hasNum = false;\n this.#numSum.length = 0;\n this.#numMul.length = 0;\n // percentage\n this.#hasPct = false;\n this.#pctSum.length = 0;\n this.#pctMul.length = 0;\n // dimension\n this.#hasDim = false;\n this.#dimSum.length = 0;\n this.#dimSub.length = 0;\n this.#dimMul.length = 0;\n this.#dimDiv.length = 0;\n // et cetra\n this.#hasEtc = false;\n this.#etcSum.length = 0;\n this.#etcSub.length = 0;\n this.#etcMul.length = 0;\n this.#etcDiv.length = 0;\n }\n\n /**\n * sort values\n * @param values - values\n * @returns sorted values\n */\n sort(values: string[] = []): string[] {\n const arr = [...values];\n if (arr.length > 1) {\n arr.sort((a, b) => {\Line truncated
@@ -0,0 +1,79 @@
import { Options } from './typedef.js';
/**
* @type ColorStopList - list of color stops
*/
type ColorStopList = [string, string, ...string[]];
/**
* @typedef ValidateGradientLine - validate gradient line
* @property line - gradient line
* @property valid - result
*/
interface ValidateGradientLine {
line: string;
valid: boolean;
}
/**
* @typedef ValidateColorStops - validate color stops
* @property colorStops - list of color stops
* @property valid - result
*/
interface ValidateColorStops {
colorStops: string[];
valid: boolean;
}
/**
* @typedef Gradient - parsed CSS gradient
* @property value - input value
* @property type - gradient type
* @property [gradientLine] - gradient line
* @property colorStopList - list of color stops
*/
interface Gradient {
value: string;
type: string;
gradientLine?: string;
colorStopList: ColorStopList;
}
/**
* get gradient type
* @param value - gradient value
* @returns gradient type
*/
export declare const getGradientType: (value: string) => string;
/**
* validate gradient line
* @param value - gradient line value
* @param type - gradient type
* @returns result
*/
export declare const validateGradientLine: (value: string, type: string) => ValidateGradientLine;
/**
* validate color stop list
* @param list
* @param type
* @param [opt]
* @returns result
*/
export declare const validateColorStopList: (list: string[], type: string, opt?: Options) => ValidateColorStops;
/**
* parse CSS gradient
* @param value - gradient value
* @param [opt] - options
* @returns parsed result
*/
export declare const parseGradient: (value: string, opt?: Options) => Gradient | null;
/**
* resolve CSS gradient
* @param value - CSS value
* @param [opt] - options
* @returns result
*/
export declare const resolveGradient: (value: string, opt?: Options) => string;
/**
* is CSS gradient
* @param value - CSS value
* @param [opt] - options
* @returns result
*/
export declare const isGradient: (value: string, opt?: Options) => boolean;
export {};
+289
View File
@@ -0,0 +1,289 @@
import { createCacheKey, getCache, setCache } from "./cache.js";
import { isString } from "./common.js";
import { splitValue } from "./util.js";
import { ANGLE, CS_HUE, CS_RECT, LENGTH, NUM, NUM_POSITIVE, PCT, VAL_COMP } from "./constant.js";
import { isColor, resolveColor } from "./resolve.js";
//#region src/js/css-gradient.ts
/**
* css-gradient
*/
var NAMESPACE = "css-gradient";
var DIM_ANGLE = `${NUM}(?:${ANGLE})`;
var DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`;
var DIM_LEN_PCT = `${`${NUM}(?:${LENGTH})|0`}|${PCT}`;
var DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`;
var DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`;
var CTR = "center";
var L_R = "left|right";
var T_B = "top|bottom";
var S_E = "start|end";
var AXIS_X = `${L_R}|x-(?:${S_E})`;
var AXIS_Y = `${T_B}|y-(?:${S_E})`;
var BLOCK = `block-(?:${S_E})`;
var INLINE = `inline-(?:${S_E})`;
var POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`;
var POS_2 = [
`(?:${CTR}|${AXIS_X})\\s+(?:${CTR}|${AXIS_Y})`,
`(?:${CTR}|${AXIS_Y})\\s+(?:${CTR}|${AXIS_X})`,
`(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`,
`(?:${CTR}|${BLOCK})\\s+(?:${CTR}|${INLINE})`,
`(?:${CTR}|${INLINE})\\s+(?:${CTR}|${BLOCK})`,
`(?:${CTR}|${S_E})\\s+(?:${CTR}|${S_E})`
].join("|");
var POS_4 = [
`(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})`,
`(?:${AXIS_Y})\\s+(?:${DIM_LEN_PCT})\\s+(?:${AXIS_X})\\s+(?:${DIM_LEN_PCT})`,
`(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})\\s+(?:${INLINE})\\s+(?:${DIM_LEN_PCT})`,
`(?:${INLINE})\\s+(?:${DIM_LEN_PCT})\\s+(?:${BLOCK})\\s+(?:${DIM_LEN_PCT})`,
`(?:${S_E})\\s+(?:${DIM_LEN_PCT})\\s+(?:${S_E})\\s+(?:${DIM_LEN_PCT})`
].join("|");
var RAD_EXTENT = "(?:clos|farth)est-(?:corner|side)";
var RAD_SIZE = [
`${RAD_EXTENT}(?:\\s+${RAD_EXTENT})?`,
`${DIM_LEN_POSI}`,
`(?:${DIM_LEN_PCT_POSI})\\s+(?:${DIM_LEN_PCT_POSI})`
].join("|");
var RAD_SHAPE = "circle|ellipse";
var FROM_ANGLE = `from\\s+${DIM_ANGLE}`;
var AT_POSITION = `at\\s+(?:${POS_1}|${POS_2}|${POS_4})`;
var TO_SIDE_CORNER = `to\\s+(?:(?:${L_R})(?:\\s(?:${T_B}))?|(?:${T_B})(?:\\s(?:${L_R}))?)`;
var IN_COLOR_SPACE = `in\\s+(?:${CS_RECT}|${CS_HUE})`;
var LINE_SYNTAX_LINEAR = [`(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\s+${IN_COLOR_SPACE})?`, `${IN_COLOR_SPACE}(?:\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`].join("|");
var LINE_SYNTAX_RADIAL = [
`(?:${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
`(?:${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
`${IN_COLOR_SPACE}(?:\\s+${RAD_SHAPE})(?:\\s+(?:${RAD_SIZE}))?(?:\\s+${AT_POSITION})?`,
`${IN_COLOR_SPACE}(?:\\s+${RAD_SIZE})(?:\\s+(?:${RAD_SHAPE}))?(?:\\s+${AT_POSITION})?`,
`${IN_COLOR_SPACE}(?:\\s+${AT_POSITION})?`
].join("|");
var LINE_SYNTAX_CONIC = [
`${FROM_ANGLE}(?:\\s+${AT_POSITION})?(?:\\s+${IN_COLOR_SPACE})?`,
`${AT_POSITION}(?:\\s+${IN_COLOR_SPACE})?`,
`${IN_COLOR_SPACE}(?:\\s+${FROM_ANGLE})?(?:\\s+${AT_POSITION})?`
].join("|");
var DEFAULT_LINEAR = [/to\s+bottom/];
var DEFAULT_RADIAL = [
/ellipse/,
/farthest-corner/,
/at\s+center/
];
var DEFAULT_CONIC = [/at\s+center/];
var IS_CONIC = /^(?:repeating-)?conic-gradient$/;
var IS_LINEAR = /^(?:repeating-)?linear-gradient$/;
var IS_RADIAL = /^(?:repeating-)?radial-gradient$/;
var REG_COLOR_HINT_CONIC = new RegExp(`^(?:${DIM_ANGLE_PCT})$`);
var REG_COLOR_HINT_NON_CONIC = new RegExp(`^(?:${DIM_LEN_PCT})$`);
var REG_DIM_CONIC = new RegExp(`(?:\\s+(?:${DIM_ANGLE_PCT})){1,2}$`);
var REG_DIM_NON_CONIC = new RegExp(`(?:\\s+(?:${DIM_LEN_PCT})){1,2}$`);
var REG_GRAD = /^(?:repeating-)?(?:conic|linear|radial)-gradient\(/;
var REG_GRAD_CAPT = /^((?:repeating-)?(?:conic|linear|radial)-gradient)\(/;
var REG_LINE_CONIC = new RegExp(`^(?:${LINE_SYNTAX_CONIC})$`);
var REG_LINE_LINEAR = new RegExp(`^(?:${LINE_SYNTAX_LINEAR})$`);
var REG_LINE_RADIAL = new RegExp(`^(?:${LINE_SYNTAX_RADIAL})$`);
/**
* get gradient type
* @param value - gradient value
* @returns gradient type
*/
var getGradientType = (value) => {
if (isString(value)) {
value = value.trim();
if (REG_GRAD.test(value)) {
const [, type] = value.match(REG_GRAD_CAPT);
return type;
}
}
return "";
};
/**
* validate gradient line
* @param value - gradient line value
* @param type - gradient type
* @returns result
*/
var validateGradientLine = (value, type) => {
if (isString(value) && isString(type)) {
value = value.trim();
type = type.trim();
let reg = null;
let defaultValues = [];
if (IS_LINEAR.test(type)) {
reg = REG_LINE_LINEAR;
defaultValues = DEFAULT_LINEAR;
} else if (IS_RADIAL.test(type)) {
reg = REG_LINE_RADIAL;
defaultValues = DEFAULT_RADIAL;
} else if (IS_CONIC.test(type)) {
reg = REG_LINE_CONIC;
defaultValues = DEFAULT_CONIC;
}
if (reg) {
const valid = reg.test(value);
if (valid) {
let line = value;
for (const defaultValue of defaultValues) line = line.replace(defaultValue, "");
line = line.replace(/\s{2,}/g, " ").trim();
return {
line,
valid
};
}
return {
valid,
line: value
};
}
}
return {
line: value,
valid: false
};
};
/**
* validate color stop list
* @param list
* @param type
* @param [opt]
* @returns result
*/
var validateColorStopList = (list, type, opt = {}) => {
if (Array.isArray(list) && list.length > 1) {
const isConic = IS_CONIC.test(type);
const regColorHint = isConic ? REG_COLOR_HINT_CONIC : REG_COLOR_HINT_NON_CONIC;
const regDimension = isConic ? REG_DIM_CONIC : REG_DIM_NON_CONIC;
const valueList = [];
let prevType = "";
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (isString(item)) {
if (regColorHint.test(item)) {
if (i === 0 || prevType === "hint") return {
colorStops: list,
valid: false
};
prevType = "hint";
valueList.push(item);
} else {
const itemColor = item.replace(regDimension, "");
if (isColor(itemColor, { format: "specifiedValue" })) {
const resolvedColor = resolveColor(itemColor, opt);
prevType = "color";
valueList.push(item.replace(itemColor, resolvedColor));
} else return {
colorStops: list,
valid: false
};
}
} else return {
colorStops: list,
valid: false
};
}
if (prevType !== "color") return {
colorStops: list,
valid: false
};
return {
valid: true,
colorStops: valueList
};
}
return {
colorStops: list,
valid: false
};
};
/**
* parse CSS gradient
* @param value - gradient value
* @param [opt] - options
* @returns parsed result
*/
var parseGradient = (value, opt = {}) => {
if (isString(value)) {
value = value.trim();
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "parseGradient",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
const type = getGradientType(value);
const gradValue = value.replace(REG_GRAD, "").replace(/\)$/, "");
if (type && gradValue) {
const [lineOrColorStop = "", ...itemList] = splitValue(gradValue, { delimiter: "," });
const regDimension = IS_CONIC.test(type) ? REG_DIM_CONIC : REG_DIM_NON_CONIC;
let colorStop = "";
if (regDimension.test(lineOrColorStop)) {
const itemColor = lineOrColorStop.replace(regDimension, "");
if (isColor(itemColor, { format: "specifiedValue" })) {
const resolvedColor = resolveColor(itemColor, opt);
colorStop = lineOrColorStop.replace(itemColor, resolvedColor);
}
} else if (isColor(lineOrColorStop, { format: "specifiedValue" })) colorStop = resolveColor(lineOrColorStop, opt);
if (colorStop) {
itemList.unshift(colorStop);
const { colorStops, valid } = validateColorStopList(itemList, type, opt);
if (valid) {
const res = {
value,
type,
colorStopList: colorStops
};
setCache(cacheKey, res);
return res;
}
} else if (itemList.length > 1) {
const { line: gradientLine, valid: validLine } = validateGradientLine(lineOrColorStop, type);
const { colorStops, valid: validColorStops } = validateColorStopList(itemList, type, opt);
if (validLine && validColorStops) {
const res = {
value,
type,
gradientLine,
colorStopList: colorStops
};
setCache(cacheKey, res);
return res;
}
}
}
setCache(cacheKey, null);
return null;
}
return null;
};
/**
* resolve CSS gradient
* @param value - CSS value
* @param [opt] - options
* @returns result
*/
var resolveGradient = (value, opt = {}) => {
const { format = VAL_COMP } = opt;
const gradient = parseGradient(value, opt);
if (gradient) {
const { type = "", gradientLine = "", colorStopList = [] } = gradient;
if (type && Array.isArray(colorStopList) && colorStopList.length > 1) {
if (gradientLine) return `${type}(${gradientLine}, ${colorStopList.join(", ")})`;
return `${type}(${colorStopList.join(", ")})`;
}
}
if (format === "specifiedValue") return "";
return "none";
};
/**
* is CSS gradient
* @param value - CSS value
* @param [opt] - options
* @returns result
*/
var isGradient = (value, opt = {}) => {
return parseGradient(value, opt) !== null;
};
//#endregion
export { getGradientType, isGradient, parseGradient, resolveGradient, validateColorStopList, validateGradientLine };
//# sourceMappingURL=css-gradient.js.map
@@ -0,0 +1 @@
{"version":3,"file":"css-gradient.js","names":[],"sources":["../../../src/js/css-gradient.ts"],"sourcesContent":["/**\n * css-gradient\n */\n\nimport { createCacheKey, getCache, setCache } from './cache';\nimport { isString } from './common';\nimport { isColor, resolveColor } from './resolve';\nimport { MatchedRegExp, Options } from './typedef';\nimport { splitValue } from './util';\n\n/* constants */\nimport {\n ANGLE,\n CS_HUE,\n CS_RECT,\n LENGTH,\n NUM,\n NUM_POSITIVE,\n PCT,\n VAL_COMP,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'css-gradient';\nconst DIM_ANGLE = `${NUM}(?:${ANGLE})`;\nconst DIM_ANGLE_PCT = `${DIM_ANGLE}|${PCT}`;\nconst DIM_LEN = `${NUM}(?:${LENGTH})|0`;\nconst DIM_LEN_PCT = `${DIM_LEN}|${PCT}`;\nconst DIM_LEN_PCT_POSI = `${NUM_POSITIVE}(?:${LENGTH}|%)|0`;\nconst DIM_LEN_POSI = `${NUM_POSITIVE}(?:${LENGTH})|0`;\nconst CTR = 'center';\nconst L_R = 'left|right';\nconst T_B = 'top|bottom';\nconst S_E = 'start|end';\nconst AXIS_X = `${L_R}|x-(?:${S_E})`;\nconst AXIS_Y = `${T_B}|y-(?:${S_E})`;\nconst BLOCK = `block-(?:${S_E})`;\nconst INLINE = `inline-(?:${S_E})`;\nconst POS_1 = `${CTR}|${AXIS_X}|${AXIS_Y}|${BLOCK}|${INLINE}|${DIM_LEN_PCT}`;\nconst POS_2 = [\n `(?:${CTR}|${AXIS_X})\\\\s+(?:${CTR}|${AXIS_Y})`,\n `(?:${CTR}|${AXIS_Y})\\\\s+(?:${CTR}|${AXIS_X})`,\n `(?:${CTR}|${AXIS_X}|${DIM_LEN_PCT})\\\\s+(?:${CTR}|${AXIS_Y}|${DIM_LEN_PCT})`,\n `(?:${CTR}|${BLOCK})\\\\s+(?:${CTR}|${INLINE})`,\n `(?:${CTR}|${INLINE})\\\\s+(?:${CTR}|${BLOCK})`,\n `(?:${CTR}|${S_E})\\\\s+(?:${CTR}|${S_E})`\n].join('|');\nconst POS_4 = [\n `(?:${AXIS_X})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${AXIS_Y})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${AXIS_Y})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${AXIS_X})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${BLOCK})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${INLINE})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${INLINE})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${BLOCK})\\\\s+(?:${DIM_LEN_PCT})`,\n `(?:${S_E})\\\\s+(?:${DIM_LEN_PCT})\\\\s+(?:${S_E})\\\\s+(?:${DIM_LEN_PCT})`\n].join('|');\nconst RAD_EXTENT = '(?:clos|farth)est-(?:corner|side)';\nconst RAD_SIZE = [\n `${RAD_EXTENT}(?:\\\\s+${RAD_EXTENT})?`,\n `${DIM_LEN_POSI}`,\n `(?:${DIM_LEN_PCT_POSI})\\\\s+(?:${DIM_LEN_PCT_POSI})`\n].join('|');\nconst RAD_SHAPE = 'circle|ellipse';\nconst FROM_ANGLE = `from\\\\s+${DIM_ANGLE}`;\nconst AT_POSITION = `at\\\\s+(?:${POS_1}|${POS_2}|${POS_4})`;\nconst TO_SIDE_CORNER = `to\\\\s+(?:(?:${L_R})(?:\\\\s(?:${T_B}))?|(?:${T_B})(?:\\\\s(?:${L_R}))?)`;\nconst IN_COLOR_SPACE = `in\\\\s+(?:${CS_RECT}|${CS_HUE})`;\nconst LINE_SYNTAX_LINEAR = [\n `(?:${DIM_ANGLE}|${TO_SIDE_CORNER})(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+(?:${DIM_ANGLE}|${TO_SIDE_CORNER}))?`\n].join('|');\nconst LINE_SYNTAX_RADIAL = [\n `(?:${RAD_SHAPE})(?:\\\\s+(?:${RAD_SIZE}))?(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `(?:${RAD_SIZE})(?:\\\\s+(?:${RAD_SHAPE}))?(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${AT_POSITION}(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${RAD_SHAPE})(?:\\\\s+(?:${RAD_SIZE}))?(?:\\\\s+${AT_POSITION})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${RAD_SIZE})(?:\\\\s+(?:${RAD_SHAPE}))?(?:\\\\s+${AT_POSITION})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${AT_POSITION})?`\n].join('|');\nconst LINE_SYNTAX_CONIC = [\n `${FROM_ANGLE}(?:\\\\s+${AT_POSITION})?(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${AT_POSITION}(?:\\\\s+${IN_COLOR_SPACE})?`,\n `${IN_COLOR_SPACE}(?:\\\\s+${FROM_ANGLE})?(?:\\\\s+${AT_POSITION})?`\n].join('|');\nconst DEFAULT_LINEAR = [/to\\s+bottom/];\nconst DEFAULT_RADIAL = [/ellipse/, /farthest-corner/, /at\\s+center/];\nconst DEFAULT_CONIC = [/at\\s+center/];\n\n/* type definitions */\n/**\n * @type ColorStopList - list of color stops\n */\ntype ColorStopList = [string, string, ...string[]];\n\n/**\n * @typedef ValidateGradientLine - validate gradient line\n * @property line - gradient line\n * @property valid - result\n */\ninterface ValidateGradientLine {\n line: string;\n valid: boolean;\n}\n\n/**\n * @typedef ValidateColorStops - validate color stops\n * @property colorStops - list of color stops\n * @property valid - result\n */\ninterface ValidateColorStops {\n colorStops: string[];\n valid: boolean;\n}\n\n/**\n * @typedef Gradient - parsed CSS gradient\n * @property value - input value\n * @property type - gradient type\n * @property [gradientLine] - gradient line\n * @property colorStopList - list of color stops\n */\ninterface Gradient {\n value: string;\n type: string;\n gradientLine?: string;\n colorStopList: ColorStopList;\n}\n\n/* regexp */\nconst IS_CONIC = /^(?:repeating-)?conic-gradient$/;\nconst IS_LINEAR = /^(?:repeating-)?linear-gradient$/;\nconst IS_RADIAL = /^(?:repeating-)?radial-gradient$/;\nconst REG_COLOR_HINT_CONIC = new RegExp(`^(?:${DIM_ANGLE_PCT})$`);\nconst REG_COLOR_HINT_NON_CONIC = new RegExp(`^(?:${DIM_LEN_PCT})$`);\nconst REG_DIM_CONIC = new RegExp(`(?:\\\\s+(?:${DIM_ANGLE_PCT})){1,2}$`);\nconst REG_DIM_NON_CONIC = new RegExp(`(?:\\\\sLine truncated
@@ -0,0 +1,66 @@
import { CSSToken } from '@csstools/css-tokenizer';
import { ColorChannels, Options, StringColorChannels } from './typedef.js';
/**
* @type NumberOrStringColorChannels - color channel
*/
type NumberOrStringColorChannels = ColorChannels & StringColorChannels;
/**
* resolve relative color channels
* @param value
* - CSS color value
* - system colors are not supported
* @param [opt] - options
* @param [opt.currentColor]
* - color to use for `currentcolor` keyword
* - if omitted, it will be treated as a missing color
* i.e. `rgb(none none none / none)`
* @param [opt.customProperty]
* - custom properties
* - pair of `--` prefixed property name and value,
* e.g. `customProperty: { '--some-color': '#0000ff' }`
* - and/or `callback` function to get the value of the custom property,
* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`
* @param [opt.dimension]
* - dimension, convert relative length to pixels
* - pair of unit and it's value as a number in pixels,
* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`
* - and/or `callback` function to get the value as a number in pixels,
* e.g. `dimension: { callback: convertUnitToPixel }`
* @param [opt.format]
* - output format, one of below
* - `computedValue` (default), [computed value][139] of the color
* - `specifiedValue`, [specified value][140] of the color
* - `hex`, hex color notation, i.e. `rrggbb`
* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
* @returns
* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',
* color(color-space r g b / alpha), color(color-space x y z / alpha),
* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),
* oklch(l c h / alpha), null
* - in `computedValue`, values are numbers, however `rgb()` values are
* integers
* - in `specifiedValue`, returns `empty string` for unknown and/or invalid
* color
* - in `hex`, returns `null` for `transparent`, and also returns `null` if
* any of `r`, `g`, `b`, `alpha` is not a number
* - in `hexAlpha`, returns `#00000000` for `transparent`,
* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
*/
export declare function resolveColorChannels(tokens: CSSToken[], opt?: Options): NumberOrStringColorChannels | null;
/**
* extract origin color
* @param value - CSS color value
* @param opt - options
* @param resolver - resolver function
* @returns origin color value
*/
export declare function extractOriginColor(value: string, opt?: Options, resolver?: (v: string, o?: Options) => string | null): string | null;
/**
* resolve relative color
* @param value - CSS relative color value
* @param opt - options
* @param resolver - resolver function
* @returns resolved value
*/
export declare function resolveRelativeColor(value: string, opt?: Options, resolver?: (v: string, o?: Options) => string | null): string | null;
export {};
@@ -0,0 +1,462 @@
import { createCacheKey, getCache, setCache } from "./cache.js";
import { isString, isStringOrNumber } from "./common.js";
import { roundToPrecision, splitValue } from "./util.js";
import { CS_LAB, CS_LCH, FN_REL, FN_REL_CAPT, FN_VAR, NONE, SYN_COLOR_TYPE, SYN_FN_MATH_START, SYN_FN_VAR, SYN_MIX, VAL_SPEC } from "./constant.js";
import { NAMED_COLORS, convertColorToRgb } from "./color.js";
import { resolveDimension, serializeCalc } from "./css-calc-var.js";
import { TokenType, tokenize } from "@csstools/css-tokenizer";
import { SyntaxFlag, color } from "@csstools/css-color-parser";
import { parseComponentValue } from "@csstools/css-parser-algorithms";
//#region src/js/relative-color.ts
/**
* relative-color
*/
var { CloseParen: PAREN_CLOSE, Comment: COMMENT, Delim: DELIM, Dimension: DIM, EOF, Function: FUNC, Ident: IDENT, Number: NUM, OpenParen: PAREN_OPEN, Percentage: PCT, Whitespace: W_SPACE } = TokenType;
var { HasNoneKeywords: KEY_NONE } = SyntaxFlag;
var NAMESPACE = "relative-color";
var OCT = 8;
var DEC = 10;
var HEX = 16;
var MAX_PCT = 100;
var MAX_RGB = 255;
var COLOR_CHANNELS = /* @__PURE__ */ new Map([
["color", [
"r",
"g",
"b",
"alpha"
]],
["hsl", [
"h",
"s",
"l",
"alpha"
]],
["hsla", [
"h",
"s",
"l",
"alpha"
]],
["hwb", [
"h",
"w",
"b",
"alpha"
]],
["lab", [
"l",
"a",
"b",
"alpha"
]],
["lch", [
"l",
"c",
"h",
"alpha"
]],
["oklab", [
"l",
"a",
"b",
"alpha"
]],
["oklch", [
"l",
"c",
"h",
"alpha"
]],
["rgb", [
"r",
"g",
"b",
"alpha"
]],
["rgba", [
"r",
"g",
"b",
"alpha"
]]
]);
var REG_COLOR_CAPT = new RegExp(`^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\s+`);
var REG_CS_HSL = /(?:hsla?|hwb)$/;
var REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);
var REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\(/;
var REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);
var REG_FN_REL = new RegExp(FN_REL);
var REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);
var REG_FN_REL_START = new RegExp(`^${FN_REL}`);
var REG_FN_VAR = new RegExp(SYN_FN_VAR);
/**
* resolve relative color channels
* @param value
* - CSS color value
* - system colors are not supported
* @param [opt] - options
* @param [opt.currentColor]
* - color to use for `currentcolor` keyword
* - if omitted, it will be treated as a missing color
* i.e. `rgb(none none none / none)`
* @param [opt.customProperty]
* - custom properties
* - pair of `--` prefixed property name and value,
* e.g. `customProperty: { '--some-color': '#0000ff' }`
* - and/or `callback` function to get the value of the custom property,
* e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`
* @param [opt.dimension]
* - dimension, convert relative length to pixels
* - pair of unit and it's value as a number in pixels,
* e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`
* - and/or `callback` function to get the value as a number in pixels,
* e.g. `dimension: { callback: convertUnitToPixel }`
* @param [opt.format]
* - output format, one of below
* - `computedValue` (default), [computed value][139] of the color
* - `specifiedValue`, [specified value][140] of the color
* - `hex`, hex color notation, i.e. `rrggbb`
* - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`
* @returns
* - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',
* color(color-space r g b / alpha), color(color-space x y z / alpha),
* lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),
* oklch(l c h / alpha), null
* - in `computedValue`, values are numbers, however `rgb()` values are
* integers
* - in `specifiedValue`, returns `empty string` for unknown and/or invalid
* color
* - in `hex`, returns `null` for `transparent`, and also returns `null` if
* any of `r`, `g`, `b`, `alpha` is not a number
* - in `hexAlpha`, returns `#00000000` for `transparent`,
* however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number
*/
function resolveColorChannels(tokens, opt = {}) {
if (!Array.isArray(tokens)) throw new TypeError(`${tokens} is not an array.`);
const { colorSpace = "", format = "" } = opt;
const colorChannel = COLOR_CHANNELS.get(colorSpace);
if (!colorChannel) return null;
const mathFunc = /* @__PURE__ */ new Set();
const channels = [
[],
[],
[],
[]
];
let i = 0;
let nest = 0;
let func = "";
let precededPct = false;
for (const token of tokens) {
if (!Array.isArray(token)) throw new TypeError(`${token} is not an array.`);
const [type, value, , , detail] = token;
const channel = channels[i];
if (Array.isArray(channel)) switch (type) {
case DELIM:
if (func) {
if ((value === "+" || value === "-") && precededPct && !REG_FN_CALC_SUM.test(func)) return null;
precededPct = false;
channel.push(value);
}
break;
case DIM: {
if (!func || !REG_FN_CALC_SUM.test(func)) return null;
const resolvedValue = resolveDimension(token, opt);
if (isString(resolvedValue)) channel.push(resolvedValue);
else channel.push(value);
break;
}
case FUNC:
channel.push(value);
func = value;
nest++;
if (REG_FN_MATH_START.test(value)) mathFunc.add(nest);
break;
case IDENT:
if (!colorChannel.includes(value)) return null;
channel.push(value);
if (!func) i++;
break;
case NUM:
channel.push(Number(detail?.value));
if (!func) i++;
break;
case PAREN_OPEN:
channel.push(value);
nest++;
break;
case PAREN_CLOSE:
if (func) {
if (channel[channel.length - 1] === " ") channel[channel.length - 1] = value;
else channel.push(value);
if (mathFunc.has(nest)) mathFunc.delete(nest);
nest--;
if (nest === 0) {
func = "";
i++;
}
}
break;
case PCT:
if (!func) return null;
else if (!REG_FN_CALC_SUM.test(func)) {
let lastValue;
for (let j = channel.length - 1; j >= 0; j--) if (channel[j] !== " ") {
lastValue = channel[j];
break;
}
if (lastValue === "+" || lastValue === "-") return null;
else if (lastValue === "*" || lastValue === "/") precededPct = false;
else precededPct = true;
}
channel.push(Number(detail?.value) / MAX_PCT);
break;
case W_SPACE:
if (channel.length && func) {
const lastValue = channel[channel.length - 1];
if (typeof lastValue === "number") channel.push(value);
else if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") channel.push(value);
}
break;
default: if (type !== COMMENT && type !== EOF && func) channel.push(value);
}
}
const channelValues = [];
for (const channel of channels) if (channel.length === 1) {
const [resolvedValue] = channel;
if (isStringOrNumber(resolvedValue)) channelValues.push(resolvedValue);
} else if (channel.length) {
const resolvedValue = serializeCalc(channel.join(""), { format });
channelValues.push(resolvedValue);
}
return channelValues;
}
/**
* extract origin color
* @param value - CSS color value
* @param opt - options
* @param resolver - resolver function
* @returns origin color value
*/
function extractOriginColor(value, opt = {}, resolver = () => null) {
const { colorScheme = "normal", currentColor = "", format = "" } = opt;
if (isString(value)) {
value = value.toLowerCase().trim();
if (!value) return null;
if (!REG_FN_REL_START.test(value)) return value;
} else return null;
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "extractOriginColor",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
if (/currentcolor/.test(value)) {
if (currentColor) value = value.replace(/currentcolor/g, currentColor);
else {
setCache(cacheKey, null);
return null;
}
}
let colorSpace = "";
if (REG_FN_REL_CAPT.test(value)) [, colorSpace] = value.match(REG_FN_REL_CAPT);
opt.colorSpace = colorSpace;
if (value.includes("light-dark(")) {
const colorParts = value.replace(new RegExp(`^${colorSpace}\\(`), "").replace(/\)$/, "");
const [, originColor = ""] = splitValue(colorParts);
const specifiedOriginColor = resolver(originColor, {
colorScheme,
format: VAL_SPEC
});
if (!specifiedOriginColor) {
setCache(cacheKey, null);
return null;
}
if (format === "specifiedValue") value = value.replace(originColor, specifiedOriginColor);
else {
const resolvedOriginColor = resolver(specifiedOriginColor, opt);
if (isString(resolvedOriginColor)) value = value.replace(originColor, resolvedOriginColor);
else {
setCache(cacheKey, null);
return null;
}
}
}
if (REG_COLOR_CAPT.test(value)) {
const [, originColor] = value.match(REG_COLOR_CAPT);
const [, restValue] = value.split(originColor);
if (/^[a-z]+$/.test(originColor)) {
if (!/^transparent$/.test(originColor) && !Object.hasOwn(NAMED_COLORS, originColor)) {
setCache(cacheKey, null);
return null;
}
} else if (format === "specifiedValue") {
const resolvedOriginColor = resolver(originColor, opt);
if (isString(resolvedOriginColor)) value = value.replace(originColor, resolvedOriginColor);
}
if (format === "specifiedValue") {
const channelValues = resolveColorChannels(tokenize({ css: restValue }), opt);
if (channelValues === null) {
setCache(cacheKey, null);
return null;
}
const [v1, v2, v3, v4] = channelValues;
let channelValue = "";
if (isStringOrNumber(v4)) channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
else channelValue = ` ${channelValues.join(" ")})`;
if (restValue !== channelValue) value = value.replace(restValue, channelValue);
}
} else {
const [, restValue] = value.split(REG_FN_REL_START);
const tokens = tokenize({ css: restValue });
const originColor = [];
let nest = 0;
let tokenIndex = 0;
for (const [type, tokenValue] of tokens) {
tokenIndex++;
switch (type) {
case FUNC:
case PAREN_OPEN:
originColor.push(tokenValue);
nest++;
break;
case PAREN_CLOSE: {
const lastValue = originColor[originColor.length - 1];
if (lastValue === " ") originColor[originColor.length - 1] = tokenValue;
else if (isString(lastValue)) originColor.push(tokenValue);
nest--;
break;
}
case W_SPACE: {
const lastValue = originColor[originColor.length - 1];
if (isString(lastValue) && !lastValue.endsWith("(") && lastValue !== " ") originColor.push(tokenValue);
break;
}
default: if (type !== COMMENT && type !== EOF) originColor.push(tokenValue);
}
if (nest === 0) break;
}
const resolvedOriginColor = resolveRelativeColor(originColor.join("").trim(), opt, resolver);
if (resolvedOriginColor === null) {
setCache(cacheKey, null);
return null;
}
const channelValues = resolveColorChannels(tokens.slice(tokenIndex), opt);
if (channelValues === null) {
setCache(cacheKey, null);
return null;
}
const [v1, v2, v3, v4] = channelValues;
let channelValue = "";
if (isStringOrNumber(v4)) channelValue = ` ${v1} ${v2} ${v3} / ${v4})`;
else channelValue = ` ${channelValues.join(" ")})`;
value = value.replace(restValue, `${resolvedOriginColor}${channelValue}`);
}
setCache(cacheKey, value);
return value;
}
/**
* resolve relative color
* @param value - CSS relative color value
* @param opt - options
* @param resolver - resolver function
* @returns resolved value
*/
function resolveRelativeColor(value, opt = {}, resolver = () => null) {
const { format = "" } = opt;
if (isString(value)) {
if (REG_FN_VAR.test(value)) {
if (format !== "specifiedValue") throw new SyntaxError(`Unexpected token ${FN_VAR} found.`);
return value;
} else if (!REG_FN_REL.test(value)) return value;
value = value.toLowerCase().trim();
} else throw new TypeError(`${value} is not a string.`);
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "resolveRelativeColor",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
const originColor = extractOriginColor(value, opt, resolver);
if (originColor === null) {
setCache(cacheKey, null);
return null;
}
value = originColor;
if (format === "specifiedValue") {
if (value.startsWith("rgba(")) value = value.replace("rgba(", "rgb(");
else if (value.startsWith("hsla(")) value = value.replace("hsla(", "hsl(");
return value;
}
const tokens = tokenize({ css: value });
const components = parseComponentValue(tokens);
const parsedComponents = color(components);
if (!parsedComponents) {
setCache(cacheKey, null);
return null;
}
const { alpha: alphaComponent, channels: channelsComponent, colorNotation, syntaxFlags } = parsedComponents;
let alpha;
if (Number.isNaN(Number(alphaComponent))) {
if (syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE)) alpha = NONE;
else alpha = 0;
} else alpha = roundToPrecision(Number(alphaComponent), OCT);
let v1;
let v2;
let v3;
[v1, v2, v3] = channelsComponent;
let resolvedValue;
if (REG_CS_CIE.test(colorNotation)) {
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
if (Number.isNaN(v1)) {
if (hasNone) v1 = NONE;
else v1 = 0;
} else v1 = roundToPrecision(v1, HEX);
if (Number.isNaN(v2)) {
if (hasNone) v2 = NONE;
else v2 = 0;
} else v2 = roundToPrecision(v2, HEX);
if (Number.isNaN(v3)) {
if (hasNone) v3 = NONE;
else v3 = 0;
} else v3 = roundToPrecision(v3, HEX);
if (alpha === 1) resolvedValue = `${colorNotation}(${v1} ${v2} ${v3})`;
else resolvedValue = `${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`;
} else if (REG_CS_HSL.test(colorNotation)) {
if (Number.isNaN(v1)) v1 = 0;
if (Number.isNaN(v2)) v2 = 0;
if (Number.isNaN(v3)) v3 = 0;
let [r, g, b] = convertColorToRgb(`${colorNotation}(${v1} ${v2} ${v3} / ${alpha})`);
r = roundToPrecision(r / MAX_RGB, DEC);
g = roundToPrecision(g / MAX_RGB, DEC);
b = roundToPrecision(b / MAX_RGB, DEC);
if (alpha === 1) resolvedValue = `color(srgb ${r} ${g} ${b})`;
else resolvedValue = `color(srgb ${r} ${g} ${b} / ${alpha})`;
} else {
const cs = colorNotation === "rgb" ? "srgb" : colorNotation;
const hasNone = syntaxFlags instanceof Set && syntaxFlags.has(KEY_NONE);
if (Number.isNaN(v1)) {
if (hasNone) v1 = NONE;
else v1 = 0;
} else v1 = roundToPrecision(v1, DEC);
if (Number.isNaN(v2)) {
if (hasNone) v2 = NONE;
else v2 = 0;
} else v2 = roundToPrecision(v2, DEC);
if (Number.isNaN(v3)) {
if (hasNone) v3 = NONE;
else v3 = 0;
} else v3 = roundToPrecision(v3, DEC);
if (alpha === 1) resolvedValue = `color(${cs} ${v1} ${v2} ${v3})`;
else resolvedValue = `color(${cs} ${v1} ${v2} ${v3} / ${alpha})`;
}
setCache(cacheKey, resolvedValue);
return resolvedValue;
}
//#endregion
export { extractOriginColor, resolveColorChannels, resolveRelativeColor };
//# sourceMappingURL=relative-color.js.map
@@ -0,0 +1 @@
{"version":3,"file":"relative-color.js","names":[],"sources":["../../../src/js/relative-color.ts"],"sourcesContent":["/**\n * relative-color\n */\n\nimport { SyntaxFlag, color as colorParser } from '@csstools/css-color-parser';\nimport {\n ComponentValue,\n parseComponentValue\n} from '@csstools/css-parser-algorithms';\nimport { CSSToken, TokenType, tokenize } from '@csstools/css-tokenizer';\nimport { createCacheKey, getCache, setCache } from './cache';\nimport { NAMED_COLORS, convertColorToRgb } from './color';\nimport { isString, isStringOrNumber } from './common';\nimport { resolveDimension, serializeCalc } from './css-calc-var';\nimport { roundToPrecision, splitValue } from './util';\nimport {\n ColorChannels,\n MatchedRegExp,\n Options,\n StringColorChannels\n} from './typedef';\n\n/* constants */\nimport {\n CS_LAB,\n CS_LCH,\n FN_LIGHT_DARK,\n FN_REL,\n FN_REL_CAPT,\n FN_VAR,\n NONE,\n SYN_COLOR_TYPE,\n SYN_FN_MATH_START,\n SYN_FN_VAR,\n SYN_MIX,\n VAL_SPEC\n} from './constant';\nconst {\n CloseParen: PAREN_CLOSE,\n Comment: COMMENT,\n Delim: DELIM,\n Dimension: DIM,\n EOF,\n Function: FUNC,\n Ident: IDENT,\n Number: NUM,\n OpenParen: PAREN_OPEN,\n Percentage: PCT,\n Whitespace: W_SPACE\n} = TokenType;\nconst { HasNoneKeywords: KEY_NONE } = SyntaxFlag;\nconst NAMESPACE = 'relative-color';\n\n/* constants */\nconst OCT = 8;\nconst DEC = 10;\nconst HEX = 16;\nconst MAX_PCT = 100;\nconst MAX_RGB = 255;\nconst COLOR_CHANNELS = new Map([\n ['color', ['r', 'g', 'b', 'alpha']],\n ['hsl', ['h', 's', 'l', 'alpha']],\n ['hsla', ['h', 's', 'l', 'alpha']],\n ['hwb', ['h', 'w', 'b', 'alpha']],\n ['lab', ['l', 'a', 'b', 'alpha']],\n ['lch', ['l', 'c', 'h', 'alpha']],\n ['oklab', ['l', 'a', 'b', 'alpha']],\n ['oklch', ['l', 'c', 'h', 'alpha']],\n ['rgb', ['r', 'g', 'b', 'alpha']],\n ['rgba', ['r', 'g', 'b', 'alpha']]\n]);\n\n/* type definitions */\n/**\n * @type NumberOrStringColorChannels - color channel\n */\ntype NumberOrStringColorChannels = ColorChannels & StringColorChannels;\n\n/* regexp */\nconst REG_COLOR_CAPT = new RegExp(\n `^${FN_REL}(${SYN_COLOR_TYPE}|${SYN_MIX})\\\\s+`\n);\nconst REG_CS_HSL = /(?:hsla?|hwb)$/;\nconst REG_CS_CIE = new RegExp(`^(?:${CS_LAB}|${CS_LCH})$`);\nconst REG_FN_CALC_SUM = /^(?:abs|sig?n|cos|tan)\\(/;\nconst REG_FN_MATH_START = new RegExp(SYN_FN_MATH_START);\nconst REG_FN_REL = new RegExp(FN_REL);\nconst REG_FN_REL_CAPT = new RegExp(`^${FN_REL_CAPT}`);\nconst REG_FN_REL_START = new RegExp(`^${FN_REL}`);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\n\n/**\n * resolve relative color channels\n * @param value\n * - CSS color value\n * - system colors are not supported\n * @param [opt] - options\n * @param [opt.currentColor]\n * - color to use for `currentcolor` keyword\n * - if omitted, it will be treated as a missing color\n * i.e. `rgb(none none none / none)`\n * @param [opt.customProperty]\n * - custom properties\n * - pair of `--` prefixed property name and value,\n * e.g. `customProperty: { '--some-color': '#0000ff' }`\n * - and/or `callback` function to get the value of the custom property,\n * e.g. `customProperty: { callback: someDeclaration.getPropertyValue }`\n * @param [opt.dimension]\n * - dimension, convert relative length to pixels\n * - pair of unit and it's value as a number in pixels,\n * e.g. `dimension: { em: 12, rem: 16, vw: 10.26 }`\n * - and/or `callback` function to get the value as a number in pixels,\n * e.g. `dimension: { callback: convertUnitToPixel }`\n * @param [opt.format]\n * - output format, one of below\n * - `computedValue` (default), [computed value][139] of the color\n * - `specifiedValue`, [specified value][140] of the color\n * - `hex`, hex color notation, i.e. `rrggbb`\n * - `hexAlpha`, hex color notation with alpha channel, i.e. `#rrggbbaa`\n * @returns\n * - one of rgba?(), #rrggbb(aa)?, color-name, '(empty-string)',\n * color(color-space r g b / alpha), color(color-space x y z / alpha),\n * lab(l a b / alpha), lch(l c h / alpha), oklab(l a b / alpha),\n * oklch(l c h / alpha), null\n * - in `computedValue`, values are numbers, however `rgb()` values are\n * integers\n * - in `specifiedValue`, returns `empty string` for unknown and/or invalid\n * color\n * - in `hex`, returns `null` for `transparent`, and also returns `null` if\n * any of `r`, `g`, `b`, `alpha` is not a number\n * - in `hexAlpha`, returns `#00000000` for `transparent`,\n * however returns `null` if any of `r`, `g`, `b`, `alpha` is not a number\n */\nexport function resolveColorChannels(\n tokens: CSSToken[],\n opt: Options = {}\n): NumberOrStringColorChannels | null {\n if (!Array.isArray(tokens)) {\n throw new TypeError(`${tokens} is not an array.`);\n }\n const { colorSpace = '', format = '' } = opt;\n const colorChannel = COLOR_CHANNELS.get(colorSpace);\n // invalid color channel\n if (!colorChannel) {\n return null;\n }\n const maLine truncated
+22
View File
@@ -0,0 +1,22 @@
import { Options } from './typedef.js';
/**
* resolve color
* @param value - CSS color value
* @param opt - options
* @returns resolved color
*/
export declare const resolveColor: (value: string, opt?: Options) => string | null;
/**
* resolve CSS color
* @param value - CSS color value. system colors are not supported
* @param opt - options
* @returns resolved value
*/
export declare const resolve: (value: string, opt?: Options) => string | null;
/**
* is color
* @param value - CSS value
* @param opt - options
* @returns result
*/
export declare const isColor: (value: unknown, opt?: Options) => boolean;
+241
View File
@@ -0,0 +1,241 @@
import { createCacheKey, getCache, setCache } from "./cache.js";
import { isString } from "./common.js";
import { splitValue } from "./util.js";
import { SYN_COLOR_TYPE, SYN_FN_CALC, SYN_FN_LIGHT_DARK, SYN_FN_REL, SYN_FN_VAR, SYN_MIX, VAL_COMP, VAL_SPEC } from "./constant.js";
import { NAMED_COLORS, convertRgbToHex, resolveColorFunc, resolveColorMix, resolveColorValue } from "./color.js";
import { resolveRelativeColor } from "./relative-color.js";
import { cssCalc, resolveVar } from "./css-calc-var.js";
//#region src/js/resolve.ts
/**
* resolve
*/
var NAMESPACE = "resolve";
var RGB_TRANSPARENT = "rgba(0, 0, 0, 0)";
var REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);
var REG_FN_CALC = new RegExp(SYN_FN_CALC);
var REG_FN_COLOR = /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\(/;
var REG_FN_LIGHT_DARK = new RegExp(SYN_FN_LIGHT_DARK);
var REG_FN_REL = new RegExp(SYN_FN_REL);
var REG_FN_VAR = new RegExp(SYN_FN_VAR);
var REG_MIX = new RegExp(SYN_MIX);
/**
* resolve color
* @param value - CSS color value
* @param opt - options
* @returns resolved color
*/
var resolveColor = (value, opt = {}) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
value = value.trim();
const { colorScheme = "normal", currentColor = "", format = VAL_COMP, nullable = false } = opt;
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "resolve",
value
}, opt);
const cachedResult = getCache(cacheKey);
if (cachedResult !== false) return cachedResult.item;
if (REG_FN_VAR.test(value)) {
if (format === "specifiedValue") {
setCache(cacheKey, value);
return value;
}
const resolvedVar = resolveVar(value, opt);
if (resolvedVar === null) {
const res = format === "hex" || format === "hexAlpha" || nullable ? null : RGB_TRANSPARENT;
setCache(cacheKey, res);
return res;
}
value = resolvedVar;
}
if (opt.format !== format) opt.format = format;
value = value.toLowerCase();
if (REG_FN_LIGHT_DARK.test(value) && value.endsWith(")")) {
const colorParts = value.replace(REG_FN_LIGHT_DARK, "").replace(/\)$/, "");
const [light = "", dark = ""] = splitValue(colorParts, { delimiter: "," });
if (light && dark) {
if (format === "specifiedValue") {
const lightColor = resolveColor(light, opt);
const darkColor = resolveColor(dark, opt);
const res = lightColor && darkColor ? `light-dark(${lightColor}, ${darkColor})` : "";
setCache(cacheKey, res);
return res;
}
const resolved = resolveColor(colorScheme === "dark" ? dark : light, opt);
const res = resolved === null && !nullable ? RGB_TRANSPARENT : resolved;
setCache(cacheKey, res);
return res;
}
let invalidRes;
if (format === "specifiedValue") invalidRes = "";
else if (format === "hex" || format === "hexAlpha") invalidRes = null;
else invalidRes = RGB_TRANSPARENT;
setCache(cacheKey, invalidRes);
return invalidRes;
}
if (REG_FN_REL.test(value)) {
const resolvedRel = resolveRelativeColor(value, opt, resolveColor);
if (format === "computedValue") {
const res = resolvedRel === null && !nullable ? RGB_TRANSPARENT : resolvedRel;
setCache(cacheKey, res);
return res;
}
if (format === "specifiedValue") {
const res = resolvedRel === null ? "" : resolvedRel;
setCache(cacheKey, res);
return res;
}
value = resolvedRel === null ? "" : resolvedRel;
}
if (REG_FN_CALC.test(value)) value = cssCalc(value, opt);
let cs = "";
let r = NaN;
let g = NaN;
let b = NaN;
let alpha = NaN;
if (value === "transparent") {
let res;
switch (format) {
case VAL_SPEC:
res = value;
break;
case "hex":
res = null;
break;
case "hexAlpha":
res = "#00000000";
break;
default: res = RGB_TRANSPARENT;
}
setCache(cacheKey, res);
return res;
}
if (value === "currentcolor") {
if (format === "specifiedValue") {
setCache(cacheKey, value);
return value;
}
if (currentColor) {
let resolvedCurrent;
if (currentColor.startsWith("color-mix(")) resolvedCurrent = resolveColorMix(currentColor, opt, resolveColor);
else if (currentColor.startsWith("color(")) resolvedCurrent = resolveColorFunc(currentColor, opt);
else resolvedCurrent = resolveColorValue(currentColor, opt);
if (resolvedCurrent === null) {
setCache(cacheKey, null);
return null;
}
[cs, r, g, b, alpha] = resolvedCurrent;
} else {
const res = format === "computedValue" ? RGB_TRANSPARENT : value;
if (format === "computedValue") {
setCache(cacheKey, res);
return res;
}
}
} else if (format === "specifiedValue") {
let res = "";
if (value.startsWith("color-mix(")) {
const mixRes = resolveColorMix(value, opt, resolveColor);
res = mixRes ? mixRes : "";
} else if (value.startsWith("color(")) {
const funcRes = resolveColorFunc(value, opt);
if (isString(funcRes)) res = funcRes;
else if (Array.isArray(funcRes)) {
const [scs, rr, gg, bb, aa] = funcRes;
res = aa === 1 ? `color(${scs} ${rr} ${gg} ${bb})` : `color(${scs} ${rr} ${gg} ${bb} / ${aa})`;
}
} else {
const rgb = resolveColorValue(value, opt);
if (isString(rgb)) res = rgb;
else if (Array.isArray(rgb)) {
const [scs, rr, gg, bb, aa] = rgb;
if (scs === "rgb") res = aa === 1 ? `${scs}(${rr}, ${gg}, ${bb})` : `${scs}a(${rr}, ${gg}, ${bb}, ${aa})`;
else res = aa === 1 ? `${scs}(${rr} ${gg} ${bb})` : `${scs}(${rr} ${gg} ${bb} / ${aa})`;
}
}
setCache(cacheKey, res);
return res;
} else if (value.startsWith("color-mix(")) {
if (currentColor) value = value.replace(/currentcolor/g, currentColor);
value = value.replace(/transparent/g, RGB_TRANSPARENT);
const resolvedMix = resolveColorMix(value, opt, resolveColor);
if (resolvedMix === null) {
setCache(cacheKey, null);
return null;
}
[cs, r, g, b, alpha] = resolvedMix;
} else if (value.startsWith("color(")) {
const resolvedFunc = resolveColorFunc(value, opt);
if (resolvedFunc === null) {
setCache(cacheKey, null);
return null;
}
[cs, r, g, b, alpha] = resolvedFunc;
} else if (value) {
const resolvedVal = resolveColorValue(value, opt);
if (resolvedVal === null) {
setCache(cacheKey, null);
return null;
}
[cs, r, g, b, alpha] = resolvedVal;
}
let finalRes = "";
switch (format) {
case "hex":
case "hexAlpha":
if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b) || Number.isNaN(alpha) || format === "hex" && alpha === 0) finalRes = null;
else finalRes = convertRgbToHex([
r,
g,
b,
format === "hex" ? 1 : alpha
]);
break;
default: if (cs === "rgb") finalRes = alpha === 1 ? `${cs}(${r}, ${g}, ${b})` : `${cs}a(${r}, ${g}, ${b}, ${alpha})`;
else if ([
"lab",
"lch",
"oklab",
"oklch"
].includes(cs)) finalRes = alpha === 1 ? `${cs}(${r} ${g} ${b})` : `${cs}(${r} ${g} ${b} / ${alpha})`;
else finalRes = alpha === 1 ? `color(${cs} ${r} ${g} ${b})` : `color(${cs} ${r} ${g} ${b} / ${alpha})`;
}
setCache(cacheKey, finalRes);
return finalRes;
};
/**
* resolve CSS color
* @param value - CSS color value. system colors are not supported
* @param opt - options
* @returns resolved value
*/
var resolve = (value, opt = {}) => {
opt.nullable = false;
return resolveColor(value, opt);
};
/**
* is color
* @param value - CSS value
* @param opt - options
* @returns result
*/
var isColor = (value, opt = {}) => {
if (!isString(value)) return false;
const str = value.toLowerCase().trim();
if (!str) return false;
if (/^[a-z]+$/.test(str)) return str === "currentcolor" || str === "transparent" || Object.hasOwn(NAMED_COLORS, str);
if (REG_COLOR.test(str) || REG_MIX.test(str)) return true;
if (REG_FN_COLOR.test(str)) {
const colorOpt = {
...opt,
nullable: true
};
if (!colorOpt.format) colorOpt.format = VAL_SPEC;
return !!resolveColor(str, colorOpt);
}
return false;
};
//#endregion
export { isColor, resolve, resolveColor };
//# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
{"version":3,"file":"resolve.js","names":[],"sources":["../../../src/js/resolve.ts"],"sourcesContent":["/**\n * resolve\n */\n\nimport { createCacheKey, getCache, setCache } from './cache';\nimport {\n NAMED_COLORS,\n convertRgbToHex,\n resolveColorFunc,\n resolveColorMix,\n resolveColorValue\n} from './color';\nimport { isString } from './common';\nimport { cssCalc, resolveVar } from './css-calc-var';\nimport { resolveRelativeColor } from './relative-color';\nimport { splitValue } from './util';\nimport {\n ComputedColorChannels,\n Options,\n SpecifiedColorChannels\n} from './typedef';\n\n/* constants */\nimport {\n FN_COLOR,\n FN_MIX,\n SYN_COLOR_TYPE,\n SYN_FN_CALC,\n SYN_FN_LIGHT_DARK,\n SYN_FN_REL,\n SYN_FN_VAR,\n SYN_MIX,\n VAL_COMP,\n VAL_SPEC\n} from './constant';\nconst NAMESPACE = 'resolve';\nconst RGB_TRANSPARENT = 'rgba(0, 0, 0, 0)';\n\n/* regexp */\nconst REG_COLOR = new RegExp(`^(?:${SYN_COLOR_TYPE})$`);\nconst REG_FN_CALC = new RegExp(SYN_FN_CALC);\nconst REG_FN_COLOR =\n /^(?:(?:ok)?l(?:ab|ch)|color(?:-mix)?|hsla?|hwb|rgba?|var)\\(/;\nconst REG_FN_LIGHT_DARK = new RegExp(SYN_FN_LIGHT_DARK);\nconst REG_FN_REL = new RegExp(SYN_FN_REL);\nconst REG_FN_VAR = new RegExp(SYN_FN_VAR);\nconst REG_MIX = new RegExp(SYN_MIX);\n\n/**\n * resolve color\n * @param value - CSS color value\n * @param opt - options\n * @returns resolved color\n */\nexport const resolveColor = (\n value: string,\n opt: Options = {}\n): string | null => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n value = value.trim();\n const {\n colorScheme = 'normal',\n currentColor = '',\n format = VAL_COMP,\n nullable = false\n } = opt;\n const cacheKey: string = createCacheKey(\n { namespace: NAMESPACE, name: 'resolve', value },\n opt\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult !== false) {\n return cachedResult.item as string | null;\n }\n // 1. var() resolution\n if (REG_FN_VAR.test(value)) {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n return value;\n }\n const resolvedVar = resolveVar(value, opt);\n if (resolvedVar === null) {\n const res =\n format === 'hex' || format === 'hexAlpha' || nullable\n ? null\n : RGB_TRANSPARENT;\n setCache(cacheKey, res);\n return res;\n }\n value = resolvedVar;\n }\n if (opt.format !== format) {\n opt.format = format;\n }\n value = value.toLowerCase();\n // 2. light-dark() resolution\n if (REG_FN_LIGHT_DARK.test(value) && value.endsWith(')')) {\n const colorParts = value.replace(REG_FN_LIGHT_DARK, '').replace(/\\)$/, '');\n const [light = '', dark = ''] = splitValue(colorParts, { delimiter: ',' });\n if (light && dark) {\n if (format === VAL_SPEC) {\n const lightColor = resolveColor(light, opt);\n const darkColor = resolveColor(dark, opt);\n const res =\n lightColor && darkColor\n ? `light-dark(${lightColor}, ${darkColor})`\n : '';\n setCache(cacheKey, res);\n return res;\n }\n const chosen = colorScheme === 'dark' ? dark : light;\n const resolved = resolveColor(chosen, opt);\n const res = resolved === null && !nullable ? RGB_TRANSPARENT : resolved;\n setCache(cacheKey, res);\n return res;\n }\n // fallback for invalid light-dark\n let invalidRes;\n if (format === VAL_SPEC) {\n invalidRes = '';\n } else if (format === 'hex' || format === 'hexAlpha') {\n invalidRes = null;\n } else {\n invalidRes = RGB_TRANSPARENT;\n }\n setCache(cacheKey, invalidRes);\n return invalidRes;\n }\n // 3. Relative Color resolution\n if (REG_FN_REL.test(value)) {\n const resolvedRel = resolveRelativeColor(value, opt, resolveColor);\n if (format === VAL_COMP) {\n const res =\n resolvedRel === null && !nullable ? RGB_TRANSPARENT : resolvedRel;\n setCache(cacheKey, res);\n return res;\n }\n if (format === VAL_SPEC) {\n const res = resolvedRel === null ? '' : resolvedRel;\n setCache(cacheKey, res);\n return res;\n }\n value = resolvedRel === null ? '' : resolvedRel;\n }\n // 4. calc() resolution\n if (REG_FN_CALC.test(value)) {\n value = cssCalc(value, opt);\n }\n // 5. Keyword & Color-space resolution\n let cs = '';\n let r = NaN;\n let g = NaN;\n let b = NaN;\n let alpha = NaN;\n if (value === 'transparent') {\n let res: string | null;\n switch (format) {\n case VAL_SPEC: {\n res = value;\n break;\n }\n case 'hex': {\n res = null;\n break;\n }\n case 'hexAlpha': {\n res = '#00000000';\n break;\n }\n default: {\n res = RGB_TRANSPARENT;\n }\n }\n setCache(cacheKey, res);\n return res;\n }\n if (value === 'currentcolor') {\n if (format === VAL_SPEC) {\n setCache(cacheKey, value);\n retLine truncated
+80
View File
@@ -0,0 +1,80 @@
/**
* typedef
*/
/**
* @typedef Options - options
* @property [alpha] - enable alpha
* @property [colorSpace] - color space
* @property [currentColor] - color for currentcolor
* @property [customProperty] - custom properties
* @property [d50] - white point in d50
* @property [dimension] - dimension
* @property [format] - output format
* @property [key] - key
*/
export interface Options {
alpha?: boolean;
colorScheme?: string;
colorSpace?: string;
currentColor?: string;
customProperty?: Record<string, string | ((K: string) => string)>;
d50?: boolean;
delimiter?: string | string[];
dimension?: Record<string, number | ((K: string) => number)>;
format?: string;
nullable?: boolean;
preserveComment?: boolean;
}
/**
* @type ColorChannels - color channels
*/
export type ColorChannels = [x: number, y: number, z: number, alpha: number];
/**
* @type StringColorChannels - color channels
*/
export type StringColorChannels = [
x: string,
y: string,
z: string,
alpha: string | undefined
];
/**
* @type StringColorSpacedChannels - specified value
*/
export type StringColorSpacedChannels = [
cs: string,
x: string,
y: string,
z: string,
alpha: string | undefined
];
/**
* @type ComputedColorChannels - computed value
*/
export type ComputedColorChannels = [
cs: string,
x: number,
y: number,
z: number,
alpha: number
];
/**
* @type SpecifiedColorChannels - specified value
*/
export type SpecifiedColorChannels = [
cs: string,
x: number | string,
y: number | string,
z: number | string,
alpha: number | string
];
/**
* @type MatchedRegExp - matched regexp array
*/
export type MatchedRegExp = [
match: string,
gr1: string,
gr2: string,
gr3: string,
gr4: string
];
+39
View File
@@ -0,0 +1,39 @@
import { Options } from './typedef.js';
/**
* split value
* NOTE: comments are stripped, it can be preserved if, in the options param,
* `delimiter` is either ',' or '/' and with `preserveComment` set to `true`
* @param value - CSS value
* @param [opt] - options
* @returns array of values
*/
export declare const splitValue: (value: string, opt?: Options) => string[];
/**
* extract dashed-ident tokens
* @param value - CSS value
* @returns array of dashed-ident tokens
*/
export declare const extractDashedIdent: (value: string) => string[];
/**
* round to specified precision
* @param value - numeric value
* @param bit - minimum bits
* @returns rounded value
*/
export declare const roundToPrecision: (value: number, bit?: number) => number;
/**
* interpolate hue
* @param hueA - hue value
* @param hueB - hue value
* @param arc - shorter | longer | increasing | decreasing
* @returns result - [hueA, hueB]
*/
export declare const interpolateHue: (hueA: number, hueB: number, arc?: string) => [number, number];
/**
* resolve length in pixels
* @param value - value
* @param unit - unit
* @param [opt] - options
* @returns pixelated value
*/
export declare const resolveLengthInPixels: (value: number | string, unit: string | undefined, opt?: Options) => number;
+222
View File
@@ -0,0 +1,222 @@
import { CacheItem, createCacheKey, getCache, setCache } from "./cache.js";
import { isString } from "./common.js";
import { TokenType, tokenize } from "@csstools/css-tokenizer";
//#region src/js/util.ts
/**
* util
*/
var { CloseParen: PAREN_CLOSE, Comma: COMMA, Comment: COMMENT, Delim: DELIM, EOF, Function: FUNC, OpenParen: PAREN_OPEN, Whitespace: W_SPACE } = TokenType;
var NAMESPACE = "util";
var DEC = 10;
var HEX = 16;
var DEG = 360;
var DEG_HALF = 180;
var REG_DASHED_IDENT = /--[\w-]+/g;
var REG_COMMA = /^,$/;
var REG_SLASH = /^\/$/;
var REG_WHITESPACE = /^\s+$/;
/**
* split value
* NOTE: comments are stripped, it can be preserved if, in the options param,
* `delimiter` is either ',' or '/' and with `preserveComment` set to `true`
* @param value - CSS value
* @param [opt] - options
* @returns array of values
*/
var splitValue = (value, opt = {}) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
const strValue = value.trim();
const { delimiter = " ", preserveComment = false } = opt;
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "splitValue",
value: strValue
}, {
delimiter,
preserveComment
});
const cachedResult = getCache(cacheKey);
if (cachedResult instanceof CacheItem) return cachedResult.item;
let regDelimiter;
switch (delimiter) {
case ",":
regDelimiter = REG_COMMA;
break;
case "/":
regDelimiter = REG_SLASH;
break;
default: regDelimiter = REG_WHITESPACE;
}
const tokens = tokenize({ css: strValue });
let nest = 0;
let currentStr = "";
const res = [];
for (const [type, val] of tokens) switch (type) {
case COMMA:
case DELIM:
if (nest === 0 && regDelimiter.test(val)) {
res.push(currentStr.trim());
currentStr = "";
} else currentStr += val;
break;
case COMMENT:
if (preserveComment && (delimiter === "," || delimiter === "/")) currentStr += val;
break;
case FUNC:
case PAREN_OPEN:
currentStr += val;
nest++;
break;
case PAREN_CLOSE:
currentStr += val;
nest--;
break;
case W_SPACE:
if (regDelimiter.test(val)) {
if (nest === 0) {
if (currentStr) {
res.push(currentStr.trim());
currentStr = "";
}
} else currentStr += " ";
} else if (!currentStr.endsWith(" ")) currentStr += " ";
break;
default: if (type === EOF) {
res.push(currentStr.trim());
currentStr = "";
} else currentStr += val;
}
setCache(cacheKey, res);
return res;
};
/**
* extract dashed-ident tokens
* @param value - CSS value
* @returns array of dashed-ident tokens
*/
var extractDashedIdent = (value) => {
if (!isString(value)) throw new TypeError(`${value} is not a string.`);
const strValue = value.trim();
const cacheKey = createCacheKey({
namespace: NAMESPACE,
name: "extractDashedIdent",
value: strValue
});
const cachedResult = getCache(cacheKey);
if (cachedResult instanceof CacheItem) return cachedResult.item;
const matches = strValue.match(REG_DASHED_IDENT);
const res = matches ? [...new Set(matches)] : [];
setCache(cacheKey, res);
return res;
};
/**
* round to specified precision
* @param value - numeric value
* @param bit - minimum bits
* @returns rounded value
*/
var roundToPrecision = (value, bit = 0) => {
if (!Number.isFinite(value)) throw new TypeError(`${value} is not a finite number.`);
if (!Number.isFinite(bit)) throw new TypeError(`${bit} is not a finite number.`);
if (bit < 0 || bit > HEX) throw new RangeError(`${bit} is not between 0 and ${HEX}.`);
if (bit === 0) return Math.round(value);
const precision = bit === HEX ? 6 : bit < DEC ? 4 : 5;
return parseFloat(value.toPrecision(precision));
};
/**
* interpolate hue
* @param hueA - hue value
* @param hueB - hue value
* @param arc - shorter | longer | increasing | decreasing
* @returns result - [hueA, hueB]
*/
var interpolateHue = (hueA, hueB, arc = "shorter") => {
if (!Number.isFinite(hueA)) throw new TypeError(`${hueA} is not a finite number.`);
if (!Number.isFinite(hueB)) throw new TypeError(`${hueB} is not a finite number.`);
let a = hueA;
let b = hueB;
switch (arc) {
case "decreasing":
if (b > a) a += DEG;
break;
case "increasing":
if (b < a) b += DEG;
break;
case "longer":
if (b > a && b < a + DEG_HALF) a += DEG;
else if (b > a - DEG_HALF && b <= a) b += DEG;
break;
default: if (b > a + DEG_HALF) a += DEG;
else if (b < a - DEG_HALF) b += DEG;
}
return [a, b];
};
var absoluteFontSize = /* @__PURE__ */ new Map([
["xx-small", 9 / 16],
["x-small", 5 / 8],
["small", 13 / 16],
["medium", 1],
["large", 9 / 8],
["x-large", 3 / 2],
["xx-large", 2],
["xxx-large", 3]
]);
var relativeFontSize = /* @__PURE__ */ new Map([["smaller", 1 / 1.2], ["larger", 1.2]]);
var absoluteLength = /* @__PURE__ */ new Map([
["cm", 96 / 2.54],
["mm", 96 / 25.4],
["q", 96 / 101.6],
["in", 96],
["pc", 16],
["pt", 96 / 72],
["px", 1]
]);
var relativeLength = /* @__PURE__ */ new Map([
["rcap", 1],
["rch", .5],
["rem", 1],
["rex", .5],
["ric", 1],
["rlh", 1.2]
]);
/**
* resolve length in pixels
* @param value - value
* @param unit - unit
* @param [opt] - options
* @returns pixelated value
*/
var resolveLengthInPixels = (value, unit, opt = {}) => {
const { dimension = {} } = opt;
const { callback, em, rem, vh, vw } = dimension;
if (isString(value)) {
const str = value.toLowerCase().trim();
const ratio = absoluteFontSize.get(str);
if (ratio !== void 0) return ratio * rem;
const relRatio = relativeFontSize.get(str);
if (relRatio !== void 0) return relRatio * em;
return NaN;
}
if (Number.isFinite(value) && unit) {
const u = unit.toLowerCase();
if (Object.hasOwn(dimension, u)) return value * Number(dimension[u]);
if (typeof callback === "function") return value * (callback(u) ?? NaN);
const absRatio = absoluteLength.get(u);
if (absRatio !== void 0) return value * absRatio;
const relRatio = relativeLength.get(u);
if (relRatio !== void 0) return value * relRatio * rem;
const rUnitRatio = relativeLength.get(`r${u}`);
if (rUnitRatio !== void 0) return value * rUnitRatio * em;
switch (u) {
case "vb": return value * vh;
case "vi": return value * vw;
case "vmax": return value * Math.max(vh, vw);
case "vmin": return value * Math.min(vh, vw);
}
}
return NaN;
};
//#endregion
export { extractDashedIdent, interpolateHue, resolveLengthInPixels, roundToPrecision, splitValue };
//# sourceMappingURL=util.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"util.js","names":[],"sources":["../../../src/js/util.ts"],"sourcesContent":["/**\n * util\n */\n\nimport { TokenType, tokenize } from '@csstools/css-tokenizer';\nimport { CacheItem, createCacheKey, getCache, setCache } from './cache';\nimport { isString } from './common';\nimport { Options } from './typedef';\n\n/* constants */\nconst {\n CloseParen: PAREN_CLOSE,\n Comma: COMMA,\n Comment: COMMENT,\n Delim: DELIM,\n EOF,\n Function: FUNC,\n OpenParen: PAREN_OPEN,\n Whitespace: W_SPACE\n} = TokenType;\nconst NAMESPACE = 'util';\n\n/* numeric constants */\nconst DEC = 10;\nconst HEX = 16;\nconst DEG = 360;\nconst DEG_HALF = 180;\n\n/* regexp */\nconst REG_DASHED_IDENT = /--[\\w-]+/g;\nconst REG_COMMA = /^,$/;\nconst REG_SLASH = /^\\/$/;\nconst REG_WHITESPACE = /^\\s+$/;\n\n/**\n * split value\n * NOTE: comments are stripped, it can be preserved if, in the options param,\n * `delimiter` is either ',' or '/' and with `preserveComment` set to `true`\n * @param value - CSS value\n * @param [opt] - options\n * @returns array of values\n */\nexport const splitValue = (value: string, opt: Options = {}): string[] => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const strValue = value.trim();\n const { delimiter = ' ', preserveComment = false } = opt;\n const cacheKey: string = createCacheKey(\n {\n namespace: NAMESPACE,\n name: 'splitValue',\n value: strValue\n },\n { delimiter, preserveComment }\n );\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string[];\n }\n let regDelimiter;\n switch (delimiter) {\n case ',': {\n regDelimiter = REG_COMMA;\n break;\n }\n case '/': {\n regDelimiter = REG_SLASH;\n break;\n }\n default: {\n regDelimiter = REG_WHITESPACE;\n }\n }\n const tokens = tokenize({ css: strValue });\n let nest = 0;\n let currentStr = '';\n const res: string[] = [];\n for (const [type, val] of tokens) {\n switch (type) {\n case COMMA:\n case DELIM: {\n if (nest === 0 && regDelimiter.test(val)) {\n res.push(currentStr.trim());\n currentStr = '';\n } else {\n currentStr += val;\n }\n break;\n }\n case COMMENT: {\n if (preserveComment && (delimiter === ',' || delimiter === '/')) {\n currentStr += val;\n }\n break;\n }\n case FUNC:\n case PAREN_OPEN: {\n currentStr += val;\n nest++;\n break;\n }\n case PAREN_CLOSE: {\n currentStr += val;\n nest--;\n break;\n }\n case W_SPACE: {\n if (regDelimiter.test(val)) {\n if (nest === 0) {\n if (currentStr) {\n res.push(currentStr.trim());\n currentStr = '';\n }\n } else {\n currentStr += ' ';\n }\n } else if (!currentStr.endsWith(' ')) {\n currentStr += ' ';\n }\n break;\n }\n default: {\n if (type === EOF) {\n res.push(currentStr.trim());\n currentStr = '';\n } else {\n currentStr += val;\n }\n }\n }\n }\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * extract dashed-ident tokens\n * @param value - CSS value\n * @returns array of dashed-ident tokens\n */\nexport const extractDashedIdent = (value: string): string[] => {\n if (!isString(value)) {\n throw new TypeError(`${value} is not a string.`);\n }\n const strValue = value.trim();\n const cacheKey: string = createCacheKey({\n namespace: NAMESPACE,\n name: 'extractDashedIdent',\n value: strValue\n });\n const cachedResult = getCache(cacheKey);\n if (cachedResult instanceof CacheItem) {\n return cachedResult.item as string[];\n }\n const matches = strValue.match(REG_DASHED_IDENT);\n const res = matches ? [...new Set(matches)] : [];\n setCache(cacheKey, res);\n return res;\n};\n\n/**\n * round to specified precision\n * @param value - numeric value\n * @param bit - minimum bits\n * @returns rounded value\n */\nexport const roundToPrecision = (value: number, bit: number = 0): number => {\n if (!Number.isFinite(value)) {\n throw new TypeError(`${value} is not a finite number.`);\n }\n if (!Number.isFinite(bit)) {\n throw new TypeError(`${bit} is not a finite number.`);\n }\n if (bit < 0 || bit > HEX) {\n throw new RangeError(`${bit} is not between 0 and ${HEX}.`);\n }\n if (bit === 0) {\n return Math.round(value);\n }\n const precision = bit === HEX ? 6 : bit < DEC ? 4 : 5;\n return parseFloat(value.toPrecision(precision));\n};\n\n/**\n * interpolate hue\n * @param hueA - hue value\n * @param hueB - hue value\n * @param arc - shorter | longer | increasing | decreasing\n * @returns result - [hueA, hueB]\n */\nexport const interpolateHue = (\n hueA: number,\n hueB: number,\n Line truncated
+82
View File
@@ -0,0 +1,82 @@
{
"name": "@asamuzakjp/css-color",
"description": "CSS color - Resolve and convert CSS colors.",
"author": "asamuzaK",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/asamuzaK/cssColor.git"
},
"homepage": "https://github.com/asamuzaK/cssColor#readme",
"bugs": {
"url": "https://github.com/asamuzaK/cssColor/issues"
},
"files": [
"dist",
"src"
],
"type": "module",
"types": "./dist/esm/index.d.ts",
"exports": {
".": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"./package.json": "./package.json"
},
"dependencies": {
"@csstools/css-calc": "^3.3.0",
"@csstools/css-color-parser": "^4.1.10",
"@csstools/css-parser-algorithms": "^4.0.0",
"@csstools/css-tokenizer": "^4.0.0",
"lru-cache": "^11.5.2"
},
"devDependencies": {
"@tanstack/vite-config": "^0.6.0",
"@types/node": "^26.2.0",
"@vitest/coverage-istanbul": "^4.1.10",
"esbuild": "^0.28.1",
"eslint": "^9.39.5",
"eslint-plugin-regexp": "^3.1.1",
"globals": "^17.9.0",
"knip": "^6.32.0",
"mitata": "^1.0.34",
"neostandard": "^0.13.0",
"prettier": "^3.9.6",
"publint": "^0.3.23",
"rimraf": "^6.1.3",
"tsx": "^4.23.11",
"typescript": "^6.0.3",
"vite": "^8.2.1",
"vitest": "^4.1.10"
},
"packageManager": "pnpm@10.34.4",
"pnpm": {
"onlyBuiltDependencies": [
"esbuild",
"oxc-resolver",
"unrs-resolver"
],
"overrides": {
"ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0",
"lodash@>=4.0.0 <=4.17.23": ">=4.18.0",
"minimatch@<3.1.4": ">=3.1.4"
}
},
"scripts": {
"bench:color": "npx tsx --expose-gc ./benchmark/bench-color.ts",
"build": "pnpm run clean && pnpm run test && pnpm run knip && vite build && pnpm run publint",
"clean": "rimraf ./coverage ./dist",
"knip": "knip",
"prettier": "prettier . --ignore-unknown --write",
"publint": "publint --strict",
"test": "pnpm run prettier && pnpm run --stream \"/^test:.*/\"",
"test:eslint": "eslint ./src ./test --fix",
"test:types": "tsc",
"test:unit": "vitest"
},
"engines": {
"node": "^22.13.0 || >=24.0.0"
},
"version": "6.0.7"
}
+29
View File
@@ -0,0 +1,29 @@
/*!
* CSS color - Resolve, parse, convert CSS color.
* @license MIT
* @copyright asamuzaK (Kazz)
* @see {@link https://github.com/asamuzaK/cssColor/blob/main/LICENSE}
*/
import { cssCalc, cssVar } from './js/css-calc-var';
import { isGradient, resolveGradient } from './js/css-gradient';
import { isColor } from './js/resolve';
import {
extractDashedIdent,
resolveLengthInPixels,
splitValue
} from './js/util';
export { convert } from './js/convert';
export { resolve } from './js/resolve';
/* utils */
export const utils = {
cssCalc,
cssVar,
extractDashedIdent,
isColor,
isGradient,
resolveGradient,
resolveLengthInPixels,
splitValue
};
+117
View File
@@ -0,0 +1,117 @@
/**
* cache
*/
import { LRUCache } from 'lru-cache';
import { Options } from './typedef';
/* constants */
const CACHE_SIZE = 4096;
/**
* CacheItem
*/
export class CacheItem {
/* private */
#item: unknown;
constructor(item: unknown) {
this.#item = item;
}
get item() {
return this.#item;
}
}
/*
* lru cache instance
*/
export const lruCache = new LRUCache<string, CacheItem>({
max: CACHE_SIZE
});
/**
* set cache
* @param key - cache key
* @param value - value to cache
* @returns void
*/
export const setCache = (key: string, value: unknown): void => {
if (!key) {
return;
}
if (value instanceof CacheItem) {
lruCache.set(key, value);
} else {
lruCache.set(key, new CacheItem(value));
}
};
/**
* get cache
* @param key - cache key
* @returns cached item or false otherwise
*/
export const getCache = (key: string): CacheItem | false => {
if (!key) {
return false;
}
const item = lruCache.get(key);
if (item !== undefined) {
return item as CacheItem;
}
return false;
};
/**
* helper function to sort object keys alphabetically
* @param obj - Object
* @returns stringified JSON
*/
const stringifySorted = (obj: Record<string, unknown>): string => {
const keys = Object.keys(obj);
if (keys.length === 0) {
return '';
}
keys.sort();
let result = '';
for (const key of keys) {
result += `${key}:${JSON.stringify(obj[key])};`;
}
return result;
};
/**
* create cache key
* @param keyData - key data
* @param [opt] - options
* @returns cache key
*/
export const createCacheKey = (
keyData: Record<string, string>,
opt: Options = {}
): string => {
if (
!keyData ||
(opt.customProperty && typeof opt.customProperty.callback === 'function') ||
(opt.dimension && typeof opt.dimension.callback === 'function')
) {
return '';
}
const namespace = keyData.namespace || '';
const name = keyData.name || '';
const value = keyData.value || '';
if (!namespace && !name && !value) {
return '';
}
const baseKey = `${namespace}:${name}:${value}`;
const optStr = `${opt.format || ''}|${opt.colorSpace || ''}|${opt.colorScheme || ''}|${opt.currentColor || ''}|${opt.d50 ? '1' : '0'}|${opt.nullable ? '1' : '0'}|${opt.preserveComment ? '1' : '0'}|${opt.delimiter || ''}`;
const customPropStr = opt.customProperty
? stringifySorted(opt.customProperty as Record<string, unknown>)
: '';
const dimStr = opt.dimension
? stringifySorted(opt.dimension as Record<string, unknown>)
: '';
return `${baseKey}::${optStr}::${customPropStr}::${dimStr}`;
};
Loaded 100 of 8152 files, more files were not shown because too many files have changed in this diff. Show more