├── .gitattributes ├── src ├── index.ts ├── rnShowMoreText.tsx ├── rnShowMoreText.ios.tsx └── helper.ts ├── .gitignore ├── tsconfig.json ├── .npmignore ├── LICENSE ├── package.json ├── README.md └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import RNShowMoreText, { 2 | RNShowMoreTextComponent, 3 | RNShowMoreTextProps, 4 | } from "./rnShowMoreText"; 5 | 6 | export { RNShowMoreTextComponent, RNShowMoreTextProps }; 7 | export default RNShowMoreText; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | 4 | # Build 5 | lib/ 6 | 7 | # Logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | 13 | # Misc 14 | .DS_Store 15 | .env 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | # IDE 22 | .idea/ 23 | .vscode/ 24 | *.swp 25 | *.swo -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./lib", 7 | "strict": true, 8 | "jsx": "react-native", 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "lib": ["es2018"], 13 | "moduleResolution": "node" 14 | }, 15 | "include": ["src"], 16 | "exclude": ["node_modules", "**/__tests__/*"] 17 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Source code 2 | src/ 3 | 4 | # Development files 5 | node_modules/ 6 | .git/ 7 | .github/ 8 | .vscode/ 9 | .idea/ 10 | 11 | assets/ 12 | 13 | # Configuration files 14 | tsconfig.json 15 | jest.config.js 16 | .eslintrc 17 | .prettierrc 18 | .babelrc 19 | 20 | # Test files 21 | __tests__/ 22 | *.test.ts 23 | *.test.tsx 24 | *.spec.ts 25 | *.spec.tsx 26 | 27 | # Documentation 28 | docs/ 29 | examples/ 30 | demo/ 31 | 32 | # Misc 33 | .DS_Store 34 | npm-debug.log 35 | yarn-debug.log 36 | yarn-error.log 37 | *.log 38 | .env 39 | .env.* 40 | coverage/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 ZipEnter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rn-show-more-text", 3 | "version": "2.0.0", 4 | "description": "React Native show more text component", 5 | "main": "lib/index.js", 6 | "types": "lib/index.d.ts", 7 | "scripts": { 8 | "build": "tsc", 9 | "prepare": "npm run build", 10 | "clean": "rm -rf lib/", 11 | "prebuild": "npm run clean", 12 | "lint": "eslint . --ext .ts,.tsx", 13 | "format": "prettier --write \"src/**/*.{ts,tsx}\"", 14 | "dev": "tsc --watch", 15 | "prepublishOnly": "npm run build", 16 | "version": "npm run format && git add -A src", 17 | "postversion": "git push && git push --tags", 18 | "release:patch": "npm version patch && npm publish", 19 | "release:minor": "npm version minor && npm publish", 20 | "release:major": "npm version major && npm publish" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/vincenttran99/rn-show-more-text.git" 25 | }, 26 | "keywords": [ 27 | "react-native", 28 | "react", 29 | "typescript", 30 | "react", 31 | "show more", 32 | "ellipsis", 33 | "multiline", 34 | "show more text", 35 | "show partial text", 36 | "hide partial text", 37 | "show-more fix", 38 | "show text", 39 | "hide text", 40 | "read more", 41 | "see more", 42 | "collapse", 43 | "expandable" 44 | ], 45 | "author": "vincenttran99", 46 | "license": "MIT", 47 | "bugs": { 48 | "url": "https://github.com/vincenttran99/rn-show-more-text/issues" 49 | }, 50 | "homepage": "https://github.com/vincenttran99/rn-show-more-text#readme", 51 | "peerDependencies": { 52 | "react": "*", 53 | "react-native": "*" 54 | }, 55 | "devDependencies": { 56 | "@types/react": "^19.1.4", 57 | "@types/react-native": "^0.70.0", 58 | "prettier": "^3.5.3", 59 | "react": "^19.1.0", 60 | "react-dom": "^19.1.0", 61 | "react-native": "^0.79.2", 62 | "ts-node": "^10.9.2", 63 | "typescript": "^4.9.5" 64 | }, 65 | "dependencies": {} 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RN Show More Text 2 | 3 | A React Native component that intelligently truncates text with a customizable "Show more"/"Show less" functionality. 4 | 5 | ## Getting Started 6 | 7 | ```sh 8 | yarn add rn-show-more-text 9 | ``` 10 | 11 | or 12 | 13 | ```sh 14 | npm install rn-show-more-text 15 | ``` 16 | 17 | ## Usage 18 | 19 | 20 | 21 | ```tsx 22 | import RNShowMoreText from "rn-show-more-text"; 23 | 24 | // Basic usage 25 | 26 | { 27 | "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum." 28 | } 29 | 30 | 31 | // With custom styling 32 | 38 | {longText} 39 | 40 | 41 | // With advanced character width customization 42 | 50 | {longText} 51 | 52 | ``` 53 | 54 | ## Props 55 | 56 | The RNShowMoreText component supports the following props: 57 | 58 | | Name | Type | Required | Default | Description | 59 | | ------------------------ | ---------------------- | -------- | ---------------------- | ------------------------------------------------------------------------------------------- | 60 | | numberOfLines | number | Yes | - | Maximum number of lines to display before truncating | 61 | | children | string | Yes | - | Text content to display | 62 | | readMoreStyle | StyleProp\ | No | { fontWeight: 'bold' } | Style for the "show more"/"show less" text | 63 | | readMoreTextProps | TextProps | No | - | Additional props for the "show more"/"show less" text component | 64 | | readMoreText | string | No | "Show more" | Custom text for the "show more" button | 65 | | readLessText | string | No | "Show less" | Custom text for the "show less" button | 66 | | compensationSpaceAndroid | number | No | 0 | Extra space to account for when calculating text truncation on Android (in character width) | 67 | | compensationSpaceIos | number | No | 1 | Extra space to account for when calculating text truncation on iOS (in character width) | 68 | | isMonospaced | boolean | No | false | Whether the font being used is monospaced (all characters have equal width) | 69 | | shortWidthCharacters | string[] | No | [] | Array of characters that have short width (0.5x normal character width) | 70 | | longWidthCharacters | string[] | No | [] | Array of characters that have long width (1.5x normal character width) | 71 | 72 | In addition, this component accepts all standard [Text Props](https://reactnative.dev/docs/text) from React Native. 73 | 74 | ## Key Features 75 | 76 | - Intelligently calculates text truncation with proper ellipsis 77 | - **Advanced text handling**: Supports various character widths including emojis, narrow characters (i, t, l), and wide characters (m, w, M, W) 78 | - **Smart visual width calculation**: Automatically adjusts for different character types to ensure accurate text measurement 79 | - Smooth animation when expanding/collapsing text 80 | - Customizable "Show more"/"Show less" text and styling 81 | - Works with dynamic content and container resizing 82 | - Optimized performance with memoization 83 | - Cross-platform compatibility with platform-specific adjustments 84 | 85 | ## How It Works 86 | 87 | > **Note: Android instability may occur**. For example, even though the same paragraph has different lengths, on Android devices, "line bouncing" may occur. For example, if you have a string printed out with 10 lines, if you delete the last 1-2 words of the string, it may also change the number of lines and the length of the lines even with the first lines (which are actually unrelated to the last words). Currently, I do not have a solution to this problem. If anyone has a solution, please create an issue or a PR so we can discuss it, thank you. 88 | 89 | The component intelligently calculates the average character width and determines exactly how much text can be displayed within the specified number of lines while leaving room for the "Show more" button. This ensures that text is truncated at a natural point with proper ellipsis. 90 | 91 | `compensationSpaceIos` and `compensationSpaceAndroid` are offset parameters, where 1 unit corresponds to 1 character width. These parameters help account for platform-specific text rendering differences. For example, when we replace 8 characters "i" with 8 characters "m", it is possible to make the "Show more" text jump to a new line because they have different visual widths. 92 | 93 | The component appends "... " (4 characters) to the truncated text before adding the "Show more" button. The compensation space provides additional buffer to prevent layout issues: 94 | 95 | - **iOS** (default: 1): iOS text rendering is generally more predictable, requiring minimal compensation 96 | - **Android** (default: 0): Android text rendering can be more variable, but the default works for most cases 97 | 98 | Basically, the larger the compensation space, the less likely it is that "Show more" will jump to the next line. The smaller the compensation space, the more space it will create on the right. You may need to adjust these values based on your specific font and text content. 99 | 100 | ## Advanced Text Handling 101 | 102 | This component provides sophisticated text handling capabilities that go beyond simple character counting. It intelligently handles various types of characters with different visual widths: 103 | 104 | ### Character Width Classification 105 | 106 | - **Short Width Characters (0.5x)**: Narrow characters like `i`, `t`, `f`, `r`, `l`, punctuation marks (`.`, `,`, `;`, `:`) 107 | - **Normal Width Characters (1x)**: Most alphabetic characters and numbers 108 | - **Long Width Characters (1.5x)**: Wide characters like `m`, `w`, `M`, `W` 109 | - **Emoji Characters (2x)**: All emoji characters take approximately double the width of normal characters 110 | 111 | ### Smart Visual Width Calculation 112 | 113 | The component uses a sophisticated algorithm to calculate the visual width of text: 114 | 115 | 1. **Character Classification**: Each character is classified into one of the width categories above 116 | 2. **Visual Length Calculation**: The total visual width is calculated by summing the individual character widths 117 | 3. **Intelligent Truncation**: Text is truncated based on visual width rather than character count, ensuring consistent appearance 118 | 119 | ### Customization Options 120 | 121 | You can customize the character width classification: 122 | 123 | - `shortWidthCharacters`: Override the default list of narrow characters 124 | - `longWidthCharacters`: Override the default list of wide characters 125 | - `isMonospaced`: Set to true if using a monospaced font where all characters have equal width 126 | 127 | ### Example with Mixed Content 128 | 129 | ```tsx 130 | // Text with emojis, narrow and wide characters 131 | 132 | {"Hello! 👋 This text contains emojis 😊🎉, narrow characters like 'i' and 'l', and wide characters like 'M' and 'W'. The component will calculate the visual width accurately! 🚀"} 133 | 134 | 135 | // Custom character width configuration 136 | 141 | {"Custom width handling for specific characters and symbols."} 142 | 143 | ``` 144 | 145 | This advanced handling ensures that text truncation appears natural and consistent, regardless of the mix of character types in your content. 146 | 147 | ## License 148 | 149 | [MIT](LICENSE) 150 | -------------------------------------------------------------------------------- /src/rnShowMoreText.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | memo, 3 | useCallback, 4 | useLayoutEffect, 5 | useMemo, 6 | useRef, 7 | useState, 8 | } from "react"; 9 | import { 10 | GestureResponderEvent, 11 | LayoutChangeEvent, 12 | NativeSyntheticEvent, 13 | StyleProp, 14 | StyleSheet, 15 | Text, 16 | TextLayoutEventData, 17 | TextLayoutLine, 18 | TextProps, 19 | TextStyle, 20 | } from "react-native"; 21 | import { 22 | balanceDiffHelper, 23 | calculateSlicePositionHelper, 24 | calculateStringWidthHelper, 25 | getVisualLengthHelper, 26 | visualSliceHelper, 27 | } from "./helper"; 28 | 29 | /** 30 | * Interface for RNShowMoreText component props 31 | * Extends the base text component props with additional functionality 32 | * for handling text truncation with "see more"/"hide" options 33 | */ 34 | export type RNShowMoreTextProps = TextProps & { 35 | /** Maximum number of lines to display before truncating */ 36 | numberOfLines: number; 37 | /** Text content to display */ 38 | children: string; 39 | /** Style for the "see more"/"hide" text */ 40 | readMoreStyle?: StyleProp; 41 | /** Extra space to account for when calculating text truncation (in character width) */ 42 | compensationSpaceIos?: number; 43 | compensationSpaceAndroid?: number; 44 | /** Additional props for the "see more"/"hide" text component */ 45 | readMoreTextProps?: TextProps; 46 | /** Whether the font being used is monospaced (all characters have equal width) */ 47 | isMonospaced?: boolean; 48 | /** Array of characters that have short width (0.5x normal character width) */ 49 | shortWidthCharacters?: string[]; 50 | /** Array of characters that have long width (1.5x normal character width) */ 51 | longWidthCharacters?: string[]; 52 | 53 | readMoreText?: string; 54 | readLessText?: string; 55 | }; 56 | 57 | /** 58 | * Text component with ellipsis and "see more"/"hide" functionality 59 | * 60 | * This component intelligently truncates text to fit within a specified number of lines, 61 | * adding a "see more" button that allows users to expand the text to show its full content. 62 | * 63 | * Important: You should provide a width for this component for proper calculation. 64 | * 65 | * @param numberOfLines - Maximum number of lines to display before truncating 66 | * @param onTextLayout - Optional callback for text layout events 67 | * @param children - Text content to display 68 | * @param readMoreStyle - Style for "see more"/"hide" text 69 | * @param readMoreTextProps - Additional props for the "see more"/"hide" text component 70 | * @param style - Style for the main text component 71 | * @param compensationSpace - Extra space to account for when calculating text truncation 72 | * @param props - Additional props passed to the text component 73 | */ 74 | export const RNShowMoreTextComponent = ({ 75 | numberOfLines, 76 | onTextLayout, 77 | children, 78 | readMoreStyle, 79 | readMoreTextProps, 80 | style, 81 | readMoreText, 82 | readLessText, 83 | compensationSpaceAndroid = 0, 84 | isMonospaced = false, 85 | shortWidthCharacters = [], 86 | longWidthCharacters = [], 87 | ...props 88 | }: RNShowMoreTextProps): React.JSX.Element => { 89 | // State to track if text needs truncation with "read more" option 90 | const [isNeedReadMore, setIsNeedReadMore] = useState(false); 91 | // State used to trigger re-renders when calculations are complete 92 | const [renderTrigger, setRenderTrigger] = useState(false); 93 | // State to track if full text is currently displayed 94 | const isShowingFullTextRef = useRef(false); 95 | 96 | // Refs to store text content in different states 97 | const fullTextRef = useRef(children); 98 | const truncatedTextRef = useRef(children); 99 | 100 | // Refs for layout calculations 101 | const containerWidthRef = useRef(0); 102 | const textLinesRef = useRef([]); 103 | const isCalculationCompleteRef = useRef(false); 104 | const hasPropsChangedRef = useRef(false); 105 | const oldChildren = useRef(children); 106 | 107 | const isNeedTrigger = oldChildren.current !== children; 108 | 109 | // Calculate the length of "Show more" text plus compensation space 110 | const readMoreTextContent = useMemo( 111 | () => `... ${(readMoreText || "Show more").trim()}`, 112 | [readMoreText] 113 | ); 114 | 115 | /** 116 | * Reset calculation state when props change 117 | */ 118 | useLayoutEffect(() => { 119 | // Mark that props have changed, requiring recalculation 120 | hasPropsChangedRef.current = true; 121 | fullTextRef.current = children; 122 | textLinesRef.current = []; 123 | isShowingFullTextRef.current = false; 124 | oldChildren.current = children; 125 | // Trigger re-render to start new calculation 126 | // setRenderTrigger((prev) => !prev); 127 | return () => { 128 | isCalculationCompleteRef.current = false; 129 | }; 130 | }, [children, style, numberOfLines]); 131 | 132 | /** 133 | * Calculate truncated text based on available space and number of lines 134 | * This is the core logic that determines how much text can be shown 135 | * and whether a "see more" button is needed 136 | */ 137 | const calculateTruncatedText = useCallback(() => { 138 | // Skip calculation if we don't have necessary layout information 139 | if (textLinesRef.current?.length === 0 || containerWidthRef.current === 0) { 140 | return; 141 | } 142 | 143 | // Mark calculation as complete and props as processed 144 | isCalculationCompleteRef.current = true; 145 | hasPropsChangedRef.current = false; 146 | 147 | // Check if text exceeds the specified number of lines 148 | if (textLinesRef.current?.length > numberOfLines) { 149 | let visibleText = ""; // Accumulates text from visible lines 150 | 151 | // Process each line up to the numberOfLines limit 152 | for (let i = 0; i < numberOfLines; i++) { 153 | const currentLine = textLinesRef.current[i]; 154 | visibleText = visibleText.concat(currentLine.text); 155 | } 156 | 157 | let avgCharWidth = 0; 158 | 159 | // Prepare text for width calculation (remove trailing newline) 160 | const lastRow = 161 | textLinesRef.current.length >= numberOfLines 162 | ? textLinesRef.current[numberOfLines - 1] 163 | : undefined; 164 | 165 | const lastRowForWidthCalc = lastRow 166 | ? lastRow.text.endsWith("\n") 167 | ? lastRow.text.slice(0, -1) 168 | : lastRow.text 169 | : ""; 170 | 171 | const lastRowVisualLength = getVisualLengthHelper( 172 | lastRowForWidthCalc, 173 | shortWidthCharacters, 174 | longWidthCharacters 175 | ); 176 | 177 | // Calculate average character width for this line, 178 | // only if it has measurable text content and width. 179 | if (lastRowVisualLength.visualLength > 0) { 180 | avgCharWidth = (lastRow?.width || 0) / lastRowVisualLength.visualLength; 181 | } 182 | 183 | // Get width of the last visible line (the line at numberOfLines - 1 index) 184 | const lastLineWidth = textLinesRef.current[numberOfLines - 1].width; 185 | // Calculate the balance between the number of emojis and the number of short characters in the last line. 186 | const balance = balanceDiffHelper( 187 | lastRowVisualLength.emojiCount, 188 | lastRowVisualLength.shortCharCount, 189 | lastRowVisualLength.longCharCount 190 | ); 191 | 192 | // If the balance is not zero, adjust the average character width. 193 | avgCharWidth = 194 | balance === 0 195 | ? avgCharWidth 196 | : avgCharWidth * 197 | (balance < 0 198 | ? 1 + Math.abs(balance) / lastRowVisualLength.visualLength 199 | : 1 - Math.abs(balance) / lastRowVisualLength.visualLength); 200 | 201 | // Calculate the target width for the last line to accommodate the "see more" text. 202 | // This is the container width minus the estimated width of "see more" text. 203 | const readMoreTextLength = calculateStringWidthHelper( 204 | readMoreTextContent, 205 | avgCharWidth || 1, 206 | isMonospaced, 207 | shortWidthCharacters, 208 | longWidthCharacters 209 | ); 210 | 211 | const targetLastLineWidth = 212 | containerWidthRef.current - readMoreTextLength; // Use fallback 1 for avgCharWidth if it's 0 213 | 214 | // Remove trailing newline from the accumulated visibleText if present 215 | if (visibleText.endsWith("\n")) { 216 | visibleText = visibleText.slice(0, -1); 217 | } 218 | 219 | // Determine how many characters to trim from the end of visibleText. 220 | // If the last line is already short enough (lastLineWidth <= targetLastLineWidth), 221 | // sliceEndOffset will be undefined, meaning no characters are trimmed from visibleText itself before adding "...". 222 | // Otherwise, calculate a negative offset (sliceEndOffset) representing the number of characters to remove from the end. 223 | // The (avgCharacterWidth || 1) ensures division by a non-zero number. 224 | const sliceEndOffset = 225 | lastLineWidth <= targetLastLineWidth 226 | ? undefined 227 | : calculateSlicePositionHelper( 228 | lastRowForWidthCalc, 229 | avgCharWidth, 230 | readMoreTextLength + compensationSpaceAndroid * avgCharWidth, 231 | isMonospaced, 232 | shortWidthCharacters, 233 | longWidthCharacters 234 | ); 235 | 236 | // Construct the truncated text. 237 | // If sliceEndOffset is defined (negative), it's used to trim characters from the end of visibleText. 238 | // countShortCharactersHelper adjusts the trim count, possibly for multi-byte or variable-width characters. 239 | truncatedTextRef.current = visualSliceHelper( 240 | visibleText, 241 | 0, 242 | sliceEndOffset ? sliceEndOffset : undefined 243 | ).trim(); 244 | 245 | // Update refs and state to reflect truncation 246 | fullTextRef.current = truncatedTextRef.current; 247 | setIsNeedReadMore(true); 248 | } else { 249 | // Text fits within specified lines, no "see more" needed 250 | setIsNeedReadMore(false); 251 | } 252 | 253 | // Trigger re-render with calculated text 254 | setRenderTrigger((prev) => !prev); 255 | }, [ 256 | readMoreTextContent, 257 | numberOfLines, 258 | compensationSpaceAndroid, 259 | isMonospaced, 260 | shortWidthCharacters, 261 | longWidthCharacters, 262 | ]); 263 | 264 | /** 265 | * Handle text layout event to get line information 266 | * Forwards the event to any provided onTextLayout prop 267 | */ 268 | const onTextLayoutHandler = useCallback( 269 | (event: NativeSyntheticEvent) => { 270 | // Forward event to any provided onTextLayout handler 271 | onTextLayout?.(event); 272 | 273 | // Skip if calculation is already complete 274 | if (isCalculationCompleteRef.current) { 275 | return; 276 | } 277 | 278 | // Store line information from layout event 279 | textLinesRef.current = event.nativeEvent?.lines || []; 280 | calculateTruncatedText(); 281 | }, 282 | [onTextLayout, numberOfLines, readMoreTextContent, compensationSpaceAndroid] 283 | ); 284 | 285 | /** 286 | * Toggle between showing truncated text and full text 287 | */ 288 | const toggleTextExpansion = useCallback( 289 | (event: GestureResponderEvent) => { 290 | if (isShowingFullTextRef.current) { 291 | // Switch to truncated text 292 | fullTextRef.current = truncatedTextRef.current; 293 | isShowingFullTextRef.current = false; 294 | } else { 295 | // Switch to full text 296 | fullTextRef.current = children; 297 | isShowingFullTextRef.current = true; 298 | } 299 | setRenderTrigger((prev) => !prev); 300 | // Call any onPress handler provided in readMoreTextProps 301 | readMoreTextProps?.onPress?.(event); 302 | }, 303 | [children, readMoreTextProps?.onPress] 304 | ); 305 | 306 | /** 307 | * Handle container layout to get width information 308 | */ 309 | const onContainerLayout = useCallback( 310 | (event: LayoutChangeEvent) => { 311 | // Skip if calculation is already complete 312 | 313 | if (isCalculationCompleteRef.current) { 314 | return; 315 | } 316 | 317 | // Store container width from layout event 318 | containerWidthRef.current = event.nativeEvent?.layout?.width || 0; 319 | calculateTruncatedText(); 320 | }, 321 | [numberOfLines] 322 | ); 323 | 324 | return ( 325 | 349 | {isNeedTrigger ? children : fullTextRef.current} 350 | {!isNeedTrigger && isNeedReadMore ? ( 351 | 356 | {isShowingFullTextRef.current 357 | ? " " + (readLessText || "Show less") 358 | : readMoreTextContent} 359 | 360 | ) : null} 361 | 362 | ); 363 | }; 364 | 365 | const styles = StyleSheet.create({ 366 | container: { 367 | width: "100%", 368 | }, 369 | readMoreText: { 370 | fontWeight: "bold", 371 | }, 372 | }); 373 | 374 | /** 375 | * Memoized version of RNShowMoreText component to prevent unnecessary re-renders 376 | */ 377 | const RNShowMoreText = memo(RNShowMoreTextComponent); 378 | export default RNShowMoreText; 379 | -------------------------------------------------------------------------------- /src/rnShowMoreText.ios.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | memo, 3 | useCallback, 4 | useLayoutEffect, 5 | useMemo, 6 | useRef, 7 | useState, 8 | } from "react"; 9 | import { 10 | GestureResponderEvent, 11 | LayoutChangeEvent, 12 | NativeSyntheticEvent, 13 | StyleProp, 14 | StyleSheet, 15 | Text, 16 | TextLayoutEventData, 17 | TextLayoutLine, 18 | TextProps, 19 | TextStyle, 20 | View, 21 | } from "react-native"; 22 | import { 23 | balanceDiffHelper, 24 | calculateSlicePositionHelper, 25 | calculateStringWidthHelper, 26 | getVisualLengthHelper, 27 | visualSliceHelper, 28 | } from "./helper"; 29 | 30 | /** 31 | * Interface for BTextEllipsis component props 32 | * Extends the base text component props with additional functionality 33 | * for handling text truncation with "see more"/"hide" options 34 | */ 35 | export type TBTextEllipsisProps = TextProps & { 36 | /** Maximum number of lines to display before truncating */ 37 | numberOfLines: number; 38 | /** Text content to display */ 39 | children: string; 40 | /** Additional props for the "see more"/"hide" text component */ 41 | readMoreTextProps?: TextProps; 42 | /** Extra space to account for when calculating text truncation (in character width) */ 43 | compensationSpaceIos?: number; 44 | compensationSpaceAndroid?: number; 45 | /** Style for the "see more"/"hide" text */ 46 | readMoreStyle?: StyleProp; 47 | /** Whether the font being used is monospaced (all characters have equal width) */ 48 | isMonospaced?: boolean; 49 | /** Array of characters that have short width (0.5x normal character width) */ 50 | shortWidthCharacters?: string[]; 51 | /** Array of characters that have long width (1.5x normal character width) */ 52 | longWidthCharacters?: string[]; 53 | 54 | readMoreText?: string; 55 | readLessText?: string; 56 | }; 57 | 58 | /** 59 | * Text component with ellipsis and "see more"/"hide" functionality 60 | * 61 | * This component intelligently truncates text to fit within a specified number of lines, 62 | * adding a "see more" button that allows users to expand the text to show its full content. 63 | * 64 | * Important: You should provide a width for this component for proper calculation. 65 | * 66 | * @param numberOfLines - Maximum number of lines to display before truncating 67 | * @param children - Text content to display 68 | * @param readMoreStyle - Style for "see more"/"hide" text 69 | * @param style - Style for the main text component 70 | * @param readMoreTextProps - Additional props for the "see more"/"hide" text component 71 | * @param compensationSpace - Extra space to account for when calculating text truncation 72 | * @param props - Additional props passed to the text component 73 | */ 74 | export const RNShowMoreTextComponent = ({ 75 | numberOfLines, 76 | children, 77 | readMoreStyle, 78 | style, 79 | readMoreTextProps, 80 | readMoreText, 81 | readLessText, 82 | compensationSpaceIos = 1, 83 | isMonospaced = false, 84 | shortWidthCharacters = [], 85 | longWidthCharacters = [], 86 | ...props 87 | }: TBTextEllipsisProps): React.JSX.Element => { 88 | // State to track if text needs truncation with "read more" option 89 | const [isNeedReadMore, setIsNeedReadMore] = useState(false); 90 | // State used to trigger re-renders when calculations are complete 91 | const [renderTrigger, setRenderTrigger] = useState(false); 92 | // State to track if full text is currently displayed 93 | const isShowingFullTextRef = useRef(false); 94 | 95 | // Refs to store text content in different states 96 | const fullTextRef = useRef(children); 97 | const truncatedTextRef = useRef(children); 98 | 99 | // Refs for layout calculations 100 | const containerWidthRef = useRef(0); 101 | const textLinesRef = useRef([]); 102 | const isCalculationCompleteRef = useRef(false); 103 | const hasPropsChangedRef = useRef(false); 104 | const oldChildren = useRef(children); 105 | 106 | const isNeedTrigger = oldChildren.current !== children; 107 | 108 | // Calculate the length of "Show more" text plus compensation space 109 | const readMoreTextContent = useMemo( 110 | () => `... ${(readMoreText || "Show more").trim()}`, 111 | [readMoreText] 112 | ); 113 | 114 | /** 115 | * Reset calculation state when props change 116 | */ 117 | useLayoutEffect(() => { 118 | // Mark that props have changed, requiring recalculation 119 | hasPropsChangedRef.current = true; 120 | fullTextRef.current = children; 121 | textLinesRef.current = []; 122 | isShowingFullTextRef.current = false; 123 | oldChildren.current = children; 124 | // Trigger re-render to start new calculation 125 | // setRenderTrigger((prev) => !prev); 126 | return () => { 127 | isCalculationCompleteRef.current = false; 128 | }; 129 | }, [children, style, numberOfLines]); 130 | 131 | /** 132 | * Calculate truncated text based on available space and number of lines 133 | * This is the core logic that determines how much text can be shown 134 | * and whether a "see more" button is needed 135 | */ 136 | const calculateTruncatedText = useCallback(() => { 137 | // Skip calculation if we don't have necessary layout information 138 | if (textLinesRef.current?.length === 0 || containerWidthRef.current === 0) { 139 | return; 140 | } 141 | 142 | // Mark calculation as complete and props as processed 143 | isCalculationCompleteRef.current = true; 144 | hasPropsChangedRef.current = false; 145 | 146 | // Check if text exceeds the specified number of lines 147 | if (textLinesRef.current?.length > numberOfLines) { 148 | let visibleText = ""; // Accumulates text from visible lines 149 | 150 | // Process each line up to the numberOfLines limit 151 | for (let i = 0; i < numberOfLines; i++) { 152 | const currentLine = textLinesRef.current[i]; 153 | visibleText = visibleText.concat(currentLine.text); 154 | } 155 | 156 | let avgCharWidth = 0; 157 | 158 | // Prepare text for width calculation (remove trailing newline) 159 | const lastRow = 160 | textLinesRef.current.length >= numberOfLines 161 | ? textLinesRef.current[numberOfLines - 1] 162 | : undefined; 163 | 164 | const lastRowForWidthCalc = lastRow 165 | ? lastRow.text.endsWith("\n") 166 | ? lastRow.text.slice(0, -1) 167 | : lastRow.text 168 | : ""; 169 | 170 | const lastRowVisualLength = getVisualLengthHelper( 171 | lastRowForWidthCalc, 172 | shortWidthCharacters, 173 | longWidthCharacters 174 | ); 175 | 176 | // Calculate average character width for this line, 177 | // only if it has measurable text content and width. 178 | if (lastRowVisualLength.visualLength > 0) { 179 | avgCharWidth = (lastRow?.width || 0) / lastRowVisualLength.visualLength; 180 | } 181 | 182 | // Get width of the last visible line (the line at numberOfLines - 1 index) 183 | const lastLineWidth = textLinesRef.current[numberOfLines - 1].width; 184 | // Calculate the balance between the number of emojis and the number of short characters in the last line. 185 | const balance = balanceDiffHelper( 186 | lastRowVisualLength.emojiCount, 187 | lastRowVisualLength.shortCharCount, 188 | lastRowVisualLength.longCharCount 189 | ); 190 | 191 | // If the balance is not zero, adjust the average character width. 192 | avgCharWidth = 193 | balance === 0 194 | ? avgCharWidth 195 | : avgCharWidth * 196 | (balance < 0 197 | ? 1 + Math.abs(balance) / lastRowVisualLength.visualLength 198 | : 1 - Math.abs(balance) / lastRowVisualLength.visualLength); 199 | 200 | // Calculate the target width for the last line to accommodate the "see more" text. 201 | // This is the container width minus the estimated width of "see more" text. 202 | const readMoreTextLength = calculateStringWidthHelper( 203 | readMoreTextContent, 204 | avgCharWidth || 1, 205 | isMonospaced, 206 | shortWidthCharacters, 207 | longWidthCharacters 208 | ); 209 | 210 | const targetLastLineWidth = 211 | containerWidthRef.current - readMoreTextLength; // Use fallback 1 for avgCharWidth if it's 0 212 | 213 | // Remove trailing newline from the accumulated visibleText if present 214 | if (visibleText.endsWith("\n")) { 215 | visibleText = visibleText.slice(0, -1); 216 | } 217 | 218 | // Determine how many characters to trim from the end of visibleText. 219 | // If the last line is already short enough (lastLineWidth <= targetLastLineWidth), 220 | // sliceEndOffset will be undefined, meaning no characters are trimmed from visibleText itself before adding "...". 221 | // Otherwise, calculate a negative offset (sliceEndOffset) representing the number of characters to remove from the end. 222 | // The (avgCharacterWidth || 1) ensures division by a non-zero number. 223 | const sliceEndOffset = 224 | lastLineWidth <= targetLastLineWidth 225 | ? undefined 226 | : calculateSlicePositionHelper( 227 | lastRowForWidthCalc, 228 | avgCharWidth, 229 | readMoreTextLength + compensationSpaceIos * avgCharWidth, 230 | isMonospaced, 231 | shortWidthCharacters, 232 | longWidthCharacters 233 | ); 234 | 235 | // Construct the truncated text. 236 | // If sliceEndOffset is defined (negative), it's used to trim characters from the end of visibleText. 237 | // countShortCharactersHelper adjusts the trim count, possibly for multi-byte or variable-width characters. 238 | truncatedTextRef.current = visualSliceHelper( 239 | visibleText, 240 | 0, 241 | sliceEndOffset ? sliceEndOffset : undefined 242 | ).trim(); 243 | 244 | // Update refs and state to reflect truncation 245 | fullTextRef.current = truncatedTextRef.current; 246 | setIsNeedReadMore(true); 247 | } else { 248 | // Text fits within specified lines, no "see more" needed 249 | setIsNeedReadMore(false); 250 | } 251 | 252 | // Trigger re-render with calculated text 253 | setRenderTrigger((prev) => !prev); 254 | }, [ 255 | readMoreTextContent, 256 | numberOfLines, 257 | compensationSpaceIos, 258 | isMonospaced, 259 | shortWidthCharacters, 260 | longWidthCharacters, 261 | ]); 262 | 263 | /** 264 | * Handle text layout event to get line information 265 | * Forwards the event to any provided onTextLayout prop 266 | */ 267 | const onTextLayoutHandler = useCallback( 268 | (event: NativeSyntheticEvent) => { 269 | // Skip if calculation is already complete 270 | if (isCalculationCompleteRef.current) { 271 | return; 272 | } 273 | 274 | // Store line information from layout event 275 | textLinesRef.current = event.nativeEvent?.lines || []; 276 | calculateTruncatedText(); 277 | }, 278 | [numberOfLines, readMoreTextContent, compensationSpaceIos] 279 | ); 280 | 281 | /** 282 | * Toggle between showing truncated text and full text 283 | */ 284 | const toggleTextExpansion = useCallback( 285 | (event: GestureResponderEvent) => { 286 | if (isShowingFullTextRef.current) { 287 | // Switch to truncated text 288 | fullTextRef.current = truncatedTextRef.current; 289 | isShowingFullTextRef.current = false; 290 | } else { 291 | // Switch to full text 292 | fullTextRef.current = children; 293 | isShowingFullTextRef.current = true; 294 | } 295 | setRenderTrigger((prev) => !prev); 296 | // Call any onPress handler provided in readMoreTextProps 297 | readMoreTextProps?.onPress?.(event); 298 | }, 299 | [children, readMoreTextProps?.onPress] 300 | ); 301 | 302 | /** 303 | * Handle container layout to get width information 304 | */ 305 | const onContainerLayout = useCallback( 306 | (event: LayoutChangeEvent) => { 307 | // Skip if calculation is already complete 308 | if (isCalculationCompleteRef.current) { 309 | return; 310 | } 311 | 312 | // Store container width from layout event 313 | containerWidthRef.current = event.nativeEvent?.layout?.width || 0; 314 | calculateTruncatedText(); 315 | }, 316 | [numberOfLines] 317 | ); 318 | 319 | return ( 320 | 321 | {/* Visible text component */} 322 | 341 | {fullTextRef.current} 342 | {!isNeedTrigger && isNeedReadMore ? ( 343 | 349 | {isShowingFullTextRef.current 350 | ? " " + (readLessText || "Show less") 351 | : readMoreTextContent} 352 | 353 | ) : null} 354 | 355 | 356 | {/* Hidden text component used for measurement */} 357 | {isNeedTrigger || !isCalculationCompleteRef.current ? ( 358 | 366 | ) : null} 367 | 368 | ); 369 | }; 370 | 371 | const styles = StyleSheet.create({ 372 | container: { 373 | width: "100%", 374 | }, 375 | readMoreText: { 376 | fontWeight: "bold", 377 | }, 378 | absolute: { 379 | position: "absolute", 380 | opacity: 0, 381 | zIndex: -1000, 382 | }, 383 | }); 384 | 385 | /** 386 | * Memoized version of BTextEllipsis component to prevent unnecessary re-renders 387 | */ 388 | const RNShowMoreText = memo(RNShowMoreTextComponent); 389 | export default RNShowMoreText; 390 | function balanceDiff(emojiCount: any, shortCharCount: any, longCharCount: any) { 391 | throw new Error("Function not implemented."); 392 | } 393 | -------------------------------------------------------------------------------- /src/helper.ts: -------------------------------------------------------------------------------- 1 | export const SHORT_CHARACTERS = new Set([ 2 | "í", 3 | "ỉ", 4 | "ị", 5 | "ỉ", 6 | "ì", 7 | "i", 8 | "t", 9 | "f", 10 | "r", 11 | "l", 12 | ".", 13 | ",", 14 | "|", 15 | ":", 16 | ";", 17 | "'", 18 | '"', 19 | "!", 20 | ]); 21 | 22 | export const LONG_CHARACTERS = new Set(["m", "w", "M", "W"]); 23 | 24 | // Compiled regex patterns for better performance 25 | const EMOJI_REGEX = 26 | /((?:\p{Extended_Pictographic}(?:\uFE0F)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F)?)*)|(?:\p{Regional_Indicator}{2}))/gu; 27 | const SIMPLE_EMOJI_REGEX = 28 | /(\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*)/gu; 29 | const COLOR_ATTRIBUTE_REGEX = 30 | /(fill|stroke|stop-color|color|flood-color|lighting-color)="#[a-fA-F0-9]{3,6}"/g; 31 | 32 | // Cache for normalized strings to avoid repeated normalization 33 | const normalizeCache = new Map(); 34 | 35 | // Helper function to get normalized string with caching 36 | function getNormalizedString(text: string): string { 37 | if (normalizeCache.has(text)) { 38 | return normalizeCache.get(text)!; 39 | } 40 | const normalized = text.normalize("NFC"); 41 | // Limit cache size to prevent memory leaks 42 | if (normalizeCache.size > 1000) { 43 | normalizeCache.clear(); 44 | } 45 | normalizeCache.set(text, normalized); 46 | return normalized; 47 | } 48 | 49 | /** 50 | * Counts the number of "short" characters in a given string. 51 | * @param input - The string to analyze. 52 | * @param customShortCharacters - Custom array of characters with short width (0.5x) 53 | * @returns The count of short characters. 54 | */ 55 | export function countShortCharactersHelper( 56 | input: string, 57 | customShortCharacters: string[] = [] 58 | ): number { 59 | let count = 0; 60 | 61 | // Merge custom and default short characters into a single Set for optimal performance 62 | const allShortCharacters = 63 | customShortCharacters.length > 0 64 | ? new Set([...customShortCharacters, ...SHORT_CHARACTERS]) 65 | : SHORT_CHARACTERS; 66 | 67 | for (const char of input) { 68 | if (allShortCharacters.has(char)) { 69 | count++; 70 | } 71 | } 72 | return count; 73 | } 74 | 75 | /** 76 | * Calculate the actual visual length of a string 77 | * Handles complex emojis and regular characters using regex segmentation 78 | * @param text - The string to measure 79 | * @returns The visual length of the string 80 | */ 81 | /** 82 | * Returns visual length, short character count, emoji count, and long character count of a string 83 | * @param text - The string to analyze 84 | * @param customShortCharacters - Custom array of characters with short width (0.5x) 85 | * @param customLongCharacters - Custom array of characters with long width (1.5x) 86 | * @returns { visualLength, shortCharCount, emojiCount, longCharCount } 87 | */ 88 | export function getVisualLengthHelper( 89 | text: string, 90 | customShortCharacters: string[] = [], 91 | customLongCharacters: string[] = [] 92 | ): { 93 | visualLength: number; 94 | shortCharCount: number; 95 | emojiCount: number; 96 | longCharCount: number; 97 | } { 98 | // Early return for empty strings 99 | if (!text) 100 | return { 101 | visualLength: 0, 102 | shortCharCount: 0, 103 | emojiCount: 0, 104 | longCharCount: 0, 105 | }; 106 | 107 | const normalized = getNormalizedString(text); 108 | EMOJI_REGEX.lastIndex = 0; 109 | 110 | let visualLength = 0; 111 | let emojiCount = 0; 112 | let lastIndex = 0; 113 | let match; 114 | 115 | // Count emojis and calculate visual length without creating segments array 116 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 117 | // Add regular characters count before emoji 118 | if (match.index > lastIndex) { 119 | visualLength += match.index - lastIndex; 120 | } 121 | // Add emoji as single visual unit 122 | visualLength++; 123 | emojiCount++; 124 | lastIndex = EMOJI_REGEX.lastIndex; 125 | } 126 | 127 | // Add remaining regular characters 128 | if (lastIndex < normalized.length) { 129 | visualLength += normalized.length - lastIndex; 130 | } 131 | 132 | // Reset regex lastIndex 133 | EMOJI_REGEX.lastIndex = 0; 134 | 135 | // Count short characters efficiently 136 | const shortCharCount = countShortCharactersHelper( 137 | text, 138 | customShortCharacters 139 | ); 140 | 141 | // Count long characters efficiently 142 | let longCharCount = 0; 143 | const customLongSet = 144 | customLongCharacters.length > 0 ? new Set(customLongCharacters) : null; 145 | 146 | for (const char of text) { 147 | if (customLongSet?.has(char) || LONG_CHARACTERS.has(char)) { 148 | longCharCount++; 149 | } 150 | } 151 | 152 | return { 153 | visualLength, 154 | shortCharCount, 155 | emojiCount, 156 | longCharCount, 157 | }; 158 | } 159 | 160 | /** 161 | * Slice a string based on visual position (handles emojis correctly) 162 | * @param text - The string to slice 163 | * @param start - Start visual position (inclusive), can be negative 164 | * @param end - End visual position (exclusive), can be negative or undefined 165 | * @returns The sliced string based on visual positions 166 | */ 167 | export function visualSliceHelper( 168 | text: string, 169 | start: number = 0, 170 | end?: number 171 | ): string { 172 | // Early return for empty strings 173 | if (!text) return ""; 174 | 175 | // Reset regex lastIndex to ensure clean state 176 | SIMPLE_EMOJI_REGEX.lastIndex = 0; 177 | 178 | const segments: string[] = []; 179 | let lastIndex = 0; 180 | let match; 181 | 182 | // Find all emojis and split text into segments using compiled regex 183 | while ((match = SIMPLE_EMOJI_REGEX.exec(text)) !== null) { 184 | // Add regular characters before emoji 185 | if (match.index > lastIndex) { 186 | const regularText = text.slice(lastIndex, match.index); 187 | // Split regular text into individual characters 188 | for (const char of regularText) { 189 | segments.push(char); 190 | } 191 | } 192 | 193 | // Add emoji as single segment 194 | segments.push(match[0]); 195 | lastIndex = SIMPLE_EMOJI_REGEX.lastIndex; 196 | } 197 | 198 | // Add remaining regular characters 199 | if (lastIndex < text.length) { 200 | const remainingText = text.slice(lastIndex); 201 | for (const char of remainingText) { 202 | segments.push(char); 203 | } 204 | } 205 | 206 | // Reset regex lastIndex after use 207 | SIMPLE_EMOJI_REGEX.lastIndex = 0; 208 | 209 | // Handle negative values like JavaScript's native slice 210 | const totalLength = segments.length; 211 | 212 | // Early return if start is beyond length 213 | if (start >= totalLength) return ""; 214 | 215 | // Convert negative start to positive 216 | let normalizedStart = start < 0 ? Math.max(0, totalLength + start) : start; 217 | 218 | // Convert negative end to positive, or use totalLength if undefined 219 | let normalizedEnd: number; 220 | if (end === undefined) { 221 | normalizedEnd = totalLength; 222 | } else if (end < 0) { 223 | normalizedEnd = Math.max(0, totalLength + end); 224 | } else { 225 | normalizedEnd = end; 226 | } 227 | 228 | // Ensure start and end are within bounds 229 | normalizedStart = Math.max(0, Math.min(normalizedStart, totalLength)); 230 | normalizedEnd = Math.max(0, Math.min(normalizedEnd, totalLength)); 231 | 232 | // If start >= end, return empty string 233 | if (normalizedStart >= normalizedEnd) { 234 | return ""; 235 | } 236 | 237 | // Slice based on normalized positions 238 | return segments.slice(normalizedStart, normalizedEnd).join(""); 239 | } 240 | 241 | /** 242 | * Calculate the slice position from the end of string to remove width >= targetWidth 243 | * @param text - The string to analyze 244 | * @param charWidth - Width of a normal character 245 | * @param targetWidth - Width that needs to be removed 246 | * @param isMonospaced - Whether the font is monospaced (all characters have equal width) 247 | * @param customShortCharacters - Custom array of characters with short width (0.5x) 248 | * @param customLongCharacters - Custom array of characters with long width (1.5x) 249 | * @returns The slice position from the end (negative value for slice) 250 | */ 251 | export function calculateSlicePositionHelper( 252 | text: string, 253 | charWidth: number, 254 | targetWidth: number, 255 | isMonospaced: boolean = false, 256 | customShortCharacters: string[] = [], 257 | customLongCharacters: string[] = [] 258 | ): number { 259 | // Early return for empty strings or zero target width 260 | if (!text || targetWidth <= 0) return 0; 261 | 262 | const normalized = getNormalizedString(text); 263 | 264 | // For monospaced fonts, we still need to handle emojis specially 265 | if (isMonospaced) { 266 | // Reset regex lastIndex to ensure clean state 267 | EMOJI_REGEX.lastIndex = 0; 268 | 269 | // Calculate from the end without creating segments array 270 | let accumulatedWidth = 0; 271 | let slicePosition = 0; 272 | let totalLength = 0; 273 | 274 | // First pass: calculate total visual length 275 | let lastIndex = 0; 276 | let match; 277 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 278 | // Add regular characters count before emoji 279 | if (match.index > lastIndex) { 280 | totalLength += match.index - lastIndex; 281 | } 282 | // Add emoji as single visual unit 283 | totalLength++; 284 | lastIndex = EMOJI_REGEX.lastIndex; 285 | } 286 | // Add remaining regular characters 287 | if (lastIndex < normalized.length) { 288 | totalLength += normalized.length - lastIndex; 289 | } 290 | 291 | // Reset regex for second pass 292 | EMOJI_REGEX.lastIndex = 0; 293 | 294 | // Second pass: calculate slice position from end 295 | const emojiPositions = new Map(); 296 | lastIndex = 0; 297 | let visualPos = 0; 298 | 299 | // Mark emoji positions 300 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 301 | // Add regular characters positions 302 | while (lastIndex < match.index) { 303 | visualPos++; 304 | lastIndex++; 305 | } 306 | // Mark emoji position 307 | emojiPositions.set(visualPos, true); 308 | visualPos++; 309 | lastIndex = EMOJI_REGEX.lastIndex; 310 | } 311 | 312 | // Calculate from the end 313 | for (let i = totalLength - 1; i >= 0; i--) { 314 | const isEmoji = emojiPositions.has(i); 315 | accumulatedWidth += isEmoji ? charWidth * 2 : charWidth; 316 | slicePosition++; 317 | 318 | if (accumulatedWidth >= targetWidth) { 319 | // Check for trailing space optimization 320 | if (i > 0 && !emojiPositions.has(i - 1)) { 321 | // Get the actual character at this position 322 | let charIndex = 0; 323 | let visualIndex = 0; 324 | EMOJI_REGEX.lastIndex = 0; 325 | lastIndex = 0; 326 | 327 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 328 | if (match.index > lastIndex) { 329 | const regularChars = match.index - lastIndex; 330 | if (visualIndex + regularChars > i - 1) { 331 | charIndex = lastIndex + (i - 1 - visualIndex); 332 | break; 333 | } 334 | visualIndex += regularChars; 335 | charIndex = match.index; 336 | } 337 | if (visualIndex === i - 1) { 338 | charIndex = match.index; 339 | break; 340 | } 341 | visualIndex++; 342 | lastIndex = EMOJI_REGEX.lastIndex; 343 | charIndex = lastIndex; 344 | } 345 | 346 | if (charIndex < normalized.length && normalized[charIndex] === " ") { 347 | slicePosition++; 348 | } 349 | } 350 | 351 | EMOJI_REGEX.lastIndex = 0; 352 | return -slicePosition; 353 | } 354 | } 355 | 356 | EMOJI_REGEX.lastIndex = 0; 357 | return -totalLength; 358 | } 359 | 360 | // For proportional fonts, use optimized logic without creating segments array 361 | EMOJI_REGEX.lastIndex = 0; 362 | 363 | // Merge custom and default character sets for optimal performance 364 | const allShortCharacters = 365 | customShortCharacters.length > 0 366 | ? new Set([...customShortCharacters, ...SHORT_CHARACTERS]) 367 | : SHORT_CHARACTERS; 368 | const allLongCharacters = 369 | customLongCharacters.length > 0 370 | ? new Set([...customLongCharacters, ...LONG_CHARACTERS]) 371 | : LONG_CHARACTERS; 372 | 373 | // Helper function to get character width 374 | const getCharWidth = (char: string): number => { 375 | // Space characters have 0.5x width 376 | if (char === " ") return charWidth * 0.5; 377 | 378 | // Check merged character sets (single lookup each) 379 | if (allShortCharacters.has(char)) return charWidth * 0.5; 380 | if (allLongCharacters.has(char)) return charWidth * 1.5; 381 | 382 | // Regular characters have 1x width 383 | return charWidth; 384 | }; 385 | 386 | // Calculate total visual length and build position map 387 | let totalVisualLength = 0; 388 | const emojiPositions = new Map(); 389 | let lastIndex = 0; 390 | let match; 391 | let visualPos = 0; 392 | 393 | // Process emojis and mark their positions 394 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 395 | // Add regular characters before emoji 396 | while (lastIndex < match.index) { 397 | totalVisualLength++; 398 | visualPos++; 399 | lastIndex++; 400 | } 401 | 402 | // Mark emoji position 403 | emojiPositions.set(visualPos, true); 404 | totalVisualLength++; 405 | visualPos++; 406 | lastIndex = EMOJI_REGEX.lastIndex; 407 | } 408 | 409 | // Add remaining regular characters 410 | while (lastIndex < normalized.length) { 411 | totalVisualLength++; 412 | lastIndex++; 413 | } 414 | 415 | // Reset regex 416 | EMOJI_REGEX.lastIndex = 0; 417 | 418 | // Calculate from the end 419 | let accumulatedWidth = 0; 420 | let slicePosition = 0; 421 | 422 | for (let i = totalVisualLength - 1; i >= 0; i--) { 423 | let width: number; 424 | 425 | if (emojiPositions.has(i)) { 426 | // This is an emoji position 427 | width = charWidth * 2; 428 | } else { 429 | // Get the actual character at this visual position 430 | let charIndex = 0; 431 | let currentVisualPos = 0; 432 | lastIndex = 0; 433 | 434 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 435 | // Process regular characters before emoji 436 | while (lastIndex < match.index && currentVisualPos <= i) { 437 | if (currentVisualPos === i) { 438 | charIndex = lastIndex; 439 | break; 440 | } 441 | currentVisualPos++; 442 | lastIndex++; 443 | } 444 | 445 | if (currentVisualPos === i) { 446 | charIndex = lastIndex; 447 | break; 448 | } 449 | 450 | // Skip emoji 451 | if (currentVisualPos === i) { 452 | // This shouldn't happen as we already checked emojiPositions 453 | break; 454 | } 455 | currentVisualPos++; 456 | lastIndex = EMOJI_REGEX.lastIndex; 457 | } 458 | 459 | // Handle remaining characters 460 | while (lastIndex < normalized.length && currentVisualPos <= i) { 461 | if (currentVisualPos === i) { 462 | charIndex = lastIndex; 463 | break; 464 | } 465 | currentVisualPos++; 466 | lastIndex++; 467 | } 468 | 469 | width = getCharWidth(normalized[charIndex] || ""); 470 | } 471 | 472 | accumulatedWidth += width; 473 | slicePosition++; 474 | 475 | if (accumulatedWidth >= targetWidth) { 476 | // Check for trailing space optimization 477 | if (i > 0 && !emojiPositions.has(i - 1)) { 478 | // Get character at position i-1 479 | let charIndex = 0; 480 | let currentVisualPos = 0; 481 | lastIndex = 0; 482 | EMOJI_REGEX.lastIndex = 0; 483 | 484 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 485 | while (lastIndex < match.index && currentVisualPos <= i - 1) { 486 | if (currentVisualPos === i - 1) { 487 | charIndex = lastIndex; 488 | break; 489 | } 490 | currentVisualPos++; 491 | lastIndex++; 492 | } 493 | if (currentVisualPos === i - 1) break; 494 | currentVisualPos++; 495 | lastIndex = EMOJI_REGEX.lastIndex; 496 | } 497 | 498 | while (lastIndex < normalized.length && currentVisualPos <= i - 1) { 499 | if (currentVisualPos === i - 1) { 500 | charIndex = lastIndex; 501 | break; 502 | } 503 | currentVisualPos++; 504 | lastIndex++; 505 | } 506 | 507 | if (normalized[charIndex] === " ") { 508 | slicePosition++; 509 | } 510 | } 511 | 512 | EMOJI_REGEX.lastIndex = 0; 513 | return -slicePosition; 514 | } 515 | } 516 | 517 | EMOJI_REGEX.lastIndex = 0; 518 | return -totalVisualLength; 519 | } 520 | 521 | /** 522 | * Calculate the total visual width of a string 523 | * @param text - The string to analyze 524 | * @param charWidth - Width of a normal character 525 | * @param isMonospaced - Whether the font is monospaced (all characters have equal width) 526 | * @param customShortCharacters - Custom array of characters with short width (0.5x) 527 | * @param customLongCharacters - Custom array of characters with long width (1.5x) 528 | * @returns The total visual width of the string 529 | */ 530 | export function calculateStringWidthHelper( 531 | text: string, 532 | charWidth: number, 533 | isMonospaced: boolean = false, 534 | customShortCharacters: string[] = [], 535 | customLongCharacters: string[] = [] 536 | ): number { 537 | // Early return for empty strings 538 | if (!text) return 0; 539 | 540 | const normalized = getNormalizedString(text); 541 | 542 | // For monospaced fonts, we still need to handle emojis specially 543 | if (isMonospaced) { 544 | // Reset regex lastIndex to ensure clean state 545 | EMOJI_REGEX.lastIndex = 0; 546 | 547 | let totalWidth = 0; 548 | let lastIndex = 0; 549 | let match; 550 | 551 | // Process emojis first using compiled regex 552 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 553 | // Add width of regular characters before emoji (all have same width in monospaced) 554 | if (match.index > lastIndex) { 555 | totalWidth += (match.index - lastIndex) * charWidth; 556 | } 557 | 558 | // Add emoji width (2 * charWidth even in monospaced) 559 | totalWidth += charWidth * 2; 560 | lastIndex = EMOJI_REGEX.lastIndex; 561 | } 562 | 563 | // Add width of remaining regular characters 564 | if (lastIndex < normalized.length) { 565 | totalWidth += (normalized.length - lastIndex) * charWidth; 566 | } 567 | 568 | // Reset regex lastIndex after use 569 | EMOJI_REGEX.lastIndex = 0; 570 | return totalWidth; 571 | } 572 | 573 | // For proportional fonts, use optimized logic 574 | EMOJI_REGEX.lastIndex = 0; 575 | 576 | // Merge custom and default character sets for optimal performance 577 | const allShortCharacters = 578 | customShortCharacters.length > 0 579 | ? new Set([...customShortCharacters, ...SHORT_CHARACTERS]) 580 | : SHORT_CHARACTERS; 581 | const allLongCharacters = 582 | customLongCharacters.length > 0 583 | ? new Set([...customLongCharacters, ...LONG_CHARACTERS]) 584 | : LONG_CHARACTERS; 585 | 586 | // Helper function to get character width (reuse from calculateSlicePositionHelper) 587 | const getCharWidth = (char: string): number => { 588 | // Space characters have 0.5x width 589 | if (char === " ") return charWidth * 0.5; 590 | 591 | // Check merged character sets (single lookup each) 592 | if (allShortCharacters.has(char)) return charWidth * 0.5; 593 | if (allLongCharacters.has(char)) return charWidth * 1.5; 594 | 595 | // Regular characters have 1x width 596 | return charWidth; 597 | }; 598 | 599 | let totalWidth = 0; 600 | let lastIndex = 0; 601 | let match; 602 | 603 | // Process emojis first using compiled regex 604 | while ((match = EMOJI_REGEX.exec(normalized)) !== null) { 605 | // Add width of regular characters before emoji 606 | if (match.index > lastIndex) { 607 | for (let i = lastIndex; i < match.index; i++) { 608 | totalWidth += getCharWidth(normalized[i]); 609 | } 610 | } 611 | 612 | // Add emoji width (2 * charWidth) 613 | totalWidth += charWidth * 2; 614 | lastIndex = EMOJI_REGEX.lastIndex; 615 | } 616 | 617 | // Add width of remaining regular characters 618 | if (lastIndex < normalized.length) { 619 | for (let i = lastIndex; i < normalized.length; i++) { 620 | totalWidth += getCharWidth(normalized[i]); 621 | } 622 | } 623 | 624 | // Reset regex lastIndex after use 625 | EMOJI_REGEX.lastIndex = 0; 626 | return totalWidth; 627 | } 628 | 629 | export function balanceDiffHelper( 630 | numOfEmojis: number = 0, 631 | numOfShortCharacters: number = 0, 632 | numOfLongCharacters: number = 0 633 | ) { 634 | return numOfEmojis + 0.5 * numOfLongCharacters - 0.5 * numOfShortCharacters; 635 | } 636 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ampproject/remapping@^2.2.0": 6 | version "2.3.0" 7 | resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz" 8 | integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== 9 | dependencies: 10 | "@jridgewell/gen-mapping" "^0.3.5" 11 | "@jridgewell/trace-mapping" "^0.3.24" 12 | 13 | "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7", "@babel/code-frame@^7.27.1": 14 | version "7.27.1" 15 | resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz" 16 | integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== 17 | dependencies: 18 | "@babel/helper-validator-identifier" "^7.27.1" 19 | js-tokens "^4.0.0" 20 | picocolors "^1.1.1" 21 | 22 | "@babel/compat-data@^7.27.2": 23 | version "7.27.2" 24 | resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz" 25 | integrity sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ== 26 | 27 | "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.25.2": 28 | version "7.27.1" 29 | resolved "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz" 30 | integrity sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ== 31 | dependencies: 32 | "@ampproject/remapping" "^2.2.0" 33 | "@babel/code-frame" "^7.27.1" 34 | "@babel/generator" "^7.27.1" 35 | "@babel/helper-compilation-targets" "^7.27.1" 36 | "@babel/helper-module-transforms" "^7.27.1" 37 | "@babel/helpers" "^7.27.1" 38 | "@babel/parser" "^7.27.1" 39 | "@babel/template" "^7.27.1" 40 | "@babel/traverse" "^7.27.1" 41 | "@babel/types" "^7.27.1" 42 | convert-source-map "^2.0.0" 43 | debug "^4.1.0" 44 | gensync "^1.0.0-beta.2" 45 | json5 "^2.2.3" 46 | semver "^6.3.1" 47 | 48 | "@babel/generator@^7.25.0", "@babel/generator@^7.27.1": 49 | version "7.27.1" 50 | resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz" 51 | integrity sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w== 52 | dependencies: 53 | "@babel/parser" "^7.27.1" 54 | "@babel/types" "^7.27.1" 55 | "@jridgewell/gen-mapping" "^0.3.5" 56 | "@jridgewell/trace-mapping" "^0.3.25" 57 | jsesc "^3.0.2" 58 | 59 | "@babel/helper-compilation-targets@^7.27.1": 60 | version "7.27.2" 61 | resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz" 62 | integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== 63 | dependencies: 64 | "@babel/compat-data" "^7.27.2" 65 | "@babel/helper-validator-option" "^7.27.1" 66 | browserslist "^4.24.0" 67 | lru-cache "^5.1.1" 68 | semver "^6.3.1" 69 | 70 | "@babel/helper-module-imports@^7.27.1": 71 | version "7.27.1" 72 | resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz" 73 | integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== 74 | dependencies: 75 | "@babel/traverse" "^7.27.1" 76 | "@babel/types" "^7.27.1" 77 | 78 | "@babel/helper-module-transforms@^7.27.1": 79 | version "7.27.1" 80 | resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz" 81 | integrity sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g== 82 | dependencies: 83 | "@babel/helper-module-imports" "^7.27.1" 84 | "@babel/helper-validator-identifier" "^7.27.1" 85 | "@babel/traverse" "^7.27.1" 86 | 87 | "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": 88 | version "7.27.1" 89 | resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" 90 | integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== 91 | 92 | "@babel/helper-string-parser@^7.27.1": 93 | version "7.27.1" 94 | resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" 95 | integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== 96 | 97 | "@babel/helper-validator-identifier@^7.27.1": 98 | version "7.27.1" 99 | resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz" 100 | integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== 101 | 102 | "@babel/helper-validator-option@^7.27.1": 103 | version "7.27.1" 104 | resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" 105 | integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== 106 | 107 | "@babel/helpers@^7.27.1": 108 | version "7.27.1" 109 | resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz" 110 | integrity sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ== 111 | dependencies: 112 | "@babel/template" "^7.27.1" 113 | "@babel/types" "^7.27.1" 114 | 115 | "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.25.3", "@babel/parser@^7.27.1", "@babel/parser@^7.27.2": 116 | version "7.27.2" 117 | resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz" 118 | integrity sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw== 119 | dependencies: 120 | "@babel/types" "^7.27.1" 121 | 122 | "@babel/plugin-syntax-async-generators@^7.8.4": 123 | version "7.8.4" 124 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" 125 | integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== 126 | dependencies: 127 | "@babel/helper-plugin-utils" "^7.8.0" 128 | 129 | "@babel/plugin-syntax-bigint@^7.8.3": 130 | version "7.8.3" 131 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" 132 | integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== 133 | dependencies: 134 | "@babel/helper-plugin-utils" "^7.8.0" 135 | 136 | "@babel/plugin-syntax-class-properties@^7.12.13": 137 | version "7.12.13" 138 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" 139 | integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== 140 | dependencies: 141 | "@babel/helper-plugin-utils" "^7.12.13" 142 | 143 | "@babel/plugin-syntax-class-static-block@^7.14.5": 144 | version "7.14.5" 145 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" 146 | integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== 147 | dependencies: 148 | "@babel/helper-plugin-utils" "^7.14.5" 149 | 150 | "@babel/plugin-syntax-import-attributes@^7.24.7": 151 | version "7.27.1" 152 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz" 153 | integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== 154 | dependencies: 155 | "@babel/helper-plugin-utils" "^7.27.1" 156 | 157 | "@babel/plugin-syntax-import-meta@^7.10.4": 158 | version "7.10.4" 159 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" 160 | integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== 161 | dependencies: 162 | "@babel/helper-plugin-utils" "^7.10.4" 163 | 164 | "@babel/plugin-syntax-json-strings@^7.8.3": 165 | version "7.8.3" 166 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" 167 | integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== 168 | dependencies: 169 | "@babel/helper-plugin-utils" "^7.8.0" 170 | 171 | "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": 172 | version "7.10.4" 173 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" 174 | integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== 175 | dependencies: 176 | "@babel/helper-plugin-utils" "^7.10.4" 177 | 178 | "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": 179 | version "7.8.3" 180 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" 181 | integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== 182 | dependencies: 183 | "@babel/helper-plugin-utils" "^7.8.0" 184 | 185 | "@babel/plugin-syntax-numeric-separator@^7.10.4": 186 | version "7.10.4" 187 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" 188 | integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== 189 | dependencies: 190 | "@babel/helper-plugin-utils" "^7.10.4" 191 | 192 | "@babel/plugin-syntax-object-rest-spread@^7.8.3": 193 | version "7.8.3" 194 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" 195 | integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== 196 | dependencies: 197 | "@babel/helper-plugin-utils" "^7.8.0" 198 | 199 | "@babel/plugin-syntax-optional-catch-binding@^7.8.3": 200 | version "7.8.3" 201 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" 202 | integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== 203 | dependencies: 204 | "@babel/helper-plugin-utils" "^7.8.0" 205 | 206 | "@babel/plugin-syntax-optional-chaining@^7.8.3": 207 | version "7.8.3" 208 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" 209 | integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== 210 | dependencies: 211 | "@babel/helper-plugin-utils" "^7.8.0" 212 | 213 | "@babel/plugin-syntax-private-property-in-object@^7.14.5": 214 | version "7.14.5" 215 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" 216 | integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== 217 | dependencies: 218 | "@babel/helper-plugin-utils" "^7.14.5" 219 | 220 | "@babel/plugin-syntax-top-level-await@^7.14.5": 221 | version "7.14.5" 222 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" 223 | integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== 224 | dependencies: 225 | "@babel/helper-plugin-utils" "^7.14.5" 226 | 227 | "@babel/runtime@^7.25.0": 228 | version "7.27.1" 229 | resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz" 230 | integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog== 231 | 232 | "@babel/template@^7.25.0", "@babel/template@^7.27.1", "@babel/template@^7.3.3": 233 | version "7.27.2" 234 | resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz" 235 | integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== 236 | dependencies: 237 | "@babel/code-frame" "^7.27.1" 238 | "@babel/parser" "^7.27.2" 239 | "@babel/types" "^7.27.1" 240 | 241 | "@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3": 242 | version "7.27.1" 243 | resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz" 244 | integrity sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg== 245 | dependencies: 246 | "@babel/code-frame" "^7.27.1" 247 | "@babel/generator" "^7.27.1" 248 | "@babel/parser" "^7.27.1" 249 | "@babel/template" "^7.27.1" 250 | "@babel/types" "^7.27.1" 251 | debug "^4.3.1" 252 | globals "^11.1.0" 253 | 254 | "@babel/traverse@^7.25.3", "@babel/traverse@^7.27.1": 255 | version "7.27.1" 256 | resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz" 257 | integrity sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg== 258 | dependencies: 259 | "@babel/code-frame" "^7.27.1" 260 | "@babel/generator" "^7.27.1" 261 | "@babel/parser" "^7.27.1" 262 | "@babel/template" "^7.27.1" 263 | "@babel/types" "^7.27.1" 264 | debug "^4.3.1" 265 | globals "^11.1.0" 266 | 267 | "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.2", "@babel/types@^7.27.1", "@babel/types@^7.3.3": 268 | version "7.27.1" 269 | resolved "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz" 270 | integrity sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q== 271 | dependencies: 272 | "@babel/helper-string-parser" "^7.27.1" 273 | "@babel/helper-validator-identifier" "^7.27.1" 274 | 275 | "@cspotcode/source-map-support@^0.8.0": 276 | version "0.8.1" 277 | resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" 278 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 279 | dependencies: 280 | "@jridgewell/trace-mapping" "0.3.9" 281 | 282 | "@isaacs/ttlcache@^1.4.1": 283 | version "1.4.1" 284 | resolved "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz" 285 | integrity sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA== 286 | 287 | "@istanbuljs/load-nyc-config@^1.0.0": 288 | version "1.1.0" 289 | resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" 290 | integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== 291 | dependencies: 292 | camelcase "^5.3.1" 293 | find-up "^4.1.0" 294 | get-package-type "^0.1.0" 295 | js-yaml "^3.13.1" 296 | resolve-from "^5.0.0" 297 | 298 | "@istanbuljs/schema@^0.1.2": 299 | version "0.1.3" 300 | resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" 301 | integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== 302 | 303 | "@jest/create-cache-key-function@^29.7.0": 304 | version "29.7.0" 305 | resolved "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz" 306 | integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA== 307 | dependencies: 308 | "@jest/types" "^29.6.3" 309 | 310 | "@jest/environment@^29.7.0": 311 | version "29.7.0" 312 | resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz" 313 | integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== 314 | dependencies: 315 | "@jest/fake-timers" "^29.7.0" 316 | "@jest/types" "^29.6.3" 317 | "@types/node" "*" 318 | jest-mock "^29.7.0" 319 | 320 | "@jest/fake-timers@^29.7.0": 321 | version "29.7.0" 322 | resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" 323 | integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== 324 | dependencies: 325 | "@jest/types" "^29.6.3" 326 | "@sinonjs/fake-timers" "^10.0.2" 327 | "@types/node" "*" 328 | jest-message-util "^29.7.0" 329 | jest-mock "^29.7.0" 330 | jest-util "^29.7.0" 331 | 332 | "@jest/schemas@^29.6.3": 333 | version "29.6.3" 334 | resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" 335 | integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== 336 | dependencies: 337 | "@sinclair/typebox" "^0.27.8" 338 | 339 | "@jest/transform@^29.7.0": 340 | version "29.7.0" 341 | resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" 342 | integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== 343 | dependencies: 344 | "@babel/core" "^7.11.6" 345 | "@jest/types" "^29.6.3" 346 | "@jridgewell/trace-mapping" "^0.3.18" 347 | babel-plugin-istanbul "^6.1.1" 348 | chalk "^4.0.0" 349 | convert-source-map "^2.0.0" 350 | fast-json-stable-stringify "^2.1.0" 351 | graceful-fs "^4.2.9" 352 | jest-haste-map "^29.7.0" 353 | jest-regex-util "^29.6.3" 354 | jest-util "^29.7.0" 355 | micromatch "^4.0.4" 356 | pirates "^4.0.4" 357 | slash "^3.0.0" 358 | write-file-atomic "^4.0.2" 359 | 360 | "@jest/types@^29.6.3": 361 | version "29.6.3" 362 | resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" 363 | integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== 364 | dependencies: 365 | "@jest/schemas" "^29.6.3" 366 | "@types/istanbul-lib-coverage" "^2.0.0" 367 | "@types/istanbul-reports" "^3.0.0" 368 | "@types/node" "*" 369 | "@types/yargs" "^17.0.8" 370 | chalk "^4.0.0" 371 | 372 | "@jridgewell/gen-mapping@^0.3.5": 373 | version "0.3.8" 374 | resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz" 375 | integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== 376 | dependencies: 377 | "@jridgewell/set-array" "^1.2.1" 378 | "@jridgewell/sourcemap-codec" "^1.4.10" 379 | "@jridgewell/trace-mapping" "^0.3.24" 380 | 381 | "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": 382 | version "3.1.2" 383 | resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" 384 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== 385 | 386 | "@jridgewell/set-array@^1.2.1": 387 | version "1.2.1" 388 | resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz" 389 | integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== 390 | 391 | "@jridgewell/source-map@^0.3.3": 392 | version "0.3.6" 393 | resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz" 394 | integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== 395 | dependencies: 396 | "@jridgewell/gen-mapping" "^0.3.5" 397 | "@jridgewell/trace-mapping" "^0.3.25" 398 | 399 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": 400 | version "1.5.0" 401 | resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" 402 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== 403 | 404 | "@jridgewell/trace-mapping@0.3.9": 405 | version "0.3.9" 406 | resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" 407 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 408 | dependencies: 409 | "@jridgewell/resolve-uri" "^3.0.3" 410 | "@jridgewell/sourcemap-codec" "^1.4.10" 411 | 412 | "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": 413 | version "0.3.25" 414 | resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" 415 | integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== 416 | dependencies: 417 | "@jridgewell/resolve-uri" "^3.1.0" 418 | "@jridgewell/sourcemap-codec" "^1.4.14" 419 | 420 | "@react-native/assets-registry@0.79.2": 421 | version "0.79.2" 422 | resolved "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.79.2.tgz" 423 | integrity sha512-5h2Z7/+/HL/0h88s0JHOdRCW4CXMCJoROxqzHqxdrjGL6EBD1DdaB4ZqkCOEVSW4Vjhir5Qb97C8i/MPWEYPtg== 424 | 425 | "@react-native/codegen@0.79.2": 426 | version "0.79.2" 427 | resolved "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.79.2.tgz" 428 | integrity sha512-8JTlGLuLi1p8Jx2N/enwwEd7/2CfrqJpv90Cp77QLRX3VHF2hdyavRIxAmXMwN95k+Me7CUuPtqn2X3IBXOWYg== 429 | dependencies: 430 | glob "^7.1.1" 431 | hermes-parser "0.25.1" 432 | invariant "^2.2.4" 433 | nullthrows "^1.1.1" 434 | yargs "^17.6.2" 435 | 436 | "@react-native/community-cli-plugin@0.79.2": 437 | version "0.79.2" 438 | resolved "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.79.2.tgz" 439 | integrity sha512-E+YEY2dL+68HyR2iahsZdyBKBUi9QyPyaN9vsnda1jNgCjNpSPk2yAF5cXsho+zKK5ZQna3JSeE1Kbi2IfGJbw== 440 | dependencies: 441 | "@react-native/dev-middleware" "0.79.2" 442 | chalk "^4.0.0" 443 | debug "^2.2.0" 444 | invariant "^2.2.4" 445 | metro "^0.82.0" 446 | metro-config "^0.82.0" 447 | metro-core "^0.82.0" 448 | semver "^7.1.3" 449 | 450 | "@react-native/debugger-frontend@0.79.2": 451 | version "0.79.2" 452 | resolved "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.79.2.tgz" 453 | integrity sha512-cGmC7X6kju76DopSBNc+PRAEetbd7TWF9J9o84hOp/xL3ahxR2kuxJy0oJX8Eg8oehhGGEXTuMKHzNa3rDBeSg== 454 | 455 | "@react-native/dev-middleware@0.79.2": 456 | version "0.79.2" 457 | resolved "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.79.2.tgz" 458 | integrity sha512-9q4CpkklsAs1L0Bw8XYCoqqyBSrfRALGEw4/r0EkR38Y/6fVfNfdsjSns0pTLO6h0VpxswK34L/hm4uK3MoLHw== 459 | dependencies: 460 | "@isaacs/ttlcache" "^1.4.1" 461 | "@react-native/debugger-frontend" "0.79.2" 462 | chrome-launcher "^0.15.2" 463 | chromium-edge-launcher "^0.2.0" 464 | connect "^3.6.5" 465 | debug "^2.2.0" 466 | invariant "^2.2.4" 467 | nullthrows "^1.1.1" 468 | open "^7.0.3" 469 | serve-static "^1.16.2" 470 | ws "^6.2.3" 471 | 472 | "@react-native/gradle-plugin@0.79.2": 473 | version "0.79.2" 474 | resolved "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.79.2.tgz" 475 | integrity sha512-6MJFemrwR0bOT0QM+2BxX9k3/pvZQNmJ3Js5pF/6owsA0cUDiCO57otiEU8Fz+UywWEzn1FoQfOfQ8vt2GYmoA== 476 | 477 | "@react-native/js-polyfills@0.79.2": 478 | version "0.79.2" 479 | resolved "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.79.2.tgz" 480 | integrity sha512-IaY87Ckd4GTPMkO1/Fe8fC1IgIx3vc3q9Tyt/6qS3Mtk9nC0x9q4kSR5t+HHq0/MuvGtu8HpdxXGy5wLaM+zUw== 481 | 482 | "@react-native/normalize-colors@0.79.2": 483 | version "0.79.2" 484 | resolved "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.79.2.tgz" 485 | integrity sha512-+b+GNrupWrWw1okHnEENz63j7NSMqhKeFMOyzYLBwKcprG8fqJQhDIGXfizKdxeIa5NnGSAevKL1Ev1zJ56X8w== 486 | 487 | "@react-native/virtualized-lists@0.79.2": 488 | version "0.79.2" 489 | resolved "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.79.2.tgz" 490 | integrity sha512-9G6ROJeP+rdw9Bvr5ruOlag11ET7j1z/En1riFFNo6W3xZvJY+alCuH1ttm12y9+zBm4n8jwCk4lGhjYaV4dKw== 491 | dependencies: 492 | invariant "^2.2.4" 493 | nullthrows "^1.1.1" 494 | 495 | "@sinclair/typebox@^0.27.8": 496 | version "0.27.8" 497 | resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" 498 | integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== 499 | 500 | "@sinonjs/commons@^3.0.0": 501 | version "3.0.1" 502 | resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz" 503 | integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== 504 | dependencies: 505 | type-detect "4.0.8" 506 | 507 | "@sinonjs/fake-timers@^10.0.2": 508 | version "10.3.0" 509 | resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz" 510 | integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== 511 | dependencies: 512 | "@sinonjs/commons" "^3.0.0" 513 | 514 | "@tsconfig/node10@^1.0.7": 515 | version "1.0.11" 516 | resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz" 517 | integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== 518 | 519 | "@tsconfig/node12@^1.0.7": 520 | version "1.0.11" 521 | resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" 522 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 523 | 524 | "@tsconfig/node14@^1.0.0": 525 | version "1.0.3" 526 | resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" 527 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 528 | 529 | "@tsconfig/node16@^1.0.2": 530 | version "1.0.4" 531 | resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz" 532 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 533 | 534 | "@types/babel__core@^7.1.14": 535 | version "7.20.5" 536 | resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" 537 | integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== 538 | dependencies: 539 | "@babel/parser" "^7.20.7" 540 | "@babel/types" "^7.20.7" 541 | "@types/babel__generator" "*" 542 | "@types/babel__template" "*" 543 | "@types/babel__traverse" "*" 544 | 545 | "@types/babel__generator@*": 546 | version "7.27.0" 547 | resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz" 548 | integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== 549 | dependencies: 550 | "@babel/types" "^7.0.0" 551 | 552 | "@types/babel__template@*": 553 | version "7.4.4" 554 | resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" 555 | integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== 556 | dependencies: 557 | "@babel/parser" "^7.1.0" 558 | "@babel/types" "^7.0.0" 559 | 560 | "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": 561 | version "7.20.7" 562 | resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz" 563 | integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== 564 | dependencies: 565 | "@babel/types" "^7.20.7" 566 | 567 | "@types/graceful-fs@^4.1.3": 568 | version "4.1.9" 569 | resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" 570 | integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== 571 | dependencies: 572 | "@types/node" "*" 573 | 574 | "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": 575 | version "2.0.6" 576 | resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" 577 | integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== 578 | 579 | "@types/istanbul-lib-report@*": 580 | version "3.0.3" 581 | resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz" 582 | integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== 583 | dependencies: 584 | "@types/istanbul-lib-coverage" "*" 585 | 586 | "@types/istanbul-reports@^3.0.0": 587 | version "3.0.4" 588 | resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz" 589 | integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== 590 | dependencies: 591 | "@types/istanbul-lib-report" "*" 592 | 593 | "@types/node@*": 594 | version "22.15.17" 595 | resolved "https://registry.npmjs.org/@types/node/-/node-22.15.17.tgz" 596 | integrity sha512-wIX2aSZL5FE+MR0JlvF87BNVrtFWf6AE6rxSE9X7OwnVvoyCQjpzSRJ+M87se/4QCkCiebQAqrJ0y6fwIyi7nw== 597 | dependencies: 598 | undici-types "~6.21.0" 599 | 600 | "@types/react-native@^0.70.0": 601 | version "0.70.19" 602 | resolved "https://registry.npmjs.org/@types/react-native/-/react-native-0.70.19.tgz" 603 | integrity sha512-c6WbyCgWTBgKKMESj/8b4w+zWcZSsCforson7UdXtXMecG3MxCinYi6ihhrHVPyUrVzORsvEzK8zg32z4pK6Sg== 604 | dependencies: 605 | "@types/react" "*" 606 | 607 | "@types/react@*", "@types/react@^19.1.4": 608 | version "19.1.4" 609 | resolved "https://registry.npmjs.org/@types/react/-/react-19.1.4.tgz" 610 | integrity sha512-EB1yiiYdvySuIITtD5lhW4yPyJ31RkJkkDw794LaQYrxCSaQV/47y5o1FMC4zF9ZyjUjzJMZwbovEnT5yHTW6g== 611 | dependencies: 612 | csstype "^3.0.2" 613 | 614 | "@types/stack-utils@^2.0.0": 615 | version "2.0.3" 616 | resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" 617 | integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== 618 | 619 | "@types/yargs-parser@*": 620 | version "21.0.3" 621 | resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" 622 | integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== 623 | 624 | "@types/yargs@^17.0.8": 625 | version "17.0.33" 626 | resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz" 627 | integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== 628 | dependencies: 629 | "@types/yargs-parser" "*" 630 | 631 | abort-controller@^3.0.0: 632 | version "3.0.0" 633 | resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" 634 | integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== 635 | dependencies: 636 | event-target-shim "^5.0.0" 637 | 638 | accepts@^1.3.7: 639 | version "1.3.8" 640 | resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" 641 | integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== 642 | dependencies: 643 | mime-types "~2.1.34" 644 | negotiator "0.6.3" 645 | 646 | acorn-walk@^8.1.1: 647 | version "8.3.4" 648 | resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz" 649 | integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== 650 | dependencies: 651 | acorn "^8.11.0" 652 | 653 | acorn@^8.11.0, acorn@^8.4.1, acorn@^8.8.2: 654 | version "8.14.1" 655 | resolved "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz" 656 | integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== 657 | 658 | agent-base@^7.1.2: 659 | version "7.1.3" 660 | resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz" 661 | integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== 662 | 663 | anser@^1.4.9: 664 | version "1.4.10" 665 | resolved "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz" 666 | integrity sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww== 667 | 668 | ansi-regex@^5.0.0, ansi-regex@^5.0.1: 669 | version "5.0.1" 670 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" 671 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 672 | 673 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 674 | version "4.3.0" 675 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 676 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 677 | dependencies: 678 | color-convert "^2.0.1" 679 | 680 | ansi-styles@^5.0.0: 681 | version "5.2.0" 682 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" 683 | integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== 684 | 685 | anymatch@^3.0.3: 686 | version "3.1.3" 687 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" 688 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 689 | dependencies: 690 | normalize-path "^3.0.0" 691 | picomatch "^2.0.4" 692 | 693 | arg@^4.1.0: 694 | version "4.1.3" 695 | resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" 696 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 697 | 698 | argparse@^1.0.7: 699 | version "1.0.10" 700 | resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" 701 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 702 | dependencies: 703 | sprintf-js "~1.0.2" 704 | 705 | asap@~2.0.6: 706 | version "2.0.6" 707 | resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" 708 | integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== 709 | 710 | async-limiter@~1.0.0: 711 | version "1.0.1" 712 | resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" 713 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 714 | 715 | babel-jest@^29.7.0: 716 | version "29.7.0" 717 | resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" 718 | integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== 719 | dependencies: 720 | "@jest/transform" "^29.7.0" 721 | "@types/babel__core" "^7.1.14" 722 | babel-plugin-istanbul "^6.1.1" 723 | babel-preset-jest "^29.6.3" 724 | chalk "^4.0.0" 725 | graceful-fs "^4.2.9" 726 | slash "^3.0.0" 727 | 728 | babel-plugin-istanbul@^6.1.1: 729 | version "6.1.1" 730 | resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" 731 | integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== 732 | dependencies: 733 | "@babel/helper-plugin-utils" "^7.0.0" 734 | "@istanbuljs/load-nyc-config" "^1.0.0" 735 | "@istanbuljs/schema" "^0.1.2" 736 | istanbul-lib-instrument "^5.0.4" 737 | test-exclude "^6.0.0" 738 | 739 | babel-plugin-jest-hoist@^29.6.3: 740 | version "29.6.3" 741 | resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" 742 | integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== 743 | dependencies: 744 | "@babel/template" "^7.3.3" 745 | "@babel/types" "^7.3.3" 746 | "@types/babel__core" "^7.1.14" 747 | "@types/babel__traverse" "^7.0.6" 748 | 749 | babel-plugin-syntax-hermes-parser@0.25.1: 750 | version "0.25.1" 751 | resolved "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.25.1.tgz" 752 | integrity sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ== 753 | dependencies: 754 | hermes-parser "0.25.1" 755 | 756 | babel-preset-current-node-syntax@^1.0.0: 757 | version "1.1.0" 758 | resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz" 759 | integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== 760 | dependencies: 761 | "@babel/plugin-syntax-async-generators" "^7.8.4" 762 | "@babel/plugin-syntax-bigint" "^7.8.3" 763 | "@babel/plugin-syntax-class-properties" "^7.12.13" 764 | "@babel/plugin-syntax-class-static-block" "^7.14.5" 765 | "@babel/plugin-syntax-import-attributes" "^7.24.7" 766 | "@babel/plugin-syntax-import-meta" "^7.10.4" 767 | "@babel/plugin-syntax-json-strings" "^7.8.3" 768 | "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" 769 | "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" 770 | "@babel/plugin-syntax-numeric-separator" "^7.10.4" 771 | "@babel/plugin-syntax-object-rest-spread" "^7.8.3" 772 | "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" 773 | "@babel/plugin-syntax-optional-chaining" "^7.8.3" 774 | "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 775 | "@babel/plugin-syntax-top-level-await" "^7.14.5" 776 | 777 | babel-preset-jest@^29.6.3: 778 | version "29.6.3" 779 | resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" 780 | integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== 781 | dependencies: 782 | babel-plugin-jest-hoist "^29.6.3" 783 | babel-preset-current-node-syntax "^1.0.0" 784 | 785 | balanced-match@^1.0.0: 786 | version "1.0.2" 787 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 788 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 789 | 790 | base64-js@^1.5.1: 791 | version "1.5.1" 792 | resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" 793 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 794 | 795 | brace-expansion@^1.1.7: 796 | version "1.1.11" 797 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 798 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 799 | dependencies: 800 | balanced-match "^1.0.0" 801 | concat-map "0.0.1" 802 | 803 | braces@^3.0.3: 804 | version "3.0.3" 805 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" 806 | integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== 807 | dependencies: 808 | fill-range "^7.1.1" 809 | 810 | browserslist@^4.24.0: 811 | version "4.24.5" 812 | resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz" 813 | integrity sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw== 814 | dependencies: 815 | caniuse-lite "^1.0.30001716" 816 | electron-to-chromium "^1.5.149" 817 | node-releases "^2.0.19" 818 | update-browserslist-db "^1.1.3" 819 | 820 | bser@2.1.1: 821 | version "2.1.1" 822 | resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" 823 | integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== 824 | dependencies: 825 | node-int64 "^0.4.0" 826 | 827 | buffer-from@^1.0.0: 828 | version "1.1.2" 829 | resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" 830 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 831 | 832 | caller-callsite@^2.0.0: 833 | version "2.0.0" 834 | resolved "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz" 835 | integrity sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ== 836 | dependencies: 837 | callsites "^2.0.0" 838 | 839 | caller-path@^2.0.0: 840 | version "2.0.0" 841 | resolved "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz" 842 | integrity sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A== 843 | dependencies: 844 | caller-callsite "^2.0.0" 845 | 846 | callsites@^2.0.0: 847 | version "2.0.0" 848 | resolved "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz" 849 | integrity sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ== 850 | 851 | camelcase@^5.3.1: 852 | version "5.3.1" 853 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" 854 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 855 | 856 | camelcase@^6.2.0: 857 | version "6.3.0" 858 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" 859 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 860 | 861 | caniuse-lite@^1.0.30001716: 862 | version "1.0.30001718" 863 | resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz" 864 | integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw== 865 | 866 | chalk@^4.0.0: 867 | version "4.1.2" 868 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 869 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 870 | dependencies: 871 | ansi-styles "^4.1.0" 872 | supports-color "^7.1.0" 873 | 874 | chrome-launcher@^0.15.2: 875 | version "0.15.2" 876 | resolved "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz" 877 | integrity sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ== 878 | dependencies: 879 | "@types/node" "*" 880 | escape-string-regexp "^4.0.0" 881 | is-wsl "^2.2.0" 882 | lighthouse-logger "^1.0.0" 883 | 884 | chromium-edge-launcher@^0.2.0: 885 | version "0.2.0" 886 | resolved "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.2.0.tgz" 887 | integrity sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg== 888 | dependencies: 889 | "@types/node" "*" 890 | escape-string-regexp "^4.0.0" 891 | is-wsl "^2.2.0" 892 | lighthouse-logger "^1.0.0" 893 | mkdirp "^1.0.4" 894 | rimraf "^3.0.2" 895 | 896 | ci-info@^2.0.0: 897 | version "2.0.0" 898 | resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" 899 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 900 | 901 | ci-info@^3.2.0: 902 | version "3.9.0" 903 | resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" 904 | integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== 905 | 906 | cliui@^8.0.1: 907 | version "8.0.1" 908 | resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" 909 | integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== 910 | dependencies: 911 | string-width "^4.2.0" 912 | strip-ansi "^6.0.1" 913 | wrap-ansi "^7.0.0" 914 | 915 | color-convert@^2.0.1: 916 | version "2.0.1" 917 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 918 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 919 | dependencies: 920 | color-name "~1.1.4" 921 | 922 | color-name@~1.1.4: 923 | version "1.1.4" 924 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 925 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 926 | 927 | commander@^12.0.0: 928 | version "12.1.0" 929 | resolved "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz" 930 | integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== 931 | 932 | commander@^2.20.0: 933 | version "2.20.3" 934 | resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" 935 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 936 | 937 | concat-map@0.0.1: 938 | version "0.0.1" 939 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 940 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 941 | 942 | connect@^3.6.5: 943 | version "3.7.0" 944 | resolved "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz" 945 | integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== 946 | dependencies: 947 | debug "2.6.9" 948 | finalhandler "1.1.2" 949 | parseurl "~1.3.3" 950 | utils-merge "1.0.1" 951 | 952 | convert-source-map@^2.0.0: 953 | version "2.0.0" 954 | resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" 955 | integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== 956 | 957 | cosmiconfig@^5.0.5: 958 | version "5.2.1" 959 | resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz" 960 | integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== 961 | dependencies: 962 | import-fresh "^2.0.0" 963 | is-directory "^0.3.1" 964 | js-yaml "^3.13.1" 965 | parse-json "^4.0.0" 966 | 967 | create-require@^1.1.0: 968 | version "1.1.1" 969 | resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" 970 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 971 | 972 | csstype@^3.0.2: 973 | version "3.1.3" 974 | resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" 975 | integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== 976 | 977 | debug@2.6.9, debug@^2.2.0, debug@^2.6.9: 978 | version "2.6.9" 979 | resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" 980 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 981 | dependencies: 982 | ms "2.0.0" 983 | 984 | debug@4, debug@^4.1.0, debug@^4.3.1, debug@^4.4.0: 985 | version "4.4.1" 986 | resolved "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz" 987 | integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== 988 | dependencies: 989 | ms "^2.1.3" 990 | 991 | depd@2.0.0: 992 | version "2.0.0" 993 | resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" 994 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 995 | 996 | destroy@1.2.0: 997 | version "1.2.0" 998 | resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" 999 | integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== 1000 | 1001 | diff@^4.0.1: 1002 | version "4.0.2" 1003 | resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" 1004 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 1005 | 1006 | ee-first@1.1.1: 1007 | version "1.1.1" 1008 | resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" 1009 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 1010 | 1011 | electron-to-chromium@^1.5.149: 1012 | version "1.5.152" 1013 | resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.152.tgz" 1014 | integrity sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg== 1015 | 1016 | emoji-regex@^8.0.0: 1017 | version "8.0.0" 1018 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" 1019 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 1020 | 1021 | encodeurl@~1.0.2: 1022 | version "1.0.2" 1023 | resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" 1024 | integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== 1025 | 1026 | encodeurl@~2.0.0: 1027 | version "2.0.0" 1028 | resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" 1029 | integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== 1030 | 1031 | error-ex@^1.3.1: 1032 | version "1.3.2" 1033 | resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" 1034 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 1035 | dependencies: 1036 | is-arrayish "^0.2.1" 1037 | 1038 | error-stack-parser@^2.0.6: 1039 | version "2.1.4" 1040 | resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz" 1041 | integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== 1042 | dependencies: 1043 | stackframe "^1.3.4" 1044 | 1045 | escalade@^3.1.1, escalade@^3.2.0: 1046 | version "3.2.0" 1047 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" 1048 | integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== 1049 | 1050 | escape-html@~1.0.3: 1051 | version "1.0.3" 1052 | resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" 1053 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 1054 | 1055 | escape-string-regexp@^2.0.0: 1056 | version "2.0.0" 1057 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" 1058 | integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== 1059 | 1060 | escape-string-regexp@^4.0.0: 1061 | version "4.0.0" 1062 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 1063 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 1064 | 1065 | esprima@^4.0.0: 1066 | version "4.0.1" 1067 | resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" 1068 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 1069 | 1070 | etag@~1.8.1: 1071 | version "1.8.1" 1072 | resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" 1073 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 1074 | 1075 | event-target-shim@^5.0.0, event-target-shim@^5.0.1: 1076 | version "5.0.1" 1077 | resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" 1078 | integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== 1079 | 1080 | exponential-backoff@^3.1.1: 1081 | version "3.1.2" 1082 | resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz" 1083 | integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== 1084 | 1085 | fast-json-stable-stringify@^2.1.0: 1086 | version "2.1.0" 1087 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" 1088 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 1089 | 1090 | fb-watchman@^2.0.0: 1091 | version "2.0.2" 1092 | resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" 1093 | integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== 1094 | dependencies: 1095 | bser "2.1.1" 1096 | 1097 | fill-range@^7.1.1: 1098 | version "7.1.1" 1099 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" 1100 | integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== 1101 | dependencies: 1102 | to-regex-range "^5.0.1" 1103 | 1104 | finalhandler@1.1.2: 1105 | version "1.1.2" 1106 | resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz" 1107 | integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== 1108 | dependencies: 1109 | debug "2.6.9" 1110 | encodeurl "~1.0.2" 1111 | escape-html "~1.0.3" 1112 | on-finished "~2.3.0" 1113 | parseurl "~1.3.3" 1114 | statuses "~1.5.0" 1115 | unpipe "~1.0.0" 1116 | 1117 | find-up@^4.1.0: 1118 | version "4.1.0" 1119 | resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" 1120 | integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== 1121 | dependencies: 1122 | locate-path "^5.0.0" 1123 | path-exists "^4.0.0" 1124 | 1125 | flow-enums-runtime@^0.0.6: 1126 | version "0.0.6" 1127 | resolved "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz" 1128 | integrity sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw== 1129 | 1130 | fresh@0.5.2: 1131 | version "0.5.2" 1132 | resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" 1133 | integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== 1134 | 1135 | fs.realpath@^1.0.0: 1136 | version "1.0.0" 1137 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 1138 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 1139 | 1140 | fsevents@^2.3.2: 1141 | version "2.3.3" 1142 | resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" 1143 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 1144 | 1145 | gensync@^1.0.0-beta.2: 1146 | version "1.0.0-beta.2" 1147 | resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" 1148 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== 1149 | 1150 | get-caller-file@^2.0.5: 1151 | version "2.0.5" 1152 | resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" 1153 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 1154 | 1155 | get-package-type@^0.1.0: 1156 | version "0.1.0" 1157 | resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" 1158 | integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== 1159 | 1160 | glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: 1161 | version "7.2.3" 1162 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" 1163 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 1164 | dependencies: 1165 | fs.realpath "^1.0.0" 1166 | inflight "^1.0.4" 1167 | inherits "2" 1168 | minimatch "^3.1.1" 1169 | once "^1.3.0" 1170 | path-is-absolute "^1.0.0" 1171 | 1172 | globals@^11.1.0: 1173 | version "11.12.0" 1174 | resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" 1175 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 1176 | 1177 | graceful-fs@^4.2.4, graceful-fs@^4.2.9: 1178 | version "4.2.11" 1179 | resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" 1180 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== 1181 | 1182 | has-flag@^4.0.0: 1183 | version "4.0.0" 1184 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 1185 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 1186 | 1187 | hermes-estree@0.25.1: 1188 | version "0.25.1" 1189 | resolved "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz" 1190 | integrity sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw== 1191 | 1192 | hermes-estree@0.28.1: 1193 | version "0.28.1" 1194 | resolved "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.28.1.tgz" 1195 | integrity sha512-w3nxl/RGM7LBae0v8LH2o36+8VqwOZGv9rX1wyoWT6YaKZLqpJZ0YQ5P0LVr3tuRpf7vCx0iIG4i/VmBJejxTQ== 1196 | 1197 | hermes-parser@0.25.1: 1198 | version "0.25.1" 1199 | resolved "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz" 1200 | integrity sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA== 1201 | dependencies: 1202 | hermes-estree "0.25.1" 1203 | 1204 | hermes-parser@0.28.1: 1205 | version "0.28.1" 1206 | resolved "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.28.1.tgz" 1207 | integrity sha512-nf8o+hE8g7UJWParnccljHumE9Vlq8F7MqIdeahl+4x0tvCUJYRrT0L7h0MMg/X9YJmkNwsfbaNNrzPtFXOscg== 1208 | dependencies: 1209 | hermes-estree "0.28.1" 1210 | 1211 | http-errors@2.0.0: 1212 | version "2.0.0" 1213 | resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" 1214 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 1215 | dependencies: 1216 | depd "2.0.0" 1217 | inherits "2.0.4" 1218 | setprototypeof "1.2.0" 1219 | statuses "2.0.1" 1220 | toidentifier "1.0.1" 1221 | 1222 | https-proxy-agent@^7.0.5: 1223 | version "7.0.6" 1224 | resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz" 1225 | integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== 1226 | dependencies: 1227 | agent-base "^7.1.2" 1228 | debug "4" 1229 | 1230 | image-size@^1.0.2: 1231 | version "1.2.1" 1232 | resolved "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz" 1233 | integrity sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw== 1234 | dependencies: 1235 | queue "6.0.2" 1236 | 1237 | import-fresh@^2.0.0: 1238 | version "2.0.0" 1239 | resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz" 1240 | integrity sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg== 1241 | dependencies: 1242 | caller-path "^2.0.0" 1243 | resolve-from "^3.0.0" 1244 | 1245 | imurmurhash@^0.1.4: 1246 | version "0.1.4" 1247 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" 1248 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 1249 | 1250 | inflight@^1.0.4: 1251 | version "1.0.6" 1252 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 1253 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 1254 | dependencies: 1255 | once "^1.3.0" 1256 | wrappy "1" 1257 | 1258 | inherits@2, inherits@2.0.4, inherits@~2.0.3: 1259 | version "2.0.4" 1260 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 1261 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1262 | 1263 | invariant@^2.2.4: 1264 | version "2.2.4" 1265 | resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" 1266 | integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== 1267 | dependencies: 1268 | loose-envify "^1.0.0" 1269 | 1270 | is-arrayish@^0.2.1: 1271 | version "0.2.1" 1272 | resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" 1273 | integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== 1274 | 1275 | is-directory@^0.3.1: 1276 | version "0.3.1" 1277 | resolved "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz" 1278 | integrity sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw== 1279 | 1280 | is-docker@^2.0.0: 1281 | version "2.2.1" 1282 | resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" 1283 | integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== 1284 | 1285 | is-fullwidth-code-point@^3.0.0: 1286 | version "3.0.0" 1287 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" 1288 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 1289 | 1290 | is-number@^7.0.0: 1291 | version "7.0.0" 1292 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 1293 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1294 | 1295 | is-wsl@^2.1.1, is-wsl@^2.2.0: 1296 | version "2.2.0" 1297 | resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" 1298 | integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== 1299 | dependencies: 1300 | is-docker "^2.0.0" 1301 | 1302 | istanbul-lib-coverage@^3.2.0: 1303 | version "3.2.2" 1304 | resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" 1305 | integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== 1306 | 1307 | istanbul-lib-instrument@^5.0.4: 1308 | version "5.2.1" 1309 | resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" 1310 | integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== 1311 | dependencies: 1312 | "@babel/core" "^7.12.3" 1313 | "@babel/parser" "^7.14.7" 1314 | "@istanbuljs/schema" "^0.1.2" 1315 | istanbul-lib-coverage "^3.2.0" 1316 | semver "^6.3.0" 1317 | 1318 | jest-environment-node@^29.7.0: 1319 | version "29.7.0" 1320 | resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" 1321 | integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== 1322 | dependencies: 1323 | "@jest/environment" "^29.7.0" 1324 | "@jest/fake-timers" "^29.7.0" 1325 | "@jest/types" "^29.6.3" 1326 | "@types/node" "*" 1327 | jest-mock "^29.7.0" 1328 | jest-util "^29.7.0" 1329 | 1330 | jest-get-type@^29.6.3: 1331 | version "29.6.3" 1332 | resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" 1333 | integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== 1334 | 1335 | jest-haste-map@^29.7.0: 1336 | version "29.7.0" 1337 | resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz" 1338 | integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== 1339 | dependencies: 1340 | "@jest/types" "^29.6.3" 1341 | "@types/graceful-fs" "^4.1.3" 1342 | "@types/node" "*" 1343 | anymatch "^3.0.3" 1344 | fb-watchman "^2.0.0" 1345 | graceful-fs "^4.2.9" 1346 | jest-regex-util "^29.6.3" 1347 | jest-util "^29.7.0" 1348 | jest-worker "^29.7.0" 1349 | micromatch "^4.0.4" 1350 | walker "^1.0.8" 1351 | optionalDependencies: 1352 | fsevents "^2.3.2" 1353 | 1354 | jest-message-util@^29.7.0: 1355 | version "29.7.0" 1356 | resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" 1357 | integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== 1358 | dependencies: 1359 | "@babel/code-frame" "^7.12.13" 1360 | "@jest/types" "^29.6.3" 1361 | "@types/stack-utils" "^2.0.0" 1362 | chalk "^4.0.0" 1363 | graceful-fs "^4.2.9" 1364 | micromatch "^4.0.4" 1365 | pretty-format "^29.7.0" 1366 | slash "^3.0.0" 1367 | stack-utils "^2.0.3" 1368 | 1369 | jest-mock@^29.7.0: 1370 | version "29.7.0" 1371 | resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz" 1372 | integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== 1373 | dependencies: 1374 | "@jest/types" "^29.6.3" 1375 | "@types/node" "*" 1376 | jest-util "^29.7.0" 1377 | 1378 | jest-regex-util@^29.6.3: 1379 | version "29.6.3" 1380 | resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" 1381 | integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== 1382 | 1383 | jest-util@^29.7.0: 1384 | version "29.7.0" 1385 | resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" 1386 | integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== 1387 | dependencies: 1388 | "@jest/types" "^29.6.3" 1389 | "@types/node" "*" 1390 | chalk "^4.0.0" 1391 | ci-info "^3.2.0" 1392 | graceful-fs "^4.2.9" 1393 | picomatch "^2.2.3" 1394 | 1395 | jest-validate@^29.7.0: 1396 | version "29.7.0" 1397 | resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz" 1398 | integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== 1399 | dependencies: 1400 | "@jest/types" "^29.6.3" 1401 | camelcase "^6.2.0" 1402 | chalk "^4.0.0" 1403 | jest-get-type "^29.6.3" 1404 | leven "^3.1.0" 1405 | pretty-format "^29.7.0" 1406 | 1407 | jest-worker@^29.7.0: 1408 | version "29.7.0" 1409 | resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz" 1410 | integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== 1411 | dependencies: 1412 | "@types/node" "*" 1413 | jest-util "^29.7.0" 1414 | merge-stream "^2.0.0" 1415 | supports-color "^8.0.0" 1416 | 1417 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 1418 | version "4.0.0" 1419 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" 1420 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 1421 | 1422 | js-yaml@^3.13.1: 1423 | version "3.14.1" 1424 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" 1425 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 1426 | dependencies: 1427 | argparse "^1.0.7" 1428 | esprima "^4.0.0" 1429 | 1430 | jsc-safe-url@^0.2.2: 1431 | version "0.2.4" 1432 | resolved "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz" 1433 | integrity sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q== 1434 | 1435 | jsesc@^3.0.2: 1436 | version "3.1.0" 1437 | resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" 1438 | integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== 1439 | 1440 | json-parse-better-errors@^1.0.1: 1441 | version "1.0.2" 1442 | resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" 1443 | integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== 1444 | 1445 | json5@^2.2.3: 1446 | version "2.2.3" 1447 | resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" 1448 | integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== 1449 | 1450 | leven@^3.1.0: 1451 | version "3.1.0" 1452 | resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" 1453 | integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== 1454 | 1455 | lighthouse-logger@^1.0.0: 1456 | version "1.4.2" 1457 | resolved "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz" 1458 | integrity sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g== 1459 | dependencies: 1460 | debug "^2.6.9" 1461 | marky "^1.2.2" 1462 | 1463 | locate-path@^5.0.0: 1464 | version "5.0.0" 1465 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" 1466 | integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== 1467 | dependencies: 1468 | p-locate "^4.1.0" 1469 | 1470 | lodash.throttle@^4.1.1: 1471 | version "4.1.1" 1472 | resolved "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz" 1473 | integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== 1474 | 1475 | loose-envify@^1.0.0: 1476 | version "1.4.0" 1477 | resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" 1478 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 1479 | dependencies: 1480 | js-tokens "^3.0.0 || ^4.0.0" 1481 | 1482 | lru-cache@^5.1.1: 1483 | version "5.1.1" 1484 | resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" 1485 | integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== 1486 | dependencies: 1487 | yallist "^3.0.2" 1488 | 1489 | make-error@^1.1.1: 1490 | version "1.3.6" 1491 | resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" 1492 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1493 | 1494 | makeerror@1.0.12: 1495 | version "1.0.12" 1496 | resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" 1497 | integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== 1498 | dependencies: 1499 | tmpl "1.0.5" 1500 | 1501 | marky@^1.2.2: 1502 | version "1.3.0" 1503 | resolved "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz" 1504 | integrity sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ== 1505 | 1506 | memoize-one@^5.0.0: 1507 | version "5.2.1" 1508 | resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" 1509 | integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== 1510 | 1511 | merge-stream@^2.0.0: 1512 | version "2.0.0" 1513 | resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" 1514 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 1515 | 1516 | metro-babel-transformer@0.82.3: 1517 | version "0.82.3" 1518 | resolved "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.82.3.tgz" 1519 | integrity sha512-eC0f1MSA8rg7VoNDCYMIAIe5AEgYBskh5W8rIa4RGRdmEOsGlXbAV0AWMYoA7NlIALW/S9b10AcdIwD3n1e50w== 1520 | dependencies: 1521 | "@babel/core" "^7.25.2" 1522 | flow-enums-runtime "^0.0.6" 1523 | hermes-parser "0.28.1" 1524 | nullthrows "^1.1.1" 1525 | 1526 | metro-cache-key@0.82.3: 1527 | version "0.82.3" 1528 | resolved "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.82.3.tgz" 1529 | integrity sha512-dDLTUOJ7YYqGog9kR55InchwnkkHuxBXD765J3hQVWWPCy6xO9uZXZYGX1Y/tIMV8U7Ho1Sve0V13n5rFajrRQ== 1530 | dependencies: 1531 | flow-enums-runtime "^0.0.6" 1532 | 1533 | metro-cache@0.82.3: 1534 | version "0.82.3" 1535 | resolved "https://registry.npmjs.org/metro-cache/-/metro-cache-0.82.3.tgz" 1536 | integrity sha512-9zKhicA5GENROeP+iXku1NrI8FegtwEg3iPXHGixkm1Yppkbwsy/3lSHSiJZoT6GkZmxUDjN6sQ5QQ+/p72Msw== 1537 | dependencies: 1538 | exponential-backoff "^3.1.1" 1539 | flow-enums-runtime "^0.0.6" 1540 | https-proxy-agent "^7.0.5" 1541 | metro-core "0.82.3" 1542 | 1543 | metro-config@0.82.3, metro-config@^0.82.0: 1544 | version "0.82.3" 1545 | resolved "https://registry.npmjs.org/metro-config/-/metro-config-0.82.3.tgz" 1546 | integrity sha512-GRG9sBkPvrGXD/Wu3RdEDuWg5NDixF9t0c6Zz9kZ9Aa/aQY+m85JgaCI5HYEV+UzVC/IUFFSpJiMfzQRicppLw== 1547 | dependencies: 1548 | connect "^3.6.5" 1549 | cosmiconfig "^5.0.5" 1550 | flow-enums-runtime "^0.0.6" 1551 | jest-validate "^29.7.0" 1552 | metro "0.82.3" 1553 | metro-cache "0.82.3" 1554 | metro-core "0.82.3" 1555 | metro-runtime "0.82.3" 1556 | 1557 | metro-core@0.82.3, metro-core@^0.82.0: 1558 | version "0.82.3" 1559 | resolved "https://registry.npmjs.org/metro-core/-/metro-core-0.82.3.tgz" 1560 | integrity sha512-JQZDdXo3hyLl1pqVT4IKEwcBK+3f11qFXeCjQ1hjVpjMwQLOqSM02J7NC/4DNSBt+qWBxWj6R5Jphcc7+9AEWw== 1561 | dependencies: 1562 | flow-enums-runtime "^0.0.6" 1563 | lodash.throttle "^4.1.1" 1564 | metro-resolver "0.82.3" 1565 | 1566 | metro-file-map@0.82.3: 1567 | version "0.82.3" 1568 | resolved "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.82.3.tgz" 1569 | integrity sha512-o4wtloAge85MZl85F87FT59R/4tn5GvCvLfYcnzzDB20o2YX9AMxZqswrGMaei/GbD/Win5FrLF/Iq8oetcByA== 1570 | dependencies: 1571 | debug "^4.4.0" 1572 | fb-watchman "^2.0.0" 1573 | flow-enums-runtime "^0.0.6" 1574 | graceful-fs "^4.2.4" 1575 | invariant "^2.2.4" 1576 | jest-worker "^29.7.0" 1577 | micromatch "^4.0.4" 1578 | nullthrows "^1.1.1" 1579 | walker "^1.0.7" 1580 | 1581 | metro-minify-terser@0.82.3: 1582 | version "0.82.3" 1583 | resolved "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.82.3.tgz" 1584 | integrity sha512-/3FasOULfHq1P0KPNFy5y28Th5oknPSwEbt9JELVBMAPhUnLqQkCLr4M+RQzKG3aEQN1/mEqenWApFCkk6Nm/Q== 1585 | dependencies: 1586 | flow-enums-runtime "^0.0.6" 1587 | terser "^5.15.0" 1588 | 1589 | metro-resolver@0.82.3: 1590 | version "0.82.3" 1591 | resolved "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.82.3.tgz" 1592 | integrity sha512-pdib7UrOM04j/RjWmaqmjjWRiuCbpA8BdUSuXzvBaK0QlNzHkRRDv6kiOGxgQ+UgG+KdbPcJktsW9olqiDhf9w== 1593 | dependencies: 1594 | flow-enums-runtime "^0.0.6" 1595 | 1596 | metro-runtime@0.82.3, metro-runtime@^0.82.0: 1597 | version "0.82.3" 1598 | resolved "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.82.3.tgz" 1599 | integrity sha512-J4SrUUsBy9ire8I2sFuXN5MzPmuBHlx1bjvAjdoo1ecpH2mtS3ubRqVnMotBxuK5+GhrbW0mtg5/46PVXy26cw== 1600 | dependencies: 1601 | "@babel/runtime" "^7.25.0" 1602 | flow-enums-runtime "^0.0.6" 1603 | 1604 | metro-source-map@0.82.3, metro-source-map@^0.82.0: 1605 | version "0.82.3" 1606 | resolved "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.82.3.tgz" 1607 | integrity sha512-gz7wfjz23rit6ePQ7NKE9x+VOWGKm54vli4wbphR9W+3y0bh6Ad7T0BGH9DUzRAnOnOorewrVEqFmT24mia5sg== 1608 | dependencies: 1609 | "@babel/traverse" "^7.25.3" 1610 | "@babel/traverse--for-generate-function-map" "npm:@babel/traverse@^7.25.3" 1611 | "@babel/types" "^7.25.2" 1612 | flow-enums-runtime "^0.0.6" 1613 | invariant "^2.2.4" 1614 | metro-symbolicate "0.82.3" 1615 | nullthrows "^1.1.1" 1616 | ob1 "0.82.3" 1617 | source-map "^0.5.6" 1618 | vlq "^1.0.0" 1619 | 1620 | metro-symbolicate@0.82.3: 1621 | version "0.82.3" 1622 | resolved "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.82.3.tgz" 1623 | integrity sha512-WZKhR+QGbwkOLWP1z58Y7BFWUqLVDEEPsSQ5UI5+OWQDAwdtsPU9+sSNoJtD5qRU9qrB2XewQE3lJ2EQRRFJew== 1624 | dependencies: 1625 | flow-enums-runtime "^0.0.6" 1626 | invariant "^2.2.4" 1627 | metro-source-map "0.82.3" 1628 | nullthrows "^1.1.1" 1629 | source-map "^0.5.6" 1630 | vlq "^1.0.0" 1631 | 1632 | metro-transform-plugins@0.82.3: 1633 | version "0.82.3" 1634 | resolved "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.82.3.tgz" 1635 | integrity sha512-s1gVrkhczwMbxZLRSLCJ16K/4Sqx5IhO4sWlL6j0jlIEs1/Drn3JrkUUdQTtgmJS8SBpxmmB66cw7wnz751dVg== 1636 | dependencies: 1637 | "@babel/core" "^7.25.2" 1638 | "@babel/generator" "^7.25.0" 1639 | "@babel/template" "^7.25.0" 1640 | "@babel/traverse" "^7.25.3" 1641 | flow-enums-runtime "^0.0.6" 1642 | nullthrows "^1.1.1" 1643 | 1644 | metro-transform-worker@0.82.3: 1645 | version "0.82.3" 1646 | resolved "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.82.3.tgz" 1647 | integrity sha512-z5Y7nYlSlLAEhjFi73uEJh69G5IC6HFZmXFcrxnY+JNlsjT2r0GgsDF4WaQGtarAIt5NP88V8983/PedwNfEcw== 1648 | dependencies: 1649 | "@babel/core" "^7.25.2" 1650 | "@babel/generator" "^7.25.0" 1651 | "@babel/parser" "^7.25.3" 1652 | "@babel/types" "^7.25.2" 1653 | flow-enums-runtime "^0.0.6" 1654 | metro "0.82.3" 1655 | metro-babel-transformer "0.82.3" 1656 | metro-cache "0.82.3" 1657 | metro-cache-key "0.82.3" 1658 | metro-minify-terser "0.82.3" 1659 | metro-source-map "0.82.3" 1660 | metro-transform-plugins "0.82.3" 1661 | nullthrows "^1.1.1" 1662 | 1663 | metro@0.82.3, metro@^0.82.0: 1664 | version "0.82.3" 1665 | resolved "https://registry.npmjs.org/metro/-/metro-0.82.3.tgz" 1666 | integrity sha512-EfSLtuUmfsGk3znJ+zoN8cRLniQo3W1wyA+nJMfpTLdENfbbPnGRTwmKhzRcJIUh9jgkrrF4oRQ5shLtQ2DsUw== 1667 | dependencies: 1668 | "@babel/code-frame" "^7.24.7" 1669 | "@babel/core" "^7.25.2" 1670 | "@babel/generator" "^7.25.0" 1671 | "@babel/parser" "^7.25.3" 1672 | "@babel/template" "^7.25.0" 1673 | "@babel/traverse" "^7.25.3" 1674 | "@babel/types" "^7.25.2" 1675 | accepts "^1.3.7" 1676 | chalk "^4.0.0" 1677 | ci-info "^2.0.0" 1678 | connect "^3.6.5" 1679 | debug "^4.4.0" 1680 | error-stack-parser "^2.0.6" 1681 | flow-enums-runtime "^0.0.6" 1682 | graceful-fs "^4.2.4" 1683 | hermes-parser "0.28.1" 1684 | image-size "^1.0.2" 1685 | invariant "^2.2.4" 1686 | jest-worker "^29.7.0" 1687 | jsc-safe-url "^0.2.2" 1688 | lodash.throttle "^4.1.1" 1689 | metro-babel-transformer "0.82.3" 1690 | metro-cache "0.82.3" 1691 | metro-cache-key "0.82.3" 1692 | metro-config "0.82.3" 1693 | metro-core "0.82.3" 1694 | metro-file-map "0.82.3" 1695 | metro-resolver "0.82.3" 1696 | metro-runtime "0.82.3" 1697 | metro-source-map "0.82.3" 1698 | metro-symbolicate "0.82.3" 1699 | metro-transform-plugins "0.82.3" 1700 | metro-transform-worker "0.82.3" 1701 | mime-types "^2.1.27" 1702 | nullthrows "^1.1.1" 1703 | serialize-error "^2.1.0" 1704 | source-map "^0.5.6" 1705 | throat "^5.0.0" 1706 | ws "^7.5.10" 1707 | yargs "^17.6.2" 1708 | 1709 | micromatch@^4.0.4: 1710 | version "4.0.8" 1711 | resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" 1712 | integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== 1713 | dependencies: 1714 | braces "^3.0.3" 1715 | picomatch "^2.3.1" 1716 | 1717 | mime-db@1.52.0: 1718 | version "1.52.0" 1719 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" 1720 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 1721 | 1722 | mime-types@^2.1.27, mime-types@~2.1.34: 1723 | version "2.1.35" 1724 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" 1725 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 1726 | dependencies: 1727 | mime-db "1.52.0" 1728 | 1729 | mime@1.6.0: 1730 | version "1.6.0" 1731 | resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" 1732 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1733 | 1734 | minimatch@^3.0.4, minimatch@^3.1.1: 1735 | version "3.1.2" 1736 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 1737 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1738 | dependencies: 1739 | brace-expansion "^1.1.7" 1740 | 1741 | mkdirp@^1.0.4: 1742 | version "1.0.4" 1743 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" 1744 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 1745 | 1746 | ms@2.0.0: 1747 | version "2.0.0" 1748 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" 1749 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 1750 | 1751 | ms@2.1.3, ms@^2.1.3: 1752 | version "2.1.3" 1753 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 1754 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1755 | 1756 | negotiator@0.6.3: 1757 | version "0.6.3" 1758 | resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" 1759 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 1760 | 1761 | node-int64@^0.4.0: 1762 | version "0.4.0" 1763 | resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" 1764 | integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== 1765 | 1766 | node-releases@^2.0.19: 1767 | version "2.0.19" 1768 | resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz" 1769 | integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== 1770 | 1771 | normalize-path@^3.0.0: 1772 | version "3.0.0" 1773 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 1774 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1775 | 1776 | nullthrows@^1.1.1: 1777 | version "1.1.1" 1778 | resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz" 1779 | integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== 1780 | 1781 | ob1@0.82.3: 1782 | version "0.82.3" 1783 | resolved "https://registry.npmjs.org/ob1/-/ob1-0.82.3.tgz" 1784 | integrity sha512-8/SeymYlPMVODpCATHqm+X8eiuvD1GsKVa11n688V4GGgjrM3CRvrbtrYBs4t89LJDkv5CwGYPdqayuY0DmTTA== 1785 | dependencies: 1786 | flow-enums-runtime "^0.0.6" 1787 | 1788 | on-finished@2.4.1: 1789 | version "2.4.1" 1790 | resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" 1791 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 1792 | dependencies: 1793 | ee-first "1.1.1" 1794 | 1795 | on-finished@~2.3.0: 1796 | version "2.3.0" 1797 | resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" 1798 | integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== 1799 | dependencies: 1800 | ee-first "1.1.1" 1801 | 1802 | once@^1.3.0: 1803 | version "1.4.0" 1804 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 1805 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1806 | dependencies: 1807 | wrappy "1" 1808 | 1809 | open@^7.0.3: 1810 | version "7.4.2" 1811 | resolved "https://registry.npmjs.org/open/-/open-7.4.2.tgz" 1812 | integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== 1813 | dependencies: 1814 | is-docker "^2.0.0" 1815 | is-wsl "^2.1.1" 1816 | 1817 | p-limit@^2.2.0: 1818 | version "2.3.0" 1819 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" 1820 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== 1821 | dependencies: 1822 | p-try "^2.0.0" 1823 | 1824 | p-locate@^4.1.0: 1825 | version "4.1.0" 1826 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" 1827 | integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== 1828 | dependencies: 1829 | p-limit "^2.2.0" 1830 | 1831 | p-try@^2.0.0: 1832 | version "2.2.0" 1833 | resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" 1834 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 1835 | 1836 | parse-json@^4.0.0: 1837 | version "4.0.0" 1838 | resolved "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz" 1839 | integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== 1840 | dependencies: 1841 | error-ex "^1.3.1" 1842 | json-parse-better-errors "^1.0.1" 1843 | 1844 | parseurl@~1.3.3: 1845 | version "1.3.3" 1846 | resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" 1847 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 1848 | 1849 | path-exists@^4.0.0: 1850 | version "4.0.0" 1851 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" 1852 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1853 | 1854 | path-is-absolute@^1.0.0: 1855 | version "1.0.1" 1856 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 1857 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1858 | 1859 | picocolors@^1.1.1: 1860 | version "1.1.1" 1861 | resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" 1862 | integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== 1863 | 1864 | picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: 1865 | version "2.3.1" 1866 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 1867 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1868 | 1869 | pirates@^4.0.4: 1870 | version "4.0.7" 1871 | resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz" 1872 | integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== 1873 | 1874 | prettier@^3.5.3: 1875 | version "3.5.3" 1876 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.3.tgz#4fc2ce0d657e7a02e602549f053b239cb7dfe1b5" 1877 | integrity sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw== 1878 | 1879 | pretty-format@^29.7.0: 1880 | version "29.7.0" 1881 | resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" 1882 | integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== 1883 | dependencies: 1884 | "@jest/schemas" "^29.6.3" 1885 | ansi-styles "^5.0.0" 1886 | react-is "^18.0.0" 1887 | 1888 | promise@^8.3.0: 1889 | version "8.3.0" 1890 | resolved "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz" 1891 | integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== 1892 | dependencies: 1893 | asap "~2.0.6" 1894 | 1895 | queue@6.0.2: 1896 | version "6.0.2" 1897 | resolved "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz" 1898 | integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== 1899 | dependencies: 1900 | inherits "~2.0.3" 1901 | 1902 | range-parser@~1.2.1: 1903 | version "1.2.1" 1904 | resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" 1905 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 1906 | 1907 | react-devtools-core@^6.1.1: 1908 | version "6.1.2" 1909 | resolved "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.2.tgz" 1910 | integrity sha512-ldFwzufLletzCikNJVYaxlxMLu7swJ3T2VrGfzXlMsVhZhPDKXA38DEROidaYZVgMAmQnIjymrmqto5pyfrwPA== 1911 | dependencies: 1912 | shell-quote "^1.6.1" 1913 | ws "^7" 1914 | 1915 | react-dom@^19.1.0: 1916 | version "19.1.0" 1917 | resolved "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz" 1918 | integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g== 1919 | dependencies: 1920 | scheduler "^0.26.0" 1921 | 1922 | react-is@^18.0.0: 1923 | version "18.3.1" 1924 | resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" 1925 | integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== 1926 | 1927 | react-native@^0.79.2: 1928 | version "0.79.2" 1929 | resolved "https://registry.npmjs.org/react-native/-/react-native-0.79.2.tgz" 1930 | integrity sha512-AnGzb56JvU5YCL7cAwg10+ewDquzvmgrMddiBM0GAWLwQM/6DJfGd2ZKrMuKKehHerpDDZgG+EY64gk3x3dEkw== 1931 | dependencies: 1932 | "@jest/create-cache-key-function" "^29.7.0" 1933 | "@react-native/assets-registry" "0.79.2" 1934 | "@react-native/codegen" "0.79.2" 1935 | "@react-native/community-cli-plugin" "0.79.2" 1936 | "@react-native/gradle-plugin" "0.79.2" 1937 | "@react-native/js-polyfills" "0.79.2" 1938 | "@react-native/normalize-colors" "0.79.2" 1939 | "@react-native/virtualized-lists" "0.79.2" 1940 | abort-controller "^3.0.0" 1941 | anser "^1.4.9" 1942 | ansi-regex "^5.0.0" 1943 | babel-jest "^29.7.0" 1944 | babel-plugin-syntax-hermes-parser "0.25.1" 1945 | base64-js "^1.5.1" 1946 | chalk "^4.0.0" 1947 | commander "^12.0.0" 1948 | event-target-shim "^5.0.1" 1949 | flow-enums-runtime "^0.0.6" 1950 | glob "^7.1.1" 1951 | invariant "^2.2.4" 1952 | jest-environment-node "^29.7.0" 1953 | memoize-one "^5.0.0" 1954 | metro-runtime "^0.82.0" 1955 | metro-source-map "^0.82.0" 1956 | nullthrows "^1.1.1" 1957 | pretty-format "^29.7.0" 1958 | promise "^8.3.0" 1959 | react-devtools-core "^6.1.1" 1960 | react-refresh "^0.14.0" 1961 | regenerator-runtime "^0.13.2" 1962 | scheduler "0.25.0" 1963 | semver "^7.1.3" 1964 | stacktrace-parser "^0.1.10" 1965 | whatwg-fetch "^3.0.0" 1966 | ws "^6.2.3" 1967 | yargs "^17.6.2" 1968 | 1969 | react-refresh@^0.14.0: 1970 | version "0.14.2" 1971 | resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz" 1972 | integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== 1973 | 1974 | react@^19.1.0: 1975 | version "19.1.0" 1976 | resolved "https://registry.npmjs.org/react/-/react-19.1.0.tgz" 1977 | integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== 1978 | 1979 | regenerator-runtime@^0.13.2: 1980 | version "0.13.11" 1981 | resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" 1982 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 1983 | 1984 | require-directory@^2.1.1: 1985 | version "2.1.1" 1986 | resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" 1987 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1988 | 1989 | resolve-from@^3.0.0: 1990 | version "3.0.0" 1991 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz" 1992 | integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== 1993 | 1994 | resolve-from@^5.0.0: 1995 | version "5.0.0" 1996 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" 1997 | integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== 1998 | 1999 | rimraf@^3.0.2: 2000 | version "3.0.2" 2001 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" 2002 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 2003 | dependencies: 2004 | glob "^7.1.3" 2005 | 2006 | scheduler@0.25.0: 2007 | version "0.25.0" 2008 | resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz" 2009 | integrity sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA== 2010 | 2011 | scheduler@^0.26.0: 2012 | version "0.26.0" 2013 | resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz" 2014 | integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== 2015 | 2016 | semver@^6.3.0, semver@^6.3.1: 2017 | version "6.3.1" 2018 | resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" 2019 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== 2020 | 2021 | semver@^7.1.3: 2022 | version "7.7.2" 2023 | resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz" 2024 | integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== 2025 | 2026 | send@0.19.0: 2027 | version "0.19.0" 2028 | resolved "https://registry.npmjs.org/send/-/send-0.19.0.tgz" 2029 | integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== 2030 | dependencies: 2031 | debug "2.6.9" 2032 | depd "2.0.0" 2033 | destroy "1.2.0" 2034 | encodeurl "~1.0.2" 2035 | escape-html "~1.0.3" 2036 | etag "~1.8.1" 2037 | fresh "0.5.2" 2038 | http-errors "2.0.0" 2039 | mime "1.6.0" 2040 | ms "2.1.3" 2041 | on-finished "2.4.1" 2042 | range-parser "~1.2.1" 2043 | statuses "2.0.1" 2044 | 2045 | serialize-error@^2.1.0: 2046 | version "2.1.0" 2047 | resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz" 2048 | integrity sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw== 2049 | 2050 | serve-static@^1.16.2: 2051 | version "1.16.2" 2052 | resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz" 2053 | integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== 2054 | dependencies: 2055 | encodeurl "~2.0.0" 2056 | escape-html "~1.0.3" 2057 | parseurl "~1.3.3" 2058 | send "0.19.0" 2059 | 2060 | setprototypeof@1.2.0: 2061 | version "1.2.0" 2062 | resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" 2063 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 2064 | 2065 | shell-quote@^1.6.1: 2066 | version "1.8.2" 2067 | resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.2.tgz" 2068 | integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA== 2069 | 2070 | signal-exit@^3.0.7: 2071 | version "3.0.7" 2072 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" 2073 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 2074 | 2075 | slash@^3.0.0: 2076 | version "3.0.0" 2077 | resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" 2078 | integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== 2079 | 2080 | source-map-support@~0.5.20: 2081 | version "0.5.21" 2082 | resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" 2083 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 2084 | dependencies: 2085 | buffer-from "^1.0.0" 2086 | source-map "^0.6.0" 2087 | 2088 | source-map@^0.5.6: 2089 | version "0.5.7" 2090 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" 2091 | integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== 2092 | 2093 | source-map@^0.6.0: 2094 | version "0.6.1" 2095 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" 2096 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 2097 | 2098 | sprintf-js@~1.0.2: 2099 | version "1.0.3" 2100 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" 2101 | integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== 2102 | 2103 | stack-utils@^2.0.3: 2104 | version "2.0.6" 2105 | resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" 2106 | integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== 2107 | dependencies: 2108 | escape-string-regexp "^2.0.0" 2109 | 2110 | stackframe@^1.3.4: 2111 | version "1.3.4" 2112 | resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" 2113 | integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== 2114 | 2115 | stacktrace-parser@^0.1.10: 2116 | version "0.1.11" 2117 | resolved "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz" 2118 | integrity sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg== 2119 | dependencies: 2120 | type-fest "^0.7.1" 2121 | 2122 | statuses@2.0.1: 2123 | version "2.0.1" 2124 | resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" 2125 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 2126 | 2127 | statuses@~1.5.0: 2128 | version "1.5.0" 2129 | resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" 2130 | integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== 2131 | 2132 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 2133 | version "4.2.3" 2134 | resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" 2135 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 2136 | dependencies: 2137 | emoji-regex "^8.0.0" 2138 | is-fullwidth-code-point "^3.0.0" 2139 | strip-ansi "^6.0.1" 2140 | 2141 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 2142 | version "6.0.1" 2143 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" 2144 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 2145 | dependencies: 2146 | ansi-regex "^5.0.1" 2147 | 2148 | supports-color@^7.1.0: 2149 | version "7.2.0" 2150 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 2151 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 2152 | dependencies: 2153 | has-flag "^4.0.0" 2154 | 2155 | supports-color@^8.0.0: 2156 | version "8.1.1" 2157 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" 2158 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 2159 | dependencies: 2160 | has-flag "^4.0.0" 2161 | 2162 | terser@^5.15.0: 2163 | version "5.39.1" 2164 | resolved "https://registry.npmjs.org/terser/-/terser-5.39.1.tgz" 2165 | integrity sha512-Mm6+uad0ZuDtcV8/4uOZQDQ8RuiC5Pu+iZRedJtF7yA/27sPL7d++In/AJKpWZlU3SYMPPkVfwetn6sgZ66pUA== 2166 | dependencies: 2167 | "@jridgewell/source-map" "^0.3.3" 2168 | acorn "^8.8.2" 2169 | commander "^2.20.0" 2170 | source-map-support "~0.5.20" 2171 | 2172 | test-exclude@^6.0.0: 2173 | version "6.0.0" 2174 | resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" 2175 | integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== 2176 | dependencies: 2177 | "@istanbuljs/schema" "^0.1.2" 2178 | glob "^7.1.4" 2179 | minimatch "^3.0.4" 2180 | 2181 | throat@^5.0.0: 2182 | version "5.0.0" 2183 | resolved "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz" 2184 | integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== 2185 | 2186 | tmpl@1.0.5: 2187 | version "1.0.5" 2188 | resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" 2189 | integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== 2190 | 2191 | to-regex-range@^5.0.1: 2192 | version "5.0.1" 2193 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 2194 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 2195 | dependencies: 2196 | is-number "^7.0.0" 2197 | 2198 | toidentifier@1.0.1: 2199 | version "1.0.1" 2200 | resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" 2201 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 2202 | 2203 | ts-node@^10.9.2: 2204 | version "10.9.2" 2205 | resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" 2206 | integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== 2207 | dependencies: 2208 | "@cspotcode/source-map-support" "^0.8.0" 2209 | "@tsconfig/node10" "^1.0.7" 2210 | "@tsconfig/node12" "^1.0.7" 2211 | "@tsconfig/node14" "^1.0.0" 2212 | "@tsconfig/node16" "^1.0.2" 2213 | acorn "^8.4.1" 2214 | acorn-walk "^8.1.1" 2215 | arg "^4.1.0" 2216 | create-require "^1.1.0" 2217 | diff "^4.0.1" 2218 | make-error "^1.1.1" 2219 | v8-compile-cache-lib "^3.0.1" 2220 | yn "3.1.1" 2221 | 2222 | type-detect@4.0.8: 2223 | version "4.0.8" 2224 | resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" 2225 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 2226 | 2227 | type-fest@^0.7.1: 2228 | version "0.7.1" 2229 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz" 2230 | integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== 2231 | 2232 | typescript@^4.9.5: 2233 | version "4.9.5" 2234 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" 2235 | integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== 2236 | 2237 | undici-types@~6.21.0: 2238 | version "6.21.0" 2239 | resolved "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz" 2240 | integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== 2241 | 2242 | unpipe@~1.0.0: 2243 | version "1.0.0" 2244 | resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" 2245 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 2246 | 2247 | update-browserslist-db@^1.1.3: 2248 | version "1.1.3" 2249 | resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz" 2250 | integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== 2251 | dependencies: 2252 | escalade "^3.2.0" 2253 | picocolors "^1.1.1" 2254 | 2255 | utils-merge@1.0.1: 2256 | version "1.0.1" 2257 | resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" 2258 | integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== 2259 | 2260 | v8-compile-cache-lib@^3.0.1: 2261 | version "3.0.1" 2262 | resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" 2263 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 2264 | 2265 | vlq@^1.0.0: 2266 | version "1.0.1" 2267 | resolved "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz" 2268 | integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== 2269 | 2270 | walker@^1.0.7, walker@^1.0.8: 2271 | version "1.0.8" 2272 | resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" 2273 | integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== 2274 | dependencies: 2275 | makeerror "1.0.12" 2276 | 2277 | whatwg-fetch@^3.0.0: 2278 | version "3.6.20" 2279 | resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz" 2280 | integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== 2281 | 2282 | wrap-ansi@^7.0.0: 2283 | version "7.0.0" 2284 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" 2285 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 2286 | dependencies: 2287 | ansi-styles "^4.0.0" 2288 | string-width "^4.1.0" 2289 | strip-ansi "^6.0.0" 2290 | 2291 | wrappy@1: 2292 | version "1.0.2" 2293 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 2294 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 2295 | 2296 | write-file-atomic@^4.0.2: 2297 | version "4.0.2" 2298 | resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" 2299 | integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== 2300 | dependencies: 2301 | imurmurhash "^0.1.4" 2302 | signal-exit "^3.0.7" 2303 | 2304 | ws@^6.2.3: 2305 | version "6.2.3" 2306 | resolved "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz" 2307 | integrity sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA== 2308 | dependencies: 2309 | async-limiter "~1.0.0" 2310 | 2311 | ws@^7, ws@^7.5.10: 2312 | version "7.5.10" 2313 | resolved "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz" 2314 | integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== 2315 | 2316 | y18n@^5.0.5: 2317 | version "5.0.8" 2318 | resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" 2319 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 2320 | 2321 | yallist@^3.0.2: 2322 | version "3.1.1" 2323 | resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" 2324 | integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== 2325 | 2326 | yargs-parser@^21.1.1: 2327 | version "21.1.1" 2328 | resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" 2329 | integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 2330 | 2331 | yargs@^17.6.2: 2332 | version "17.7.2" 2333 | resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" 2334 | integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== 2335 | dependencies: 2336 | cliui "^8.0.1" 2337 | escalade "^3.1.1" 2338 | get-caller-file "^2.0.5" 2339 | require-directory "^2.1.1" 2340 | string-width "^4.2.3" 2341 | y18n "^5.0.5" 2342 | yargs-parser "^21.1.1" 2343 | 2344 | yn@3.1.1: 2345 | version "3.1.1" 2346 | resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" 2347 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 2348 | --------------------------------------------------------------------------------