summaryrefslogtreecommitdiff
path: root/node_modules/svgo/lib/path.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-05-18 23:10:59 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-05-18 23:41:44 +0800
commitfc87c009806dcc98867f6b58efe29b042aa01dee (patch)
tree8f59b3f4a5b66e9dfef2d40c8d318e258a521228 /node_modules/svgo/lib/path.js
parent3336b2356ee6152d9c6ae59bd9b87ccbc0958407 (diff)
node: updatemain
Diffstat (limited to 'node_modules/svgo/lib/path.js')
-rw-r--r--node_modules/svgo/lib/path.js380
1 files changed, 0 insertions, 380 deletions
diff --git a/node_modules/svgo/lib/path.js b/node_modules/svgo/lib/path.js
deleted file mode 100644
index 814ee2e3..00000000
--- a/node_modules/svgo/lib/path.js
+++ /dev/null
@@ -1,380 +0,0 @@
-'use strict';
-
-const { removeLeadingZero, toFixed } = require('./svgo/tools');
-
-/**
- * @typedef {import('./types').PathDataItem} PathDataItem
- * @typedef {import('./types').PathDataCommand} PathDataCommand
- */
-
-// Based on https://www.w3.org/TR/SVG11/paths.html#PathDataBNF
-
-const argsCountPerCommand = {
- M: 2,
- m: 2,
- Z: 0,
- z: 0,
- L: 2,
- l: 2,
- H: 1,
- h: 1,
- V: 1,
- v: 1,
- C: 6,
- c: 6,
- S: 4,
- s: 4,
- Q: 4,
- q: 4,
- T: 2,
- t: 2,
- A: 7,
- a: 7,
-};
-
-/**
- * @type {(c: string) => c is PathDataCommand}
- */
-const isCommand = (c) => {
- return c in argsCountPerCommand;
-};
-
-/**
- * @type {(c: string) => boolean}
- */
-const isWsp = (c) => {
- const codePoint = c.codePointAt(0);
- return (
- codePoint === 0x20 ||
- codePoint === 0x9 ||
- codePoint === 0xd ||
- codePoint === 0xa
- );
-};
-
-/**
- * @type {(c: string) => boolean}
- */
-const isDigit = (c) => {
- const codePoint = c.codePointAt(0);
- if (codePoint == null) {
- return false;
- }
- return 48 <= codePoint && codePoint <= 57;
-};
-
-/**
- * @typedef {'none' | 'sign' | 'whole' | 'decimal_point' | 'decimal' | 'e' | 'exponent_sign' | 'exponent'} ReadNumberState
- */
-
-/**
- * @type {(string: string, cursor: number) => [number, ?number]}
- */
-const readNumber = (string, cursor) => {
- let i = cursor;
- let value = '';
- let state = /** @type {ReadNumberState} */ ('none');
- for (; i < string.length; i += 1) {
- const c = string[i];
- if (c === '+' || c === '-') {
- if (state === 'none') {
- state = 'sign';
- value += c;
- continue;
- }
- if (state === 'e') {
- state = 'exponent_sign';
- value += c;
- continue;
- }
- }
- if (isDigit(c)) {
- if (state === 'none' || state === 'sign' || state === 'whole') {
- state = 'whole';
- value += c;
- continue;
- }
- if (state === 'decimal_point' || state === 'decimal') {
- state = 'decimal';
- value += c;
- continue;
- }
- if (state === 'e' || state === 'exponent_sign' || state === 'exponent') {
- state = 'exponent';
- value += c;
- continue;
- }
- }
- if (c === '.') {
- if (state === 'none' || state === 'sign' || state === 'whole') {
- state = 'decimal_point';
- value += c;
- continue;
- }
- }
- if (c === 'E' || c == 'e') {
- if (
- state === 'whole' ||
- state === 'decimal_point' ||
- state === 'decimal'
- ) {
- state = 'e';
- value += c;
- continue;
- }
- }
- break;
- }
- const number = Number.parseFloat(value);
- if (Number.isNaN(number)) {
- return [cursor, null];
- } else {
- // step back to delegate iteration to parent loop
- return [i - 1, number];
- }
-};
-
-/**
- * @type {(string: string) => PathDataItem[]}
- */
-const parsePathData = (string) => {
- /**
- * @type {PathDataItem[]}
- */
- const pathData = [];
- /**
- * @type {?PathDataCommand}
- */
- let command = null;
- let args = /** @type {number[]} */ ([]);
- let argsCount = 0;
- let canHaveComma = false;
- let hadComma = false;
- for (let i = 0; i < string.length; i += 1) {
- const c = string.charAt(i);
- if (isWsp(c)) {
- continue;
- }
- // allow comma only between arguments
- if (canHaveComma && c === ',') {
- if (hadComma) {
- break;
- }
- hadComma = true;
- continue;
- }
- if (isCommand(c)) {
- if (hadComma) {
- return pathData;
- }
- if (command == null) {
- // moveto should be leading command
- if (c !== 'M' && c !== 'm') {
- return pathData;
- }
- } else {
- // stop if previous command arguments are not flushed
- if (args.length !== 0) {
- return pathData;
- }
- }
- command = c;
- args = [];
- argsCount = argsCountPerCommand[command];
- canHaveComma = false;
- // flush command without arguments
- if (argsCount === 0) {
- pathData.push({ command, args });
- }
- continue;
- }
- // avoid parsing arguments if no command detected
- if (command == null) {
- return pathData;
- }
- // read next argument
- let newCursor = i;
- let number = null;
- if (command === 'A' || command === 'a') {
- const position = args.length;
- if (position === 0 || position === 1) {
- // allow only positive number without sign as first two arguments
- if (c !== '+' && c !== '-') {
- [newCursor, number] = readNumber(string, i);
- }
- }
- if (position === 2 || position === 5 || position === 6) {
- [newCursor, number] = readNumber(string, i);
- }
- if (position === 3 || position === 4) {
- // read flags
- if (c === '0') {
- number = 0;
- }
- if (c === '1') {
- number = 1;
- }
- }
- } else {
- [newCursor, number] = readNumber(string, i);
- }
- if (number == null) {
- return pathData;
- }
- args.push(number);
- canHaveComma = true;
- hadComma = false;
- i = newCursor;
- // flush arguments when necessary count is reached
- if (args.length === argsCount) {
- pathData.push({ command, args });
- // subsequent moveto coordinates are treated as implicit lineto commands
- if (command === 'M') {
- command = 'L';
- }
- if (command === 'm') {
- command = 'l';
- }
- args = [];
- }
- }
- return pathData;
-};
-exports.parsePathData = parsePathData;
-
-/**
- * @type {(number: number, precision?: number) => {
- * roundedStr: string,
- * rounded: number
- * }}
- */
-const roundAndStringify = (number, precision) => {
- if (precision != null) {
- number = toFixed(number, precision);
- }
-
- return {
- roundedStr: removeLeadingZero(number),
- rounded: number,
- };
-};
-
-/**
- * Elliptical arc large-arc and sweep flags are rendered with spaces
- * because many non-browser environments are not able to parse such paths
- *
- * @type {(
- * command: string,
- * args: number[],
- * precision?: number,
- * disableSpaceAfterFlags?: boolean
- * ) => string}
- */
-const stringifyArgs = (command, args, precision, disableSpaceAfterFlags) => {
- let result = '';
- let previous;
-
- for (let i = 0; i < args.length; i++) {
- const { roundedStr, rounded } = roundAndStringify(args[i], precision);
- if (
- disableSpaceAfterFlags &&
- (command === 'A' || command === 'a') &&
- // consider combined arcs
- (i % 7 === 4 || i % 7 === 5)
- ) {
- result += roundedStr;
- } else if (i === 0 || rounded < 0) {
- // avoid space before first and negative numbers
- result += roundedStr;
- } else if (
- !Number.isInteger(previous) &&
- rounded != 0 &&
- rounded < 1 &&
- rounded > -1
- ) {
- // remove space before decimal with zero whole
- // only when previous number is also decimal
- result += roundedStr;
- } else {
- result += ` ${roundedStr}`;
- }
- previous = rounded;
- }
-
- return result;
-};
-
-/**
- * @typedef {{
- * pathData: PathDataItem[];
- * precision?: number;
- * disableSpaceAfterFlags?: boolean;
- * }} StringifyPathDataOptions
- */
-
-/**
- * @param {StringifyPathDataOptions} options
- * @returns {string}
- */
-const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
- if (pathData.length === 1) {
- const { command, args } = pathData[0];
- return (
- command + stringifyArgs(command, args, precision, disableSpaceAfterFlags)
- );
- }
-
- let result = '';
- let prev = { ...pathData[0] };
-
- // match leading moveto with following lineto
- if (pathData[1].command === 'L') {
- prev.command = 'M';
- } else if (pathData[1].command === 'l') {
- prev.command = 'm';
- }
-
- for (let i = 1; i < pathData.length; i++) {
- const { command, args } = pathData[i];
- if (
- (prev.command === command &&
- prev.command !== 'M' &&
- prev.command !== 'm') ||
- // combine matching moveto and lineto sequences
- (prev.command === 'M' && command === 'L') ||
- (prev.command === 'm' && command === 'l')
- ) {
- prev.args = [...prev.args, ...args];
- if (i === pathData.length - 1) {
- result +=
- prev.command +
- stringifyArgs(
- prev.command,
- prev.args,
- precision,
- disableSpaceAfterFlags,
- );
- }
- } else {
- result +=
- prev.command +
- stringifyArgs(
- prev.command,
- prev.args,
- precision,
- disableSpaceAfterFlags,
- );
-
- if (i === pathData.length - 1) {
- result +=
- command +
- stringifyArgs(command, args, precision, disableSpaceAfterFlags);
- } else {
- prev = { command, args };
- }
- }
- }
-
- return result;
-};
-exports.stringifyPathData = stringifyPathData;