vite-awesome-svg-loader
Version:
A universal Vite SVG loader. Imports SVGs as source code, base64 and data URI. Preserves stroke width. Replaces colors with currentColor or custom colors. Creates SVG sprites. Optimizes SVGs.
1 lines • 37.4 kB
Source Map (JSON)
{"version":3,"file":"index-DTOezOEK.cjs","sources":["../../../loader/src/internal/misc.ts","../../../loader/src/internal/preserveLineWidth.ts","../../../loader/src/internal/const.ts","../../../loader/src/internal/replaceColorsCss.ts","../../../loader/src/internal/replaceColorsSvg.ts","../../../loader/src/loader.ts"],"sourcesContent":["import { XastChild } from \"svgo/lib/types\";\n// TODO: Update import when SVGO 4.x.x will be released, it should export utility functions\n// @ts-expect-error\nimport { matches as matchesSelectorRaw } from \"svgo/lib/xast.js\";\nimport type { ColorMapPerFiles, CssSelectors, FileMatcherFnContext, FileMatchers } from \"../types\";\nimport path from \"path\";\nimport { ResolvedColorReplacements } from \"./types\";\nimport { toArray } from \"common-utils\";\n\nexport function normalizeBaseDir(dir: string) {\n dir = dir.replaceAll(\"\\\\\", \"/\");\n\n if (dir.endsWith(\"/\")) {\n dir = dir.substring(0, dir.length - 1);\n }\n\n return dir;\n}\n\nexport function toBase64(str: string) {\n const binString = String.fromCodePoint(...new TextEncoder().encode(str));\n return btoa(binString);\n}\n\n/**\n * Escapes backticks in a string with a slash: \\\\\\`\n */\nexport function escapeBackticks(str: string) {\n return str.replaceAll(\"`\", \"\\\\`\");\n}\n\nexport interface MatchesQueryOrListOptions extends MatchesPathOptions {\n queryValue?: string;\n}\n\n/**\n * Checks if given relative path or filename matches query value or a list of matchers\n * @param relPathWithSlash Relative path with leading slash\n * @param queryValue Value of a query param to check. If value exists and not equals to `false` (case-insensitive),\n * function returns `true`.\n * @param matchers List of matchers to check path and filename against\n */\nexport function matchesQueryOrPath(options: MatchesQueryOrListOptions) {\n return matchesQuery(options.queryValue) || matchesPath(options);\n}\n\nexport function matchesQuery(queryValue: string | undefined) {\n return !!queryValue && queryValue.toLowerCase() !== \"false\";\n}\n\nexport interface MatchesPathOptions extends FileMatcherFnContext {\n matchers: FileMatchers;\n}\n\n/**\n * Checks if given relative path or filename matches a list of matchers\n * @param relPathWithSlash Relative path with leading slash\n * @param matchers List of matchers to check path and filename against\n */\nexport function matchesPath(options: MatchesPathOptions) {\n const filename = path.basename(options.relativePath);\n const toMatch = [filename, options.relativePath];\n const matchers = toArray(options.matchers);\n\n if (!matchers.length) {\n return false;\n }\n\n return matchers.some((matcher) => {\n switch (typeof matcher) {\n case \"string\":\n return toMatch.some((v) => v === matcher);\n\n case \"function\":\n return matcher({ fullPath: options.fullPath, relativePath: options.relativePath });\n }\n\n return toMatch.some((v) => matcher.test(v));\n });\n}\n\n/**\n * Normalizes selector string. For now, removes unneccesarry whitespace.\n */\nfunction normalizeSelector(selector: string) {\n return selector.replaceAll(/\\s+/g, \" \").trim();\n}\n\nexport interface SelectorsToListOptions extends FileMatcherFnContext {\n selectors: CssSelectors;\n}\n\n/**\n * Converts CSS selectors to a list and normalizes each selector\n * @param relPathWithSlash Relative path with leading slash\n * @param selectors Selectors\n */\nexport function selectorsToList(options: SelectorsToListOptions) {\n const selectors = toArray(options.selectors);\n const resolvedSelectors: string[] = [];\n\n for (const selector of selectors) {\n if (typeof selector === \"string\") {\n resolvedSelectors.push(normalizeSelector(selector));\n continue;\n }\n\n if (matchesPath({ ...options, matchers: selector.files })) {\n for (const selectorStr of selector.selectors) {\n resolvedSelectors.push(normalizeSelector(selectorStr));\n }\n }\n }\n\n return resolvedSelectors;\n}\n\n/**\n * Checks if a node matches a selector\n */\nexport const matchesSelector: (node: XastChild, selector: string) => boolean = matchesSelectorRaw;\n\n/**\n * Checks if a node matches at least one CSS selector in a list\n */\nexport function matchesSelectors(node: XastChild, selectors: string[]) {\n for (const selector of selectors) {\n if (matchesSelector(node, selector)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function replaceColor(color: string | undefined, replacements: ResolvedColorReplacements) {\n if (!color) {\n return replacements.default || \"\";\n }\n\n return replacements.replacements[color.toLowerCase()] || replacements.default || color;\n}\n\nexport function isColorMapPerFiles(value: unknown): value is ColorMapPerFiles {\n return Array.isArray((value as any)?.files);\n}\n","import { XastElement } from \"svgo/lib/types\";\n\nconst TAGS_TO_PRESERVE_LINE_WIDTH_OF: Record<string, true> = {\n circle: true,\n ellipse: true,\n foreignObject: true,\n image: true,\n line: true,\n path: true,\n polygon: true,\n polyline: true,\n rect: true,\n text: true,\n textPath: true,\n tspan: true,\n use: true,\n};\n\nexport function preserveLineWidth(node: XastElement, path: string) {\n if (!TAGS_TO_PRESERVE_LINE_WIDTH_OF[node.name]) {\n return;\n }\n\n const vectorEffectAttr = node.attributes[\"vector-effect\"];\n\n if (vectorEffectAttr && vectorEffectAttr !== \"non-scaling-stroke\") {\n console.warn(\n `\"${path}\": Element \"${node.name}\" already contains \"vector-effect\" property. Please remove it, ` +\n \"so it can scale correctly. This element will not be transformed.\",\n );\n } else {\n node.attributes[\"vector-effect\"] = \"non-scaling-stroke\";\n }\n}\n","import { ImportType } from \"../types\";\n\nexport const COLOR_ATTRS_TO_REPLACE: Record<string, true> = {\n \"fill\": true,\n \"stroke\": true,\n \"stop-color\": true,\n};\n\nexport const IGNORE_COLORS: Record<string, true> = {\n none: true,\n transparent: true,\n currentColor: true,\n};\n\nexport const IMPORT_TYPES: ImportType[] = [\"url\", \"source\", \"source-data-uri\", \"base64\", \"base64-data-uri\"];\n","import * as csstree from \"css-tree\";\nimport { XastChild } from \"svgo/lib/types\";\nimport { COLOR_ATTRS_TO_REPLACE, IGNORE_COLORS } from \"./const\";\nimport { matchesSelector, replaceColor } from \"./misc\";\nimport { ResolvedColorReplacements } from \"./types\";\n\nexport function replaceColorsCss(\n css: any,\n replacements: ResolvedColorReplacements,\n nodesWithOrigColors: XastChild[],\n isInline = false,\n) {\n if (!css || typeof css !== \"string\") {\n return \"\";\n }\n\n let context = \"stylesheet\";\n\n if (isInline) {\n css = `{${css}}`;\n context = \"block\";\n }\n\n // For original colors preservation\n const shouldPreserveColors = !isInline && nodesWithOrigColors.length;\n let origColorSelectors: string[] = [];\n let currentColorSelectors: string[] = [];\n let didSplitSelectors = false;\n\n const ast = csstree.parse(css, { context });\n\n csstree.walk(ast, {\n // Ignore because of broken types in csstree:\n // @ts-ignore\n visit: shouldPreserveColors ? undefined : \"Declaration\",\n\n enter: function (node) {\n // Skip rules with original colors\n if ((node as any).__SKIP_SVG_LOADER__ || (this.rule as any)?.__SKIP_SVG_LOADER__) {\n return;\n }\n\n // If need to preserve colors\n if (shouldPreserveColors) {\n // Reset lists if it's new rule\n if (node.type === \"SelectorList\") {\n origColorSelectors = [];\n currentColorSelectors = [];\n didSplitSelectors = false;\n return;\n }\n\n // Classify selectors\n if (node.type === \"Selector\") {\n const selector = csstree.generate(node);\n let isOrigColor = false;\n\n for (const svgNode of nodesWithOrigColors) {\n if (matchesSelector(svgNode, selector)) {\n isOrigColor = true;\n (node as any).__ORIG_COLOR__ = true;\n break;\n }\n }\n\n (isOrigColor ? origColorSelectors : currentColorSelectors).push(selector);\n return;\n }\n }\n\n // Check if there's a declaration with a color, and if this color should be replaced\n\n if (node.type !== \"Declaration\" || !COLOR_ATTRS_TO_REPLACE[node.property]) {\n return;\n }\n\n // @ts-ignore\n const identifier = node.value?.children?.first;\n const color = identifier?.value || identifier?.name;\n\n if (!color || IGNORE_COLORS[color]) {\n return;\n }\n\n // Create new rule with original colors and remove such selectors from the current rule.\n // We'll replace color in the current rule.\n\n if (shouldPreserveColors && !didSplitSelectors && this.rule?.prelude.type === \"SelectorList\") {\n // Split selectors and create a new rule\n\n const origColorsRule = csstree.clone(this.rule) as csstree.Rule;\n (origColorsRule as any).__SKIP_SVG_LOADER__ = true;\n const origColorsSelectors = new csstree.List<csstree.CssNode>();\n const selectors = this.rule.prelude.children;\n\n selectors.forEach((node, listItem) => {\n if ((node as any).__ORIG_COLOR__) {\n selectors.remove(listItem);\n origColorsSelectors.push(node);\n }\n });\n\n (origColorsRule.prelude as csstree.SelectorList).children = origColorsSelectors;\n\n // Parent can be either at-rule or stylesheet\n const parent = this.atrule?.block?.children || this.stylesheet?.children;\n\n // Find current rule in parent. FFS, why there's no indices?\n let insertBefore: csstree.ListItem<csstree.CssNode> | undefined;\n\n parent?.some((rule, listItem) => {\n if (rule === this.rule) {\n insertBefore = listItem;\n return true;\n }\n\n return false;\n });\n\n if (insertBefore) {\n parent?.insertData(origColorsRule, insertBefore);\n } else {\n parent?.push(origColorsRule);\n }\n\n didSplitSelectors = true;\n }\n\n // Replace color\n\n node.value = csstree.parse(replaceColor(csstree.generate(node.value), replacements), {\n context: \"value\",\n }) as csstree.Value;\n } satisfies csstree.EnterOrLeaveFn,\n });\n\n return csstree.generate(ast);\n}\n","import { XastChild, XastElement } from \"svgo/lib/types\";\nimport { IGNORE_COLORS, COLOR_ATTRS_TO_REPLACE } from \"./const\";\nimport { replaceColor } from \"./misc\";\nimport { ResolvedColorReplacements } from \"./types\";\nimport { replaceColorsCss } from \"./replaceColorsCss\";\n\n/**\n * A list of elements which should have `fill` property to be forcefully replaced.\n *\n * Fill color of these elements defaults to black, if `fill` property is not defined.\n */\nconst ELEMENTS_TO_FORCE_SET_FILL_OF: Record<string, true> = {\n circle: true,\n ellipse: true,\n path: true,\n polygon: true,\n polyline: true,\n rect: true,\n text: true,\n textPath: true,\n tref: true,\n tspan: true,\n};\n\nconst COLOR_ATTRS_TO_REPLACE_SVG = { ...COLOR_ATTRS_TO_REPLACE };\ndelete COLOR_ATTRS_TO_REPLACE_SVG.fill; // Fill is handled separately\n\n/**\n * Sets current color of a given node\n * @returns New value of `isFillSetOnRoot`.\n */\nexport function replaceColorsSvg(\n node: XastElement,\n isFillSetOnRoot: boolean,\n replacements: ResolvedColorReplacements,\n nodesWithOrigColors: XastChild[],\n) {\n if (node.name === \"style\") {\n const firstChild: any = node.children[0];\n const newCss = replaceColorsCss(firstChild?.value, replacements, nodesWithOrigColors, false);\n\n if (newCss) {\n firstChild.value = newCss;\n }\n } else {\n const newCss = replaceColorsCss(node.attributes.style, replacements, nodesWithOrigColors, true);\n\n if (newCss) {\n node.attributes.style = newCss;\n }\n }\n\n const isRoot = node.name === \"svg\";\n const fillAttr = node.attributes.fill;\n\n // If fill is set on <svg>, it'll override default fill of all underlying elements. If that's the case,\n // we shouldn't forcefully replace fill color of elements that are filled by default but don't have a color set\n if (isRoot && fillAttr) {\n isFillSetOnRoot = true;\n }\n\n // Forcefully replace fill color unless we have what's described above\n if (\n ((isRoot && isFillSetOnRoot) || (!isRoot && !isFillSetOnRoot && ELEMENTS_TO_FORCE_SET_FILL_OF[node.name])) &&\n !IGNORE_COLORS[fillAttr]\n ) {\n node.attributes.fill = replaceColor(fillAttr, replacements);\n }\n\n // Replace rest of the colors\n for (const attr in COLOR_ATTRS_TO_REPLACE_SVG) {\n const attrsColor = node.attributes[attr];\n\n if (attrsColor && !IGNORE_COLORS[attrsColor]) {\n node.attributes[attr] = replaceColor(attrsColor, replacements);\n }\n }\n\n return isFillSetOnRoot;\n}\n","import type { ConfigEnv, Plugin, UserConfig } from \"vite\";\nimport { readFile, rm, writeFile } from \"node:fs/promises\";\nimport path from \"path\";\nimport { optimize } from \"svgo\";\nimport { XastChild } from \"svgo/lib/types\";\n// TODO: Update import when SVGO 4.x.x will be released, it should export utility functions\n// @ts-expect-error\nimport { querySelectorAll } from \"svgo/lib/xast.js\";\nimport MurmurHash3 from \"imurmurhash\";\nimport {\n ColorMap,\n ColorMapPerFiles,\n CssSelectors,\n FileMatcher,\n FileMatcherFnContext,\n FileMatchers,\n SvgLoaderOptions,\n} from \"./types\";\nimport {\n escapeBackticks,\n isColorMapPerFiles,\n matchesPath,\n matchesQuery,\n matchesQueryOrPath as matchesQueryOrPathRaw,\n matchesSelectors,\n normalizeBaseDir,\n selectorsToList as selectorsToListRaw,\n toBase64,\n} from \"./internal/misc\";\nimport { preserveLineWidth } from \"./internal/preserveLineWidth\";\nimport { ResolvedColorReplacements } from \"./internal/types\";\nimport { replaceColorsSvg } from \"./internal/replaceColorsSvg\";\nimport { IMPORT_TYPES } from \"./internal/const\";\nimport { toArray } from \"common-utils\";\n\n/**\n * `vite-awesome-svg-loader` plugin.\n *\n * See {@link SvgLoaderOptions} for advanced configuration.\n *\n * @param options Plugin options. It is recommended to provide options instead of using queries in imports.\n */\nexport function viteAwesomeSvgLoader(options: SvgLoaderOptions = {}): Plugin {\n const { urlImportsInLibraryMode = \"source-data-uri\" } = options;\n let tempDir = options.tempDir || \".temp\";\n\n if (tempDir.startsWith(\"/\") || tempDir.startsWith(\"./\") || tempDir.indexOf(\":/\") !== -1) {\n throw new Error(\n '\"tempDir\" option must be in format \"path/to/temp/dir\",' +\n 'i.e. it shouldn\\'t be an absolute path, or start with \"./\".' +\n \"It'll be resolved to the project's root by the plugin.\",\n );\n }\n\n if (tempDir.endsWith(\"/\")) {\n tempDir = tempDir.substring(0, tempDir.length - 1);\n }\n\n tempDir = \"/\" + tempDir;\n\n let isBuildMode = false;\n let isLibraryMode = false;\n let root = \"\";\n let base = \"\";\n\n const replaceColorsList = toArray(options.replaceColorsList || []);\n\n // Prioritize replacements like so:\n const replacementsWithFiles: ColorMapPerFiles[] = []; // ColorMapPerFiles\n const filesWithCurrentColor: ColorMapPerFiles[] = []; // FileMatcher\n\n // ColorMap\n const allFilesReplacements: ColorMapPerFiles = {\n files: /.*/,\n replacements: {},\n default: \"\",\n };\n\n let hasAllFilesReplacements = false;\n\n const isFileMatcher = (value: Exclude<(typeof replaceColorsList)[0], ColorMapPerFiles>): value is FileMatcher => {\n switch (typeof value) {\n case \"string\":\n case \"function\":\n return true;\n }\n\n return value instanceof RegExp;\n };\n\n // Normalize list and apply prioritization\n for (const replacements of replaceColorsList) {\n if (isColorMapPerFiles(replacements)) {\n replacementsWithFiles.push(replacements);\n continue;\n }\n\n if (isFileMatcher(replacements)) {\n filesWithCurrentColor.push({\n files: replacements,\n replacements: {},\n default: \"currentColor\",\n });\n\n continue;\n }\n\n for (const color in replacements) {\n hasAllFilesReplacements = true;\n allFilesReplacements.replacements[color] = (replacements as ColorMap)[color];\n }\n }\n\n const replaceColorsListNormalized: ColorMapPerFiles[] = [...replacementsWithFiles, ...filesWithCurrentColor];\n\n if (hasAllFilesReplacements) {\n replaceColorsListNormalized.push(allFilesReplacements);\n }\n\n return {\n name: \"vite-awesome-svg-loader\",\n enforce: \"pre\",\n\n config(config: UserConfig, { command }: ConfigEnv) {\n isBuildMode = command === \"build\";\n },\n\n configResolved(config) {\n isLibraryMode = !!config.build.lib;\n root = normalizeBaseDir(config.root);\n base = normalizeBaseDir(config.base);\n },\n\n configureServer(server) {\n server.httpServer?.on(\"close\", async () => {\n if (!isBuildMode) {\n await rm(root + tempDir, { force: true, recursive: true });\n }\n });\n },\n\n async load(id: string) {\n const ext = \".svg\";\n const indexOfSvg = id.indexOf(ext);\n\n if (indexOfSvg === -1) {\n return null;\n }\n\n // Normalize file path. Vite seems to always pass absolute path, but let's be safe.\n\n let relPathWithSlash = id.substring(0, indexOfSvg + ext.length).replaceAll(\"\\\\\", \"/\");\n\n if (relPathWithSlash.startsWith(root)) {\n relPathWithSlash = relPathWithSlash.substring(root.length);\n }\n\n if (!relPathWithSlash.startsWith(\"/\")) {\n relPathWithSlash = \"/\" + relPathWithSlash;\n }\n\n // Parse query\n\n const queryStr = id.split(\"?\", 2)[1] || \"\";\n const queryKVPairs = queryStr.split(\"&\");\n\n const query: Record<string, string | undefined> = {};\n\n for (const pair of queryKVPairs) {\n const [key, value] = pair.split(\"=\");\n query[key.toLowerCase()] = value || \"1\";\n }\n\n // Create wrappers around matching functions for convenience\n\n const fileMatcherCtx: FileMatcherFnContext = {\n fullPath: (root.endsWith(\"/\") ? root.substring(root.length) : root) + relPathWithSlash,\n relativePath: relPathWithSlash,\n };\n\n const matchesQueryOrPath = (options: { matchers: FileMatchers | undefined; param?: string }) =>\n matchesQueryOrPathRaw({\n ...fileMatcherCtx,\n matchers: options.matchers || [],\n queryValue: query[options.param!],\n });\n\n const selectorsToList = (selectors: CssSelectors | undefined) =>\n selectorsToListRaw({ ...fileMatcherCtx, selectors: selectors || [] });\n\n // Skip specified files\n\n if (matchesQueryOrPath({ param: \"skip-awesome-svg-loader\", matchers: options.skipFilesList })) {\n return null;\n }\n\n // Resolve transform configuration\n\n const shouldSkipTransforms = matchesQueryOrPath({\n param: \"skip-transforms\",\n matchers: options.skipTransformsList,\n });\n\n const shouldPreserveLineWidth =\n !shouldSkipTransforms &&\n matchesQueryOrPath({ param: \"preserve-line-width\", matchers: options.preserveLineWidthList }) &&\n !matchesQueryOrPath({ matchers: options.skipPreserveLineWidthList });\n\n const skipPreserveLineWidthSelectors = shouldPreserveLineWidth\n ? selectorsToList(options.skipPreserveLineWidthSelectors)\n : [];\n\n let shouldReplaceColors = false;\n\n const colorReplacements: ResolvedColorReplacements = {\n replacements: {},\n // @ts-ignore\n default: undefined,\n };\n\n if (!shouldSkipTransforms && !matchesQueryOrPath({ matchers: options.skipReplaceColorsList })) {\n if (matchesQuery(query[\"set-current-color\"])) {\n colorReplacements.default = \"currentColor\";\n shouldReplaceColors = true;\n } else {\n for (const entry of replaceColorsListNormalized) {\n if (!matchesPath({ ...fileMatcherCtx, matchers: entry.files })) {\n continue;\n }\n\n shouldReplaceColors = true;\n\n if (colorReplacements.default === undefined && entry.default !== undefined) {\n colorReplacements.default = entry.default;\n }\n\n for (const color in entry.replacements) {\n colorReplacements.replacements[color] ||= entry.replacements[color];\n }\n }\n }\n }\n\n colorReplacements.default ??= \"currentColor\";\n\n const skipReplaceColorsSelectors = shouldReplaceColors ? selectorsToList(options.skipReplaceColorsSelectors) : [];\n const skipTransformsSelectors = shouldSkipTransforms ? [] : selectorsToList(options.skipTransformsSelectors);\n\n // Hash path and transform parameters to guarantee same output for duplicate parameters. All parameters\n // should be accounted and normalized (i.e. stuff like whitespace in CSS selectors shouldn't affect output).\n //\n // We don't want to cache the results because there may be a lot of files. Limited cache also won't help because\n // duplicates won't likely follow one after another.\n\n const hashParts: string[] = [relPathWithSlash];\n\n for (const arr of [skipPreserveLineWidthSelectors, skipReplaceColorsSelectors, skipTransformsSelectors]) {\n hashParts.push(arr.join(\",\"));\n }\n\n for (const param of [shouldSkipTransforms, shouldPreserveLineWidth, shouldReplaceColors]) {\n hashParts.push(param ? \"1\" : \"0\");\n }\n\n if (shouldReplaceColors) {\n hashParts.push(JSON.stringify(colorReplacements));\n }\n\n const hash = new MurmurHash3(hashParts.join(\"__\")).result();\n\n // Create unique asset file name\n const fileNameNoExt = path.basename(relPathWithSlash).split(\".\")[0];\n const assetFileNameNoExt = `${fileNameNoExt}-${hash}`;\n const assetFileName = assetFileNameNoExt + \".svg\";\n const assetRelPath = path.dirname(relPathWithSlash) + \"/\" + assetFileName;\n\n const fullPath = root + relPathWithSlash;\n let code = (await readFile(fullPath)).toString();\n let isFillSetOnRoot = false;\n\n const nodesWithOrigColors: XastChild[] = [];\n const classesAndIdsPrefix = assetFileNameNoExt + \"__\";\n let didTransform = false; // Detect additional passes, see multipass option\n\n code = optimize(code, {\n multipass: true,\n plugins: [\n {\n name: \"prefixIds\",\n params: {\n prefixIds: true,\n prefixClassNames: true,\n prefix: classesAndIdsPrefix,\n delim: \"\",\n },\n },\n {\n name: \"awesome-svg-loader\",\n fn: () => {\n if (didTransform) {\n return null;\n }\n\n didTransform = true;\n\n return {\n root: {\n enter: (root) => {\n for (const selectors of [skipReplaceColorsSelectors, skipTransformsSelectors]) {\n for (const selector of selectors) {\n nodesWithOrigColors.push(...querySelectorAll(root, selector));\n }\n }\n },\n },\n element: {\n enter: (node) => {\n if (matchesSelectors(node, skipTransformsSelectors)) {\n return;\n }\n\n if (shouldPreserveLineWidth && !matchesSelectors(node, skipPreserveLineWidthSelectors)) {\n preserveLineWidth(node, fullPath);\n }\n\n if (shouldReplaceColors && !matchesSelectors(node, skipReplaceColorsSelectors)) {\n isFillSetOnRoot = replaceColorsSvg(node, isFillSetOnRoot, colorReplacements, nodesWithOrigColors);\n }\n },\n },\n };\n },\n },\n ],\n }).data;\n\n let importType = options.defaultImport || \"source\";\n\n for (const type of IMPORT_TYPES) {\n if (query[type]) {\n importType = type;\n }\n }\n\n if (isLibraryMode && importType === \"url\" && urlImportsInLibraryMode !== \"emit-files\") {\n importType = urlImportsInLibraryMode;\n }\n\n /**\n * Returns exports string\n * @param src Source code enclosed with quotes. Single quotes, double quotes and backticks are fine\n * as long as they're escaped in the actual source code.)\n * @returns Exports string\n */\n const getExports = (src: string) => {\n return [\n `export const src = ${src};`,\n `export const prefix = \"${classesAndIdsPrefix}\"`,\n `export default src`,\n ].join(\"\\n\");\n };\n\n switch (importType) {\n case \"source\":\n return getExports(\"`\" + escapeBackticks(code) + \"`\");\n case \"source-data-uri\":\n return getExports(\"`data:image/svg+xml,\" + encodeURIComponent(code) + \"`\");\n case \"base64\":\n return getExports(\"`\" + escapeBackticks(toBase64(code)) + \"`\");\n case \"base64-data-uri\":\n return getExports(\"`data:image/svg+xml;base64,\" + encodeURIComponent(toBase64(code)) + \"`\");\n }\n\n if (!isBuildMode) {\n const assetUrl = tempDir + assetRelPath;\n await writeFile(root + assetUrl, code);\n return getExports(`\"${base + assetUrl}\"`);\n }\n\n const assetId = this.emitFile({\n type: \"asset\",\n name: assetFileName,\n source: code,\n });\n\n return getExports(`\"__VITE_ASSET__${assetId}__\"`);\n },\n };\n}\n"],"names":["normalizeBaseDir","dir","toBase64","str","binString","escapeBackticks","matchesQueryOrPath","options","matchesQuery","matchesPath","queryValue","toMatch","path","matchers","toArray","matcher","v","normalizeSelector","selector","selectorsToList","selectors","resolvedSelectors","selectorStr","matchesSelector","matchesSelectorRaw","matchesSelectors","node","replaceColor","color","replacements","isColorMapPerFiles","value","TAGS_TO_PRESERVE_LINE_WIDTH_OF","preserveLineWidth","vectorEffectAttr","COLOR_ATTRS_TO_REPLACE","IGNORE_COLORS","IMPORT_TYPES","replaceColorsCss","css","nodesWithOrigColors","isInline","context","shouldPreserveColors","origColorSelectors","currentColorSelectors","didSplitSelectors","ast","csstree","isOrigColor","svgNode","identifier","origColorsRule","origColorsSelectors","listItem","parent","insertBefore","rule","ELEMENTS_TO_FORCE_SET_FILL_OF","COLOR_ATTRS_TO_REPLACE_SVG","replaceColorsSvg","isFillSetOnRoot","firstChild","newCss","isRoot","fillAttr","attr","attrsColor","viteAwesomeSvgLoader","urlImportsInLibraryMode","tempDir","isBuildMode","isLibraryMode","root","base","replaceColorsList","replacementsWithFiles","filesWithCurrentColor","allFilesReplacements","hasAllFilesReplacements","isFileMatcher","replaceColorsListNormalized","config","command","server","rm","id","ext","indexOfSvg","relPathWithSlash","queryKVPairs","query","pair","key","fileMatcherCtx","matchesQueryOrPathRaw","selectorsToListRaw","shouldSkipTransforms","shouldPreserveLineWidth","skipPreserveLineWidthSelectors","shouldReplaceColors","colorReplacements","entry","skipReplaceColorsSelectors","skipTransformsSelectors","hashParts","arr","param","hash","MurmurHash3","assetFileNameNoExt","assetFileName","assetRelPath","fullPath","code","readFile","classesAndIdsPrefix","didTransform","optimize","querySelectorAll","importType","type","getExports","src","assetUrl","writeFile","assetId"],"mappings":"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"}