tailwindcss-patch 8.7.3 → 8.7.4-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-7JAOSSRO.js → chunk-5CWNAWKP.js} +1 -1
- package/dist/{chunk-3T6WSV7F.mjs → chunk-6ZDYMYHE.mjs} +261 -92
- package/dist/{chunk-JHEI2MLC.mjs → chunk-A67ABH3M.mjs} +1 -1
- package/dist/{chunk-EFYAZO6C.js → chunk-ZXW4S356.js} +235 -66
- package/dist/cli.js +5 -5
- package/dist/cli.mjs +2 -2
- package/dist/{dist-NW65QXLC.js → dist-7O2232CU.js} +1 -1
- package/dist/{dist-EMUBVNNO.mjs → dist-7UDSGIWH.mjs} +1 -1
- package/dist/index.d.mts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -3
- package/dist/index.mjs +2 -2
- package/package.json +6 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__dirname
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-A67ABH3M.mjs";
|
|
4
4
|
|
|
5
5
|
// src/logger.ts
|
|
6
6
|
import { createConsola } from "consola";
|
|
@@ -20,7 +20,7 @@ import path from "pathe";
|
|
|
20
20
|
// package.json
|
|
21
21
|
var package_default = {
|
|
22
22
|
name: "tailwindcss-patch",
|
|
23
|
-
version: "8.7.
|
|
23
|
+
version: "8.7.4-alpha.0",
|
|
24
24
|
description: "patch tailwindcss for exposing context and extract classes",
|
|
25
25
|
author: "ice breaker <1324318532@qq.com>",
|
|
26
26
|
license: "MIT",
|
|
@@ -66,6 +66,7 @@ var package_default = {
|
|
|
66
66
|
build: "tsup",
|
|
67
67
|
test: "vitest run",
|
|
68
68
|
"test:dev": "vitest",
|
|
69
|
+
"bench:cold-start": "node --import tsx bench/cold-start.ts",
|
|
69
70
|
patch: "tsx dev/bin.ts install",
|
|
70
71
|
r0: "tsx dev/bin.ts extract",
|
|
71
72
|
r1: "tsx dev/bin.ts extract --css index.css"
|
|
@@ -106,12 +107,12 @@ var package_default = {
|
|
|
106
107
|
"@babel/types": "^7.29.0",
|
|
107
108
|
"@tailwindcss-mangle/config": "workspace:*",
|
|
108
109
|
"@tailwindcss/node": "^4.2.1",
|
|
109
|
-
cac: "^
|
|
110
|
+
cac: "^7.0.0",
|
|
110
111
|
consola: "^3.4.2",
|
|
111
|
-
"fs-extra": "^11.3.
|
|
112
|
+
"fs-extra": "^11.3.4",
|
|
112
113
|
"local-pkg": "^1.1.2",
|
|
113
114
|
pathe: "^2.0.3",
|
|
114
|
-
postcss: "^8.5.
|
|
115
|
+
postcss: "^8.5.8",
|
|
115
116
|
semver: "^7.7.4",
|
|
116
117
|
"tailwindcss-config": "^1.1.4"
|
|
117
118
|
},
|
|
@@ -1906,7 +1907,7 @@ async function loadWorkspaceConfigModule() {
|
|
|
1906
1907
|
}
|
|
1907
1908
|
async function loadWorkspaceDefu() {
|
|
1908
1909
|
if (!defuPromise) {
|
|
1909
|
-
defuPromise = import("./dist-
|
|
1910
|
+
defuPromise = import("./dist-7UDSGIWH.mjs").then((mod) => mod.defu).catch(async (error) => {
|
|
1910
1911
|
if (!isMissingSharedModuleError(error)) {
|
|
1911
1912
|
throw error;
|
|
1912
1913
|
}
|
|
@@ -1931,33 +1932,66 @@ async function loadPatchOptionsForWorkspace(cwd, overrides) {
|
|
|
1931
1932
|
import { promises as fs4 } from "fs";
|
|
1932
1933
|
import process4 from "process";
|
|
1933
1934
|
import path4 from "pathe";
|
|
1935
|
+
var nodeImportPromise;
|
|
1936
|
+
var oxideImportPromise;
|
|
1937
|
+
var designSystemPromiseCache = /* @__PURE__ */ new Map();
|
|
1938
|
+
var designSystemCandidateCache = /* @__PURE__ */ new Map();
|
|
1934
1939
|
async function importNode() {
|
|
1935
1940
|
return import("@tailwindcss/node");
|
|
1936
1941
|
}
|
|
1937
1942
|
async function importOxide() {
|
|
1938
1943
|
return import("@tailwindcss/oxide");
|
|
1939
1944
|
}
|
|
1945
|
+
function getNodeModule() {
|
|
1946
|
+
nodeImportPromise ??= importNode();
|
|
1947
|
+
return nodeImportPromise;
|
|
1948
|
+
}
|
|
1949
|
+
function getOxideModule() {
|
|
1950
|
+
oxideImportPromise ??= importOxide();
|
|
1951
|
+
return oxideImportPromise;
|
|
1952
|
+
}
|
|
1953
|
+
function createDesignSystemCacheKey(css, bases) {
|
|
1954
|
+
return JSON.stringify({
|
|
1955
|
+
css,
|
|
1956
|
+
bases: Array.from(new Set(bases.filter(Boolean)))
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1940
1959
|
async function loadDesignSystem(css, bases) {
|
|
1941
1960
|
const uniqueBases = Array.from(new Set(bases.filter(Boolean)));
|
|
1942
1961
|
if (uniqueBases.length === 0) {
|
|
1943
1962
|
throw new Error("No base directories provided for Tailwind CSS design system.");
|
|
1944
1963
|
}
|
|
1945
|
-
const
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
return await __unstable__loadDesignSystem(css, { base });
|
|
1950
|
-
} catch (error) {
|
|
1951
|
-
lastError = error;
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
if (lastError instanceof Error) {
|
|
1955
|
-
throw lastError;
|
|
1964
|
+
const cacheKey = createDesignSystemCacheKey(css, uniqueBases);
|
|
1965
|
+
const cached = designSystemPromiseCache.get(cacheKey);
|
|
1966
|
+
if (cached) {
|
|
1967
|
+
return cached;
|
|
1956
1968
|
}
|
|
1957
|
-
|
|
1969
|
+
const promise = (async () => {
|
|
1970
|
+
const { __unstable__loadDesignSystem } = await getNodeModule();
|
|
1971
|
+
let lastError;
|
|
1972
|
+
for (const base of uniqueBases) {
|
|
1973
|
+
try {
|
|
1974
|
+
return await __unstable__loadDesignSystem(css, { base });
|
|
1975
|
+
} catch (error) {
|
|
1976
|
+
lastError = error;
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
if (lastError instanceof Error) {
|
|
1980
|
+
throw lastError;
|
|
1981
|
+
}
|
|
1982
|
+
throw new Error("Failed to load Tailwind CSS design system.");
|
|
1983
|
+
})();
|
|
1984
|
+
designSystemPromiseCache.set(cacheKey, promise);
|
|
1985
|
+
promise.catch(() => {
|
|
1986
|
+
if (designSystemPromiseCache.get(cacheKey) === promise) {
|
|
1987
|
+
designSystemPromiseCache.delete(cacheKey);
|
|
1988
|
+
designSystemCandidateCache.delete(cacheKey);
|
|
1989
|
+
}
|
|
1990
|
+
});
|
|
1991
|
+
return promise;
|
|
1958
1992
|
}
|
|
1959
1993
|
async function extractRawCandidatesWithPositions(content, extension = "html") {
|
|
1960
|
-
const { Scanner } = await
|
|
1994
|
+
const { Scanner } = await getOxideModule();
|
|
1961
1995
|
const scanner = new Scanner({});
|
|
1962
1996
|
const result = scanner.getCandidatesWithPositions({ content, extension });
|
|
1963
1997
|
return result.map(({ candidate, position }) => ({
|
|
@@ -1967,7 +2001,7 @@ async function extractRawCandidatesWithPositions(content, extension = "html") {
|
|
|
1967
2001
|
}));
|
|
1968
2002
|
}
|
|
1969
2003
|
async function extractRawCandidates(sources) {
|
|
1970
|
-
const { Scanner } = await
|
|
2004
|
+
const { Scanner } = await getOxideModule();
|
|
1971
2005
|
const scanner = new Scanner(sources === void 0 ? {} : { sources });
|
|
1972
2006
|
return scanner.scan();
|
|
1973
2007
|
}
|
|
@@ -1988,25 +2022,44 @@ async function extractValidCandidates(options) {
|
|
|
1988
2022
|
pattern: source.pattern,
|
|
1989
2023
|
negated: source.negated
|
|
1990
2024
|
}));
|
|
2025
|
+
const designSystemKey = createDesignSystemCacheKey(css, [base, ...baseFallbacks]);
|
|
1991
2026
|
const designSystem = await loadDesignSystem(css, [base, ...baseFallbacks]);
|
|
2027
|
+
const candidateCache = designSystemCandidateCache.get(designSystemKey) ?? /* @__PURE__ */ new Map();
|
|
2028
|
+
designSystemCandidateCache.set(designSystemKey, candidateCache);
|
|
1992
2029
|
const candidates = await extractRawCandidates(sources);
|
|
1993
|
-
const parsedCandidates = candidates.filter(
|
|
1994
|
-
(rawCandidate) => designSystem.parseCandidate(rawCandidate).length > 0
|
|
1995
|
-
);
|
|
1996
|
-
if (parsedCandidates.length === 0) {
|
|
1997
|
-
return parsedCandidates;
|
|
1998
|
-
}
|
|
1999
|
-
const cssByCandidate = designSystem.candidatesToCss(parsedCandidates);
|
|
2000
2030
|
const validCandidates = [];
|
|
2001
|
-
|
|
2002
|
-
|
|
2031
|
+
const uncachedCandidates = [];
|
|
2032
|
+
for (const rawCandidate of candidates) {
|
|
2033
|
+
const cached = candidateCache.get(rawCandidate);
|
|
2034
|
+
if (cached === true) {
|
|
2035
|
+
validCandidates.push(rawCandidate);
|
|
2036
|
+
continue;
|
|
2037
|
+
}
|
|
2038
|
+
if (cached === false) {
|
|
2039
|
+
continue;
|
|
2040
|
+
}
|
|
2041
|
+
if (designSystem.parseCandidate(rawCandidate).length > 0) {
|
|
2042
|
+
uncachedCandidates.push(rawCandidate);
|
|
2043
|
+
continue;
|
|
2044
|
+
}
|
|
2045
|
+
candidateCache.set(rawCandidate, false);
|
|
2046
|
+
}
|
|
2047
|
+
if (uncachedCandidates.length === 0) {
|
|
2048
|
+
return validCandidates;
|
|
2049
|
+
}
|
|
2050
|
+
const cssByCandidate = designSystem.candidatesToCss(uncachedCandidates);
|
|
2051
|
+
for (let index = 0; index < uncachedCandidates.length; index++) {
|
|
2052
|
+
const candidate = uncachedCandidates[index];
|
|
2003
2053
|
if (candidate === void 0) {
|
|
2004
2054
|
continue;
|
|
2005
2055
|
}
|
|
2006
|
-
const
|
|
2007
|
-
|
|
2008
|
-
|
|
2056
|
+
const candidateCss = cssByCandidate[index];
|
|
2057
|
+
const isValid = typeof candidateCss === "string" && candidateCss.trim().length > 0;
|
|
2058
|
+
candidateCache.set(candidate, isValid);
|
|
2059
|
+
if (!isValid) {
|
|
2060
|
+
continue;
|
|
2009
2061
|
}
|
|
2062
|
+
validCandidates.push(candidate);
|
|
2010
2063
|
}
|
|
2011
2064
|
return validCandidates;
|
|
2012
2065
|
}
|
|
@@ -2078,7 +2131,7 @@ function toRelativeFile(cwd, filename) {
|
|
|
2078
2131
|
async function extractProjectCandidatesWithPositions(options) {
|
|
2079
2132
|
const cwd = options?.cwd ? path4.resolve(options.cwd) : process4.cwd();
|
|
2080
2133
|
const normalizedSources = normalizeSources(options?.sources, cwd);
|
|
2081
|
-
const { Scanner } = await
|
|
2134
|
+
const { Scanner } = await getOxideModule();
|
|
2082
2135
|
const scanner = new Scanner({
|
|
2083
2136
|
sources: normalizedSources
|
|
2084
2137
|
});
|
|
@@ -2313,10 +2366,53 @@ function loadRuntimeContexts(packageInfo, majorVersion, refProperty) {
|
|
|
2313
2366
|
|
|
2314
2367
|
// src/runtime/process-tailwindcss.ts
|
|
2315
2368
|
import { createRequire as createRequire2 } from "module";
|
|
2369
|
+
import fs7 from "fs-extra";
|
|
2316
2370
|
import path7 from "pathe";
|
|
2317
2371
|
import postcss from "postcss";
|
|
2318
2372
|
import { loadConfig } from "tailwindcss-config";
|
|
2319
2373
|
var require3 = createRequire2(import.meta.url);
|
|
2374
|
+
function resolveModuleEntry(id) {
|
|
2375
|
+
return path7.isAbsolute(id) ? id : require3.resolve(id);
|
|
2376
|
+
}
|
|
2377
|
+
function resolvePackageRootFromEntry(entry) {
|
|
2378
|
+
let current = path7.dirname(entry);
|
|
2379
|
+
while (current && current !== path7.dirname(current)) {
|
|
2380
|
+
const packageJsonPath = path7.join(current, "package.json");
|
|
2381
|
+
if (fs7.pathExistsSync(packageJsonPath)) {
|
|
2382
|
+
return current;
|
|
2383
|
+
}
|
|
2384
|
+
current = path7.dirname(current);
|
|
2385
|
+
}
|
|
2386
|
+
return void 0;
|
|
2387
|
+
}
|
|
2388
|
+
function clearTailwindV3RuntimeState(pluginName) {
|
|
2389
|
+
try {
|
|
2390
|
+
const entry = resolveModuleEntry(pluginName);
|
|
2391
|
+
const root = resolvePackageRootFromEntry(entry);
|
|
2392
|
+
if (!root) {
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
const sharedStatePath = path7.join(root, "lib/lib/sharedState.js");
|
|
2396
|
+
if (!fs7.pathExistsSync(sharedStatePath)) {
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
const sharedState = require3.cache[sharedStatePath]?.exports;
|
|
2400
|
+
sharedState?.contextMap?.clear();
|
|
2401
|
+
sharedState?.configContextMap?.clear();
|
|
2402
|
+
sharedState?.contextSourcesMap?.clear();
|
|
2403
|
+
sharedState?.sourceHashMap?.clear();
|
|
2404
|
+
for (const candidate of ["lib/plugin.js", "lib/index.js"]) {
|
|
2405
|
+
const runtimeEntry = path7.join(root, candidate);
|
|
2406
|
+
if (!fs7.pathExistsSync(runtimeEntry)) {
|
|
2407
|
+
continue;
|
|
2408
|
+
}
|
|
2409
|
+
const runtimeModule = require3.cache[runtimeEntry]?.exports;
|
|
2410
|
+
runtimeModule?.contextRef?.value?.splice(0, runtimeModule.contextRef.value.length);
|
|
2411
|
+
break;
|
|
2412
|
+
}
|
|
2413
|
+
} catch {
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2320
2416
|
async function resolveConfigPath(options) {
|
|
2321
2417
|
if (options.config && path7.isAbsolute(options.config)) {
|
|
2322
2418
|
return options.config;
|
|
@@ -2330,6 +2426,9 @@ async function resolveConfigPath(options) {
|
|
|
2330
2426
|
async function runTailwindBuild(options) {
|
|
2331
2427
|
const configPath = await resolveConfigPath(options);
|
|
2332
2428
|
const pluginName = options.postcssPlugin ?? (options.majorVersion === 4 ? "@tailwindcss/postcss" : "tailwindcss");
|
|
2429
|
+
if (options.majorVersion === 3) {
|
|
2430
|
+
clearTailwindV3RuntimeState(pluginName);
|
|
2431
|
+
}
|
|
2333
2432
|
if (options.majorVersion === 4) {
|
|
2334
2433
|
return postcss([
|
|
2335
2434
|
require3(pluginName)({
|
|
@@ -2350,7 +2449,7 @@ async function runTailwindBuild(options) {
|
|
|
2350
2449
|
|
|
2351
2450
|
// src/patching/status.ts
|
|
2352
2451
|
import * as t4 from "@babel/types";
|
|
2353
|
-
import
|
|
2452
|
+
import fs9 from "fs-extra";
|
|
2354
2453
|
import path9 from "pathe";
|
|
2355
2454
|
|
|
2356
2455
|
// src/babel/index.ts
|
|
@@ -2695,7 +2794,7 @@ function transformPostcssPlugin(content, { refProperty }) {
|
|
|
2695
2794
|
|
|
2696
2795
|
// src/patching/operations/extend-length-units.ts
|
|
2697
2796
|
import * as t3 from "@babel/types";
|
|
2698
|
-
import
|
|
2797
|
+
import fs8 from "fs-extra";
|
|
2699
2798
|
import path8 from "pathe";
|
|
2700
2799
|
function updateLengthUnitsArray(content, options) {
|
|
2701
2800
|
const { variableName = "lengthUnits", units } = options;
|
|
@@ -2739,11 +2838,11 @@ function applyExtendLengthUnitsPatchV3(rootDir, options) {
|
|
|
2739
2838
|
variableName: options.variableName ?? "lengthUnits"
|
|
2740
2839
|
};
|
|
2741
2840
|
const dataTypesFilePath = path8.resolve(rootDir, opts.lengthUnitsFilePath);
|
|
2742
|
-
const exists =
|
|
2841
|
+
const exists = fs8.existsSync(dataTypesFilePath);
|
|
2743
2842
|
if (!exists) {
|
|
2744
2843
|
return { changed: false, code: void 0 };
|
|
2745
2844
|
}
|
|
2746
|
-
const content =
|
|
2845
|
+
const content = fs8.readFileSync(dataTypesFilePath, "utf8");
|
|
2747
2846
|
const { arrayRef, changed } = updateLengthUnitsArray(content, opts);
|
|
2748
2847
|
if (!arrayRef || !changed) {
|
|
2749
2848
|
return { changed: false, code: void 0 };
|
|
@@ -2755,7 +2854,7 @@ function applyExtendLengthUnitsPatchV3(rootDir, options) {
|
|
|
2755
2854
|
const nextCode = `${content.slice(0, arrayRef.start)}${code}${content.slice(arrayRef.end)}`;
|
|
2756
2855
|
if (opts.overwrite) {
|
|
2757
2856
|
const target = opts.destPath ? path8.resolve(opts.destPath) : dataTypesFilePath;
|
|
2758
|
-
|
|
2857
|
+
fs8.writeFileSync(target, nextCode, "utf8");
|
|
2759
2858
|
logger_default.success("Patched Tailwind CSS length unit list (v3).");
|
|
2760
2859
|
}
|
|
2761
2860
|
return {
|
|
@@ -2774,15 +2873,15 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
|
|
|
2774
2873
|
}
|
|
2775
2874
|
const opts = { ...options };
|
|
2776
2875
|
const distDir = path8.resolve(rootDir, "dist");
|
|
2777
|
-
if (!
|
|
2876
|
+
if (!fs8.existsSync(distDir)) {
|
|
2778
2877
|
return { files: [], changed: false };
|
|
2779
2878
|
}
|
|
2780
|
-
const entries =
|
|
2879
|
+
const entries = fs8.readdirSync(distDir);
|
|
2781
2880
|
const chunkNames = entries.filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs"));
|
|
2782
2881
|
const pattern = /\[\s*["']cm["'],\s*["']mm["'],[\w,"']+\]/;
|
|
2783
2882
|
const candidates = chunkNames.map((chunkName) => {
|
|
2784
2883
|
const file = path8.join(distDir, chunkName);
|
|
2785
|
-
const code =
|
|
2884
|
+
const code = fs8.readFileSync(file, "utf8");
|
|
2786
2885
|
const match = pattern.exec(code);
|
|
2787
2886
|
if (!match) {
|
|
2788
2887
|
return null;
|
|
@@ -2822,7 +2921,7 @@ function applyExtendLengthUnitsPatchV4(rootDir, options) {
|
|
|
2822
2921
|
}
|
|
2823
2922
|
]);
|
|
2824
2923
|
if (opts.overwrite) {
|
|
2825
|
-
|
|
2924
|
+
fs8.writeFileSync(file, item.code, "utf8");
|
|
2826
2925
|
}
|
|
2827
2926
|
}
|
|
2828
2927
|
if (candidates.some((file) => !file.hasPatched)) {
|
|
@@ -2878,11 +2977,11 @@ function checkExposeContextPatch(context) {
|
|
|
2878
2977
|
const checks = [];
|
|
2879
2978
|
function inspectFile(relative, transform) {
|
|
2880
2979
|
const filePath = path9.resolve(packageInfo.rootPath, relative);
|
|
2881
|
-
if (!
|
|
2980
|
+
if (!fs9.existsSync(filePath)) {
|
|
2882
2981
|
checks.push({ relative, exists: false, patched: false });
|
|
2883
2982
|
return;
|
|
2884
2983
|
}
|
|
2885
|
-
const content =
|
|
2984
|
+
const content = fs9.readFileSync(filePath, "utf8");
|
|
2886
2985
|
const { hasPatched } = transform(content);
|
|
2887
2986
|
checks.push({
|
|
2888
2987
|
relative,
|
|
@@ -2893,7 +2992,7 @@ function checkExposeContextPatch(context) {
|
|
|
2893
2992
|
if (majorVersion === 3) {
|
|
2894
2993
|
inspectFile("lib/processTailwindFeatures.js", transformProcessTailwindFeaturesReturnContext);
|
|
2895
2994
|
const pluginCandidates = ["lib/plugin.js", "lib/index.js"];
|
|
2896
|
-
const pluginRelative = pluginCandidates.find((candidate) =>
|
|
2995
|
+
const pluginRelative = pluginCandidates.find((candidate) => fs9.existsSync(path9.resolve(packageInfo.rootPath, candidate)));
|
|
2897
2996
|
if (pluginRelative) {
|
|
2898
2997
|
inspectFile(pluginRelative, (content) => transformPostcssPlugin(content, { refProperty }));
|
|
2899
2998
|
} else {
|
|
@@ -2924,8 +3023,8 @@ function checkExtendLengthUnitsV3(rootDir, options) {
|
|
|
2924
3023
|
const lengthUnitsFilePath = options.lengthUnitsFilePath ?? "lib/util/dataTypes.js";
|
|
2925
3024
|
const variableName = options.variableName ?? "lengthUnits";
|
|
2926
3025
|
const target = path9.resolve(rootDir, lengthUnitsFilePath);
|
|
2927
|
-
const files =
|
|
2928
|
-
if (!
|
|
3026
|
+
const files = fs9.existsSync(target) ? [path9.relative(rootDir, target)] : [];
|
|
3027
|
+
if (!fs9.existsSync(target)) {
|
|
2929
3028
|
return {
|
|
2930
3029
|
name: "extendLengthUnits",
|
|
2931
3030
|
status: "not-applied",
|
|
@@ -2933,7 +3032,7 @@ function checkExtendLengthUnitsV3(rootDir, options) {
|
|
|
2933
3032
|
files
|
|
2934
3033
|
};
|
|
2935
3034
|
}
|
|
2936
|
-
const content =
|
|
3035
|
+
const content = fs9.readFileSync(target, "utf8");
|
|
2937
3036
|
const { found, missingUnits } = inspectLengthUnitsArray(content, variableName, options.units);
|
|
2938
3037
|
if (!found) {
|
|
2939
3038
|
return {
|
|
@@ -2959,7 +3058,7 @@ function checkExtendLengthUnitsV3(rootDir, options) {
|
|
|
2959
3058
|
}
|
|
2960
3059
|
function checkExtendLengthUnitsV4(rootDir, options) {
|
|
2961
3060
|
const distDir = path9.resolve(rootDir, "dist");
|
|
2962
|
-
if (!
|
|
3061
|
+
if (!fs9.existsSync(distDir)) {
|
|
2963
3062
|
return {
|
|
2964
3063
|
name: "extendLengthUnits",
|
|
2965
3064
|
status: "not-applied",
|
|
@@ -3036,19 +3135,19 @@ function getPatchStatusReport(context) {
|
|
|
3036
3135
|
|
|
3037
3136
|
// src/api/tailwindcss-patcher.ts
|
|
3038
3137
|
import process6 from "process";
|
|
3039
|
-
import
|
|
3138
|
+
import fs11 from "fs-extra";
|
|
3040
3139
|
import { getPackageInfoSync } from "local-pkg";
|
|
3041
3140
|
import path11 from "pathe";
|
|
3042
3141
|
import { coerce } from "semver";
|
|
3043
3142
|
|
|
3044
3143
|
// src/patching/operations/export-context/index.ts
|
|
3045
|
-
import
|
|
3144
|
+
import fs10 from "fs-extra";
|
|
3046
3145
|
import path10 from "pathe";
|
|
3047
3146
|
function writeFileIfRequired(filePath, code, overwrite, successMessage) {
|
|
3048
3147
|
if (!overwrite) {
|
|
3049
3148
|
return;
|
|
3050
3149
|
}
|
|
3051
|
-
|
|
3150
|
+
fs10.writeFileSync(filePath, code, {
|
|
3052
3151
|
encoding: "utf8"
|
|
3053
3152
|
});
|
|
3054
3153
|
logger_default.success(successMessage);
|
|
@@ -3062,8 +3161,8 @@ function applyExposeContextPatch(params) {
|
|
|
3062
3161
|
if (majorVersion === 3) {
|
|
3063
3162
|
const processFileRelative = "lib/processTailwindFeatures.js";
|
|
3064
3163
|
const processFilePath = path10.resolve(rootDir, processFileRelative);
|
|
3065
|
-
if (
|
|
3066
|
-
const content =
|
|
3164
|
+
if (fs10.existsSync(processFilePath)) {
|
|
3165
|
+
const content = fs10.readFileSync(processFilePath, "utf8");
|
|
3067
3166
|
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContext(content);
|
|
3068
3167
|
result.files[processFileRelative] = code;
|
|
3069
3168
|
if (!hasPatched) {
|
|
@@ -3077,10 +3176,10 @@ function applyExposeContextPatch(params) {
|
|
|
3077
3176
|
}
|
|
3078
3177
|
}
|
|
3079
3178
|
const pluginCandidates = ["lib/plugin.js", "lib/index.js"];
|
|
3080
|
-
const pluginRelative = pluginCandidates.find((candidate) =>
|
|
3179
|
+
const pluginRelative = pluginCandidates.find((candidate) => fs10.existsSync(path10.resolve(rootDir, candidate)));
|
|
3081
3180
|
if (pluginRelative) {
|
|
3082
3181
|
const pluginPath = path10.resolve(rootDir, pluginRelative);
|
|
3083
|
-
const content =
|
|
3182
|
+
const content = fs10.readFileSync(pluginPath, "utf8");
|
|
3084
3183
|
const { code, hasPatched } = transformPostcssPlugin(content, { refProperty });
|
|
3085
3184
|
result.files[pluginRelative] = code;
|
|
3086
3185
|
if (!hasPatched) {
|
|
@@ -3096,8 +3195,8 @@ function applyExposeContextPatch(params) {
|
|
|
3096
3195
|
} else if (majorVersion === 2) {
|
|
3097
3196
|
const processFileRelative = "lib/jit/processTailwindFeatures.js";
|
|
3098
3197
|
const processFilePath = path10.resolve(rootDir, processFileRelative);
|
|
3099
|
-
if (
|
|
3100
|
-
const content =
|
|
3198
|
+
if (fs10.existsSync(processFilePath)) {
|
|
3199
|
+
const content = fs10.readFileSync(processFilePath, "utf8");
|
|
3101
3200
|
const { code, hasPatched } = transformProcessTailwindFeaturesReturnContextV2(content);
|
|
3102
3201
|
result.files[processFileRelative] = code;
|
|
3103
3202
|
if (!hasPatched) {
|
|
@@ -3112,8 +3211,8 @@ function applyExposeContextPatch(params) {
|
|
|
3112
3211
|
}
|
|
3113
3212
|
const pluginRelative = "lib/jit/index.js";
|
|
3114
3213
|
const pluginPath = path10.resolve(rootDir, pluginRelative);
|
|
3115
|
-
if (
|
|
3116
|
-
const content =
|
|
3214
|
+
if (fs10.existsSync(pluginPath)) {
|
|
3215
|
+
const content = fs10.readFileSync(pluginPath, "utf8");
|
|
3117
3216
|
const { code, hasPatched } = transformPostcssPluginV2(content, { refProperty });
|
|
3118
3217
|
result.files[pluginRelative] = code;
|
|
3119
3218
|
if (!hasPatched) {
|
|
@@ -3205,6 +3304,8 @@ var TailwindcssPatcher = class {
|
|
|
3205
3304
|
majorVersion;
|
|
3206
3305
|
cacheContext;
|
|
3207
3306
|
cacheStore;
|
|
3307
|
+
patchMemo;
|
|
3308
|
+
inFlightBuild;
|
|
3208
3309
|
constructor(options = {}) {
|
|
3209
3310
|
const resolvedOptions = options && typeof options === "object" && "patch" in options ? fromLegacyOptions(options) : options;
|
|
3210
3311
|
this.options = normalizeOptions(resolvedOptions);
|
|
@@ -3228,11 +3329,20 @@ var TailwindcssPatcher = class {
|
|
|
3228
3329
|
this.cacheStore = new CacheStore(this.options.cache, this.cacheContext);
|
|
3229
3330
|
}
|
|
3230
3331
|
async patch() {
|
|
3231
|
-
|
|
3332
|
+
const snapshot = this.createPatchSnapshot();
|
|
3333
|
+
if (this.patchMemo && this.patchMemo.snapshot === snapshot) {
|
|
3334
|
+
return this.patchMemo.result;
|
|
3335
|
+
}
|
|
3336
|
+
const result = applyTailwindPatches({
|
|
3232
3337
|
packageInfo: this.packageInfo,
|
|
3233
3338
|
options: this.options,
|
|
3234
3339
|
majorVersion: this.majorVersion
|
|
3235
3340
|
});
|
|
3341
|
+
this.patchMemo = {
|
|
3342
|
+
result,
|
|
3343
|
+
snapshot: this.createPatchSnapshot()
|
|
3344
|
+
};
|
|
3345
|
+
return result;
|
|
3236
3346
|
}
|
|
3237
3347
|
async getPatchStatus() {
|
|
3238
3348
|
return getPatchStatusReport({
|
|
@@ -3250,6 +3360,9 @@ var TailwindcssPatcher = class {
|
|
|
3250
3360
|
}
|
|
3251
3361
|
async runTailwindBuildIfNeeded() {
|
|
3252
3362
|
if (this.majorVersion === 2 || this.majorVersion === 3) {
|
|
3363
|
+
if (this.inFlightBuild) {
|
|
3364
|
+
return this.inFlightBuild;
|
|
3365
|
+
}
|
|
3253
3366
|
const executionOptions = resolveTailwindExecutionOptions(this.options, this.majorVersion);
|
|
3254
3367
|
const buildOptions = {
|
|
3255
3368
|
cwd: executionOptions.cwd,
|
|
@@ -3257,8 +3370,53 @@ var TailwindcssPatcher = class {
|
|
|
3257
3370
|
...executionOptions.config === void 0 ? {} : { config: executionOptions.config },
|
|
3258
3371
|
...executionOptions.postcssPlugin === void 0 ? {} : { postcssPlugin: executionOptions.postcssPlugin }
|
|
3259
3372
|
};
|
|
3260
|
-
|
|
3373
|
+
this.inFlightBuild = runTailwindBuild(buildOptions).then(() => void 0);
|
|
3374
|
+
try {
|
|
3375
|
+
await this.inFlightBuild;
|
|
3376
|
+
} finally {
|
|
3377
|
+
this.inFlightBuild = void 0;
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
createPatchSnapshot() {
|
|
3382
|
+
const entries = [];
|
|
3383
|
+
const pushSnapshot = (filePath) => {
|
|
3384
|
+
if (!fs11.pathExistsSync(filePath)) {
|
|
3385
|
+
entries.push(`${filePath}:missing`);
|
|
3386
|
+
return;
|
|
3387
|
+
}
|
|
3388
|
+
const stat = fs11.statSync(filePath);
|
|
3389
|
+
entries.push(`${filePath}:${stat.size}:${Math.trunc(stat.mtimeMs)}`);
|
|
3390
|
+
};
|
|
3391
|
+
if (this.options.features.exposeContext.enabled && (this.majorVersion === 2 || this.majorVersion === 3)) {
|
|
3392
|
+
if (this.majorVersion === 2) {
|
|
3393
|
+
pushSnapshot(path11.resolve(this.packageInfo.rootPath, "lib/jit/processTailwindFeatures.js"));
|
|
3394
|
+
pushSnapshot(path11.resolve(this.packageInfo.rootPath, "lib/jit/index.js"));
|
|
3395
|
+
} else {
|
|
3396
|
+
pushSnapshot(path11.resolve(this.packageInfo.rootPath, "lib/processTailwindFeatures.js"));
|
|
3397
|
+
const pluginPath = ["lib/plugin.js", "lib/index.js"].map((file) => path11.resolve(this.packageInfo.rootPath, file)).find((file) => fs11.pathExistsSync(file));
|
|
3398
|
+
if (pluginPath) {
|
|
3399
|
+
pushSnapshot(pluginPath);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3261
3402
|
}
|
|
3403
|
+
if (this.options.features.extendLengthUnits?.enabled) {
|
|
3404
|
+
if (this.majorVersion === 3) {
|
|
3405
|
+
const target = this.options.features.extendLengthUnits.lengthUnitsFilePath ?? "lib/util/dataTypes.js";
|
|
3406
|
+
pushSnapshot(path11.resolve(this.packageInfo.rootPath, target));
|
|
3407
|
+
} else if (this.majorVersion === 4) {
|
|
3408
|
+
const distDir = path11.resolve(this.packageInfo.rootPath, "dist");
|
|
3409
|
+
if (fs11.pathExistsSync(distDir)) {
|
|
3410
|
+
const chunkNames = fs11.readdirSync(distDir).filter((entry) => entry.endsWith(".js") || entry.endsWith(".mjs")).sort();
|
|
3411
|
+
for (const chunkName of chunkNames) {
|
|
3412
|
+
pushSnapshot(path11.join(distDir, chunkName));
|
|
3413
|
+
}
|
|
3414
|
+
} else {
|
|
3415
|
+
entries.push(`${distDir}:missing`);
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
return entries.join("|");
|
|
3262
3420
|
}
|
|
3263
3421
|
async collectClassSet() {
|
|
3264
3422
|
if (this.majorVersion === 4) {
|
|
@@ -3288,13 +3446,13 @@ var TailwindcssPatcher = class {
|
|
|
3288
3446
|
for (const value of existing) {
|
|
3289
3447
|
set.add(value);
|
|
3290
3448
|
}
|
|
3291
|
-
const writeTarget = await this.cacheStore.write(set);
|
|
3449
|
+
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : await this.cacheStore.write(set);
|
|
3292
3450
|
if (writeTarget) {
|
|
3293
3451
|
logger_default.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
3294
3452
|
}
|
|
3295
3453
|
} else {
|
|
3296
3454
|
if (set.size > 0) {
|
|
3297
|
-
const writeTarget = await this.cacheStore.write(set);
|
|
3455
|
+
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : await this.cacheStore.write(set);
|
|
3298
3456
|
if (writeTarget) {
|
|
3299
3457
|
logger_default.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
3300
3458
|
}
|
|
@@ -3314,13 +3472,13 @@ var TailwindcssPatcher = class {
|
|
|
3314
3472
|
for (const value of existing) {
|
|
3315
3473
|
set.add(value);
|
|
3316
3474
|
}
|
|
3317
|
-
const writeTarget = this.cacheStore.writeSync(set);
|
|
3475
|
+
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : this.cacheStore.writeSync(set);
|
|
3318
3476
|
if (writeTarget) {
|
|
3319
3477
|
logger_default.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
3320
3478
|
}
|
|
3321
3479
|
} else {
|
|
3322
3480
|
if (set.size > 0) {
|
|
3323
|
-
const writeTarget = this.cacheStore.writeSync(set);
|
|
3481
|
+
const writeTarget = this.areSetsEqual(existing, set) ? void 0 : this.cacheStore.writeSync(set);
|
|
3324
3482
|
if (writeTarget) {
|
|
3325
3483
|
logger_default.debug(`[cache] stored ${set.size} classes -> ${writeTarget}`);
|
|
3326
3484
|
}
|
|
@@ -3330,6 +3488,17 @@ var TailwindcssPatcher = class {
|
|
|
3330
3488
|
}
|
|
3331
3489
|
return set;
|
|
3332
3490
|
}
|
|
3491
|
+
areSetsEqual(a, b) {
|
|
3492
|
+
if (a.size !== b.size) {
|
|
3493
|
+
return false;
|
|
3494
|
+
}
|
|
3495
|
+
for (const value of a) {
|
|
3496
|
+
if (!b.has(value)) {
|
|
3497
|
+
return false;
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
return true;
|
|
3501
|
+
}
|
|
3333
3502
|
async getClassSet() {
|
|
3334
3503
|
await this.runTailwindBuildIfNeeded();
|
|
3335
3504
|
const set = await this.collectClassSet();
|
|
@@ -3359,12 +3528,12 @@ var TailwindcssPatcher = class {
|
|
|
3359
3528
|
return result;
|
|
3360
3529
|
}
|
|
3361
3530
|
const target = path11.resolve(this.options.output.file);
|
|
3362
|
-
await
|
|
3531
|
+
await fs11.ensureDir(path11.dirname(target));
|
|
3363
3532
|
if (this.options.output.format === "json") {
|
|
3364
3533
|
const spaces = typeof this.options.output.pretty === "number" ? this.options.output.pretty : void 0;
|
|
3365
|
-
await
|
|
3534
|
+
await fs11.writeJSON(target, classList, { spaces });
|
|
3366
3535
|
} else {
|
|
3367
|
-
await
|
|
3536
|
+
await fs11.writeFile(target, `${classList.join("\n")}
|
|
3368
3537
|
`, "utf8");
|
|
3369
3538
|
}
|
|
3370
3539
|
logger_default.success(`Tailwind CSS class list saved to ${target.replace(process6.cwd(), ".")}`);
|
|
@@ -3483,7 +3652,7 @@ function buildMigrationReport(state, context) {
|
|
|
3483
3652
|
}
|
|
3484
3653
|
|
|
3485
3654
|
// src/commands/migration-file-executor.ts
|
|
3486
|
-
import
|
|
3655
|
+
import fs13 from "fs-extra";
|
|
3487
3656
|
import path13 from "pathe";
|
|
3488
3657
|
|
|
3489
3658
|
// src/commands/migration-source.ts
|
|
@@ -3752,7 +3921,7 @@ function migrateConfigSource(source) {
|
|
|
3752
3921
|
}
|
|
3753
3922
|
|
|
3754
3923
|
// src/commands/migration-target-files.ts
|
|
3755
|
-
import
|
|
3924
|
+
import fs12 from "fs-extra";
|
|
3756
3925
|
import path12 from "pathe";
|
|
3757
3926
|
var DEFAULT_CONFIG_FILENAMES = [
|
|
3758
3927
|
"tailwindcss-patch.config.ts",
|
|
@@ -3796,7 +3965,7 @@ async function collectWorkspaceConfigFiles(cwd, maxDepth) {
|
|
|
3796
3965
|
const { dir, depth } = current;
|
|
3797
3966
|
let entries;
|
|
3798
3967
|
try {
|
|
3799
|
-
entries = await
|
|
3968
|
+
entries = await fs12.readdir(dir, { withFileTypes: true });
|
|
3800
3969
|
} catch {
|
|
3801
3970
|
continue;
|
|
3802
3971
|
}
|
|
@@ -3893,7 +4062,7 @@ async function rollbackWrittenEntries(wroteEntries) {
|
|
|
3893
4062
|
let rollbackCount = 0;
|
|
3894
4063
|
for (const written of [...wroteEntries].reverse()) {
|
|
3895
4064
|
try {
|
|
3896
|
-
await
|
|
4065
|
+
await fs13.writeFile(written.file, written.source, "utf8");
|
|
3897
4066
|
written.entry.written = false;
|
|
3898
4067
|
written.entry.rolledBack = true;
|
|
3899
4068
|
rollbackCount += 1;
|
|
@@ -3911,7 +4080,7 @@ async function executeMigrationFile(options) {
|
|
|
3911
4080
|
backupDirectory,
|
|
3912
4081
|
wroteEntries
|
|
3913
4082
|
} = options;
|
|
3914
|
-
const exists = await
|
|
4083
|
+
const exists = await fs13.pathExists(file);
|
|
3915
4084
|
if (!exists) {
|
|
3916
4085
|
return {
|
|
3917
4086
|
missing: true,
|
|
@@ -3920,7 +4089,7 @@ async function executeMigrationFile(options) {
|
|
|
3920
4089
|
backupWritten: false
|
|
3921
4090
|
};
|
|
3922
4091
|
}
|
|
3923
|
-
const source = await
|
|
4092
|
+
const source = await fs13.readFile(file, "utf8");
|
|
3924
4093
|
const migrated = migrateConfigSource(source);
|
|
3925
4094
|
const entry = {
|
|
3926
4095
|
file,
|
|
@@ -3943,12 +4112,12 @@ async function executeMigrationFile(options) {
|
|
|
3943
4112
|
if (backupDirectory) {
|
|
3944
4113
|
const backupRelativePath = resolveBackupRelativePath(cwd, file);
|
|
3945
4114
|
const backupFile = path13.resolve(backupDirectory, backupRelativePath);
|
|
3946
|
-
await
|
|
3947
|
-
await
|
|
4115
|
+
await fs13.ensureDir(path13.dirname(backupFile));
|
|
4116
|
+
await fs13.writeFile(backupFile, source, "utf8");
|
|
3948
4117
|
entry.backupFile = backupFile;
|
|
3949
4118
|
backupWritten = true;
|
|
3950
4119
|
}
|
|
3951
|
-
await
|
|
4120
|
+
await fs13.writeFile(file, migrated.code, "utf8");
|
|
3952
4121
|
entry.written = true;
|
|
3953
4122
|
wroteEntries.push({ file, source, entry });
|
|
3954
4123
|
return {
|
|
@@ -3981,15 +4150,15 @@ async function restoreConfigEntries(entries, dryRun) {
|
|
|
3981
4150
|
continue;
|
|
3982
4151
|
}
|
|
3983
4152
|
restorableEntries += 1;
|
|
3984
|
-
const backupExists = await
|
|
4153
|
+
const backupExists = await fs13.pathExists(backupFile);
|
|
3985
4154
|
if (!backupExists) {
|
|
3986
4155
|
missingBackups += 1;
|
|
3987
4156
|
continue;
|
|
3988
4157
|
}
|
|
3989
4158
|
if (!dryRun) {
|
|
3990
|
-
const backupContent = await
|
|
3991
|
-
await
|
|
3992
|
-
await
|
|
4159
|
+
const backupContent = await fs13.readFile(backupFile, "utf8");
|
|
4160
|
+
await fs13.ensureDir(path13.dirname(targetFile));
|
|
4161
|
+
await fs13.writeFile(targetFile, backupContent, "utf8");
|
|
3993
4162
|
}
|
|
3994
4163
|
restoredFiles += 1;
|
|
3995
4164
|
restored.push(targetFile);
|
|
@@ -4005,9 +4174,9 @@ async function restoreConfigEntries(entries, dryRun) {
|
|
|
4005
4174
|
}
|
|
4006
4175
|
|
|
4007
4176
|
// src/commands/migration-report-loader.ts
|
|
4008
|
-
import
|
|
4177
|
+
import fs14 from "fs-extra";
|
|
4009
4178
|
async function loadMigrationReportForRestore(reportFile) {
|
|
4010
|
-
const report = await
|
|
4179
|
+
const report = await fs14.readJSON(reportFile);
|
|
4011
4180
|
assertMigrationReportCompatibility(report, reportFile);
|
|
4012
4181
|
return {
|
|
4013
4182
|
...report.reportKind === void 0 ? {} : { reportKind: report.reportKind },
|
|
@@ -4391,7 +4560,7 @@ function runWithCommandHandler(cli, command, commandName, args, handler, default
|
|
|
4391
4560
|
|
|
4392
4561
|
// src/commands/basic-handlers.ts
|
|
4393
4562
|
import process9 from "process";
|
|
4394
|
-
import
|
|
4563
|
+
import fs15 from "fs-extra";
|
|
4395
4564
|
import path16 from "pathe";
|
|
4396
4565
|
var DEFAULT_CONFIG_NAME = "tailwindcss-mangle";
|
|
4397
4566
|
async function installCommandDefaultHandler(_ctx) {
|
|
@@ -4447,14 +4616,14 @@ async function tokensCommandDefaultHandler(ctx) {
|
|
|
4447
4616
|
const resolveGrouped = () => grouped ?? buildGrouped();
|
|
4448
4617
|
if (shouldWrite) {
|
|
4449
4618
|
const target = path16.resolve(targetFile);
|
|
4450
|
-
await
|
|
4619
|
+
await fs15.ensureDir(path16.dirname(target));
|
|
4451
4620
|
if (format === "json") {
|
|
4452
|
-
await
|
|
4621
|
+
await fs15.writeJSON(target, report, { spaces: 2 });
|
|
4453
4622
|
} else if (format === "grouped-json") {
|
|
4454
|
-
await
|
|
4623
|
+
await fs15.writeJSON(target, resolveGrouped(), { spaces: 2 });
|
|
4455
4624
|
} else {
|
|
4456
4625
|
const lines = report.entries.map(formatTokenLine);
|
|
4457
|
-
await
|
|
4626
|
+
await fs15.writeFile(target, `${lines.join("\n")}
|
|
4458
4627
|
`, "utf8");
|
|
4459
4628
|
}
|
|
4460
4629
|
logger_default.success(`Collected ${report.entries.length} tokens (${format}) \u2192 ${target.replace(process9.cwd(), ".")}`);
|
|
@@ -4561,7 +4730,7 @@ function resolveValidateCommandArgs(args) {
|
|
|
4561
4730
|
|
|
4562
4731
|
// src/commands/migration-output.ts
|
|
4563
4732
|
import process10 from "process";
|
|
4564
|
-
import
|
|
4733
|
+
import fs16 from "fs-extra";
|
|
4565
4734
|
import path17 from "pathe";
|
|
4566
4735
|
function formatPathForLog(file) {
|
|
4567
4736
|
return file.replace(process10.cwd(), ".");
|
|
@@ -4571,8 +4740,8 @@ function createMigrationCheckFailureError(changedFiles) {
|
|
|
4571
4740
|
}
|
|
4572
4741
|
async function writeMigrationReportFile(cwd, reportFile, report) {
|
|
4573
4742
|
const reportPath = path17.resolve(cwd, reportFile);
|
|
4574
|
-
await
|
|
4575
|
-
await
|
|
4743
|
+
await fs16.ensureDir(path17.dirname(reportPath));
|
|
4744
|
+
await fs16.writeJSON(reportPath, report, { spaces: 2 });
|
|
4576
4745
|
logger_default.info(`Migration report written: ${formatPathForLog(reportPath)}`);
|
|
4577
4746
|
}
|
|
4578
4747
|
function logMigrationReportAsJson(report) {
|