vegan-ipsum
Version:
Generates passages of vegan-themed placeholder text suitable for use in web pages, graphics, and more. Works in the browser, NodeJS, and React Native.
1 lines • 22.8 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","names":[],"sources":["../src/constants/index.ts","../src/constants/words.ts","../src/util/env.ts","../src/util/strings.ts","../src/lib/generator.ts","../src/lib/VeganIpsum.ts","../src/index.ts"],"sourcesContent":["// Represents the HTML format for generated text.\nexport const FORMAT_HTML = 'html';\n// Represents the plain text format for generated text.\nexport const FORMAT_PLAIN = 'plain';\n// An array of supported formats for generated text.\nexport const FORMATS = [FORMAT_HTML, FORMAT_PLAIN];\n// Type representing the supported formats for generated text.\nexport type LoremFormat = 'plain' | 'html';\n\n/**\n * An object representing line endings for different platforms.\n *\n * - `POSIX`: Line ending for POSIX-compliant systems (`\\n`).\n * - `WIN32`: Line ending for Windows systems (`\\r\\n`).\n */\nexport const LINE_ENDINGS = { POSIX: '\\n', WIN32: '\\r\\n' };\n\n/**\n * An object representing supported platforms.\n *\n * - `DARWIN`: macOS platform identifier.\n * - `LINUX`: Linux platform identifier.\n * - `WIN32`: Windows platform identifier.\n */\nexport const SUPPORTED_PLATFORMS = { DARWIN: 'darwin', LINUX: 'linux', WIN32: 'win32' };\n\n/**\n * An object containing regular expressions for validating formats and units.\n *\n * - `FORMATS`: Matches supported text formats (`plain` or `html`), case-insensitive.\n * - `UNITS`: Matches supported unit types (`paragraphs`, `sentences`, `words`), case-insensitive.\n */\nexport const REGEX = { FORMATS: /^(plain|html)$/i, UNITS: /^(paragraphs|sentences|words)$/i };\n\n// Represents the unit type for words.\nexport const UNIT_WORDS = 'words';\n// Represents the unit type for sentences.\nexport const UNIT_SENTENCES = 'sentences';\n// Represents the unit type for paragraphs.\nexport const UNIT_PARAGRAPHS = 'paragraphs';\n// An array of supported unit types for generating text.\nexport const UNITS = [UNIT_WORDS, UNIT_SENTENCES, UNIT_PARAGRAPHS];\n// Type representing the supported unit types for generating text.\nexport type LoremUnit = 'words' | 'sentences' | 'paragraphs';\n\nexport default {\n FORMAT_HTML,\n FORMAT_PLAIN,\n FORMATS,\n LINE_ENDINGS,\n SUPPORTED_PLATFORMS,\n REGEX,\n UNIT_WORDS,\n UNIT_SENTENCES,\n UNIT_PARAGRAPHS,\n UNITS,\n};\n","/**\n * An array of default lorem ipsum words.\n */\nexport const DEFAULT_WORDS = [\n 'ad',\n 'adipisicing',\n 'aliqua',\n 'aliquip',\n 'amet',\n 'anim',\n 'aute',\n 'cillum',\n 'commodo',\n 'consectetur',\n 'consequat',\n 'culpa',\n 'cupidatat',\n 'deserunt',\n 'do',\n 'dolor',\n 'dolore',\n 'duis',\n 'ea',\n 'eiusmod',\n 'elit',\n 'enim',\n 'esse',\n 'est',\n 'et',\n 'eu',\n 'ex',\n 'excepteur',\n 'exercitation',\n 'fugiat',\n 'id',\n 'in',\n 'incididunt',\n 'ipsum',\n 'irure',\n 'labore',\n 'laboris',\n 'laborum',\n 'Lorem',\n 'magna',\n 'minim',\n 'mollit',\n 'nisi',\n 'non',\n 'nostrud',\n 'nulla',\n 'occaecat',\n 'officia',\n 'pariatur',\n 'proident',\n 'qui',\n 'quis',\n 'reprehenderit',\n 'sint',\n 'sit',\n 'sunt',\n 'tempor',\n 'ullamco',\n 'ut',\n 'velit',\n 'veniam',\n 'voluptate',\n];\n\n/**\n * An array of vegan-related words to accompany the default ones.\n */\nexport const VEGAN_WORDS = [\n 'plant',\n 'vegan',\n 'kindness',\n 'crueltyfree',\n 'herbivore',\n 'compassion',\n 'earth',\n 'dairyfree',\n 'justice',\n 'respect',\n 'peace',\n 'love',\n 'greens',\n 'fruit',\n 'vegetable',\n 'freedom',\n 'life',\n 'rights',\n 'sanctuary',\n 'nonviolence',\n 'care',\n 'conscious',\n 'ethics',\n 'climate',\n 'truth',\n 'plants',\n 'health',\n 'wholefood',\n 'clean',\n 'veggie',\n 'legumes',\n 'fiber',\n 'avocado',\n 'soy',\n 'tofu',\n 'tempeh',\n 'lentils',\n 'coconut',\n 'nutrients',\n 'plantpower',\n 'choices',\n 'saving',\n 'sustain',\n 'grain',\n 'beans',\n 'peas',\n 'quinoa',\n 'broccoli',\n 'kale',\n 'lettuce',\n 'radish',\n 'basil',\n 'mint',\n 'ginger',\n 'turmeric',\n 'natural',\n 'organic',\n 'kind',\n];\n\n/**\n * An array of kindness-related words to accompany the default ones.\n */\nexport const KINDNESS_WORDS = [\n 'kindness',\n 'compassion',\n 'empathy',\n 'mercy',\n 'respect',\n 'gentleness',\n 'care',\n 'love',\n 'peace',\n 'justice',\n 'fairness',\n 'awareness',\n 'forgiveness',\n 'integrity',\n 'nonviolence',\n 'harmony',\n 'mindfulness',\n 'humility',\n 'patience',\n 'sincerity',\n 'tolerance',\n 'understanding',\n 'altruism',\n 'grace',\n 'generosity',\n 'helpfulness',\n 'selflessness',\n 'support',\n 'comfort',\n 'sympathy',\n 'warmth',\n 'charity',\n 'unity',\n 'positivity',\n];\n\n/**\n * An array of vegan food-related words to accompany the default ones.\n */\nexport const VEGAN_FOOD_WORDS = [\n 'tofu',\n 'tempeh',\n 'soymilk',\n 'almondmilk',\n 'oatmilk',\n 'vegan-burger',\n 'vegan-cheese',\n 'jackfruit',\n 'quinoa',\n 'bowl',\n 'lentil',\n 'soup',\n 'smoothie',\n 'nut',\n 'chia',\n 'pudding',\n 'granola',\n 'plant-based',\n 'vegan-yogurt',\n 'vegan-pizza',\n 'coconut',\n 'chickpea',\n 'curry',\n 'soba',\n 'noodles',\n 'pancake',\n 'avocado',\n 'toast',\n 'vegetable',\n];\n\n/**\n * An array of vegetable-related words to accompany the default ones.\n */\nexport const VEGGIE_WORDS = [\n 'broccoli',\n 'kale',\n 'spinach',\n 'lettuce',\n 'cabbage',\n 'beetroot',\n 'carrot',\n 'radish',\n 'turnip',\n 'cauliflower',\n 'zucchini',\n 'bell',\n 'pepper',\n 'cucumber',\n 'eggplant',\n 'okra',\n 'tomato',\n 'green',\n 'beans',\n 'peas',\n 'sweet',\n 'potato',\n 'pumpkin',\n 'asparagus',\n 'artichoke',\n 'brussels',\n 'sprouts',\n 'chard',\n 'fennel',\n 'leek',\n 'parsnip',\n 'celery',\n 'shallot',\n 'corn',\n 'bamboo',\n 'shoots',\n 'beet',\n 'greens',\n 'mustard',\n 'scallions',\n 'radicchio',\n 'snow',\n 'onion',\n 'squash',\n];\n\n/**\n * Final array combining default lorem ipsum and vegan-themed words.\n */\nexport const WORDS = Array.from(\n new Set([...DEFAULT_WORDS, ...VEGAN_WORDS, ...KINDNESS_WORDS, ...VEGAN_FOOD_WORDS, ...VEGGIE_WORDS])\n);\n","import { SUPPORTED_PLATFORMS } from '../constants';\n\n/**\n * Determines if the current runtime environment is Node.js.\n *\n * @returns {boolean} `true` if the runtime is Node.js, otherwise `false`.\n */\nexport const isNode = (): boolean => {\n return typeof module !== 'undefined' && !!module.exports;\n};\n\n/**\n * Determines if the current runtime environment is React Native.\n *\n * @returns {boolean} `true` if the runtime is React Native, otherwise `false`.\n */\nexport const isReactNative = (): boolean => {\n try {\n return (navigator as Navigator & { product?: string }).product === 'ReactNative';\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n return false;\n }\n};\n\n/**\n * Determines if the current runtime environment is Windows.\n *\n * @returns {boolean} `true` if the process is running on a Windows platform, otherwise `false`.\n */\nexport const isWindows = (): boolean => {\n try {\n return process.platform === SUPPORTED_PLATFORMS.WIN32;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n return false;\n }\n};\n\nexport default { isNode, isReactNative, isWindows };\n","/**\n * Capitalizes the first character of a given string after trimming whitespace.\n *\n * @param {string} str - The input string to capitalize.\n *\n * @returns {string} The input string with the first character capitalized.\n */\nexport const capitalize = (str: string): string => {\n const trimmed = str.trim();\n return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);\n};\n\n/**\n * Creates an array of a specified length, where each element is its index.\n *\n * @param {number} length - The desired length of the array. Defaults to 0.\n *\n * @returns {number[]} An array of indexes from 0 to `length - 1`.\n */\nexport const rangeArray = (length: number = 0): number[] => {\n return [...Array(length)].map((_: unknown, index: number): number => index);\n};\n\n/**\n * Creates an array of strings of a specified length, using a provided string generator function.\n *\n * @param {number} length - The desired length of the array.\n * @param {() => string} makeString - A function that generates a string for each element.\n *\n * @returns {string[]} An array of strings of the specified length.\n */\nexport const fillArrayWith = (length: number, makeString: () => string): string[] => {\n const arr = rangeArray(length);\n return arr.map(() => makeString());\n};\n\nexport default { capitalize, rangeArray, fillArrayWith };\n","import { WORDS } from '../constants/words';\nimport { capitalize, rangeArray } from '../util';\n\n/**\n * Represents a range with minimum and maximum bounds.\n */\nexport interface Bounds {\n min: number;\n max: number;\n}\n\n/**\n * Type for a pseudo-random number generator function.\n */\nexport type Prng = () => number;\n\n/**\n * Type for a seedable random number generator constructor.\n */\nexport type SeedRandom = new (seed?: string) => Prng;\n\n/**\n * Interface for math utilities with a seedable random number generator.\n */\nexport interface Math {\n seedrandom: SeedRandom;\n}\n\n/**\n * Options for configuring the `Generator` class.\n */\nexport interface GeneratorOptions {\n /**\n * Range for the number of sentences per paragraph.\n */\n sentencesPerParagraph?: Bounds;\n\n /**\n * Range for the number of words per sentence.\n */\n wordsPerSentence?: Bounds;\n\n /**\n * Custom random number generator function.\n */\n random?: Prng;\n\n /**\n * Custom word list to use for generating text.\n */\n words?: string[];\n}\n\n/**\n * A class for generating random text (words, sentences, paragraphs).\n */\nclass Generator {\n public sentencesPerParagraph: Bounds;\n public wordsPerSentence: Bounds;\n public random: Prng;\n public words: string[];\n\n /**\n * Creates an instance of the `Generator` class.\n *\n * @param {GeneratorOptions} options - Configuration options for the generator.\n *\n * @throws {Error} If the minimum exceeds the maximum in the provided bounds.\n */\n constructor({\n sentencesPerParagraph = { max: 7, min: 3 },\n wordsPerSentence = { max: 15, min: 5 },\n random,\n words = WORDS,\n }: GeneratorOptions = {}) {\n if (sentencesPerParagraph.min > sentencesPerParagraph.max) {\n throw new Error(\n `Minimum number of sentences per paragraph (${\n sentencesPerParagraph.min\n }) cannot exceed maximum (${sentencesPerParagraph.max}).`\n );\n }\n\n if (wordsPerSentence.min > wordsPerSentence.max) {\n throw new Error(\n `Minimum number of words per sentence (${\n wordsPerSentence.min\n }) cannot exceed maximum (${wordsPerSentence.max}).`\n );\n }\n\n this.sentencesPerParagraph = sentencesPerParagraph;\n this.words = words;\n this.wordsPerSentence = wordsPerSentence;\n this.random = random || Math.random;\n }\n\n /**\n * Generates a random integer between the specified minimum and maximum values.\n *\n * @param {number} min - The minimum value (inclusive).\n * @param {number} max - The maximum value (inclusive).\n *\n * @returns {number} A random integer between `min` and `max`.\n */\n public generateRandomInteger(min: number, max: number): number {\n return Math.floor(this.random() * (max - min + 1) + min);\n }\n\n /**\n * Generates a random sequence of words.\n *\n * @param {number} [num] - The number of words to generate. If not provided, a random number is used.\n *\n * @returns {string} A string of randomly generated words.\n */\n public generateRandomWords(num?: number): string {\n const { min, max } = this.wordsPerSentence;\n const length = num || this.generateRandomInteger(min, max);\n return rangeArray(length)\n .reduce((accumulator: string): string => {\n return `${this.pluckRandomWord()} ${accumulator}`;\n }, '')\n .trim();\n }\n\n /**\n * Generates a random sentence.\n *\n * @param {number} [num] - The number of words in the sentence. If not provided, a random number is used.\n *\n * @returns {string} A randomly generated sentence.\n */\n public generateRandomSentence(num?: number): string {\n return `${capitalize(this.generateRandomWords(num))}.`;\n }\n\n /**\n * Generates a random paragraph.\n *\n * @param {number} [num] - The number of sentences in the paragraph. If not provided, a random number is used.\n *\n * @returns {string} A randomly generated paragraph.\n */\n public generateRandomParagraph(num?: number): string {\n const { min, max } = this.sentencesPerParagraph;\n const length = num || this.generateRandomInteger(min, max);\n return rangeArray(length)\n .reduce((accumulator: string): string => {\n return `${this.generateRandomSentence()} ${accumulator}`;\n }, '')\n .trim();\n }\n\n /**\n * Selects a random word from the word list.\n *\n * @returns {string} A randomly selected word.\n */\n public pluckRandomWord(): string {\n const min = 0;\n const max = this.words.length - 1;\n const index = this.generateRandomInteger(min, max);\n return this.words[index];\n }\n}\n\nexport default Generator;\n","import { type LoremFormat, FORMAT_HTML, FORMAT_PLAIN, FORMATS, LINE_ENDINGS } from '../constants';\nimport { isNode, isReactNative, isWindows, fillArrayWith } from '../util';\nimport Generator, { type GeneratorOptions } from './generator';\n\n/**\n * A class for generating vegan ipsum text in various formats and units.\n */\nclass VeganIpsum {\n public generator: Generator;\n\n /**\n * Creates an instance of the `VeganIpsum` class.\n *\n * @param {GeneratorOptions} options - Configuration options for the text generator.\n * @param {LoremFormat} format - The format of the generated text (e.g., plain or HTML).\n * @param {string} [suffix] - A custom line ending or suffix for the generated text.\n *\n * @throws {Error} If the provided format is invalid.\n */\n constructor(\n options: GeneratorOptions = {},\n public format: LoremFormat = FORMAT_PLAIN,\n public suffix?: string\n ) {\n if (FORMATS.indexOf(format.toLowerCase()) === -1) {\n throw new Error(`${format} is an invalid format. Please use ${FORMATS.join(' or ')}.`);\n }\n this.generator = new Generator(options);\n this.suffix = suffix;\n }\n\n /**\n * Determines the appropriate line ending based on the environment and suffix.\n *\n * @returns {string} The line ending to use.\n */\n public getLineEnding(): string {\n if (this.suffix) {\n return this.suffix;\n }\n\n if (!isReactNative() && isNode() && isWindows()) {\n return LINE_ENDINGS.WIN32;\n }\n\n return LINE_ENDINGS.POSIX;\n }\n\n /**\n * Formats a single string based on the specified format (e.g., wraps in HTML tags if needed).\n *\n * @param {string} str - The string to format.\n *\n * @returns {string} The formatted string.\n */\n public formatString(str: string): string {\n if (this.format === FORMAT_HTML) {\n return `<p>${str}</p>`;\n }\n return str;\n }\n\n /**\n * Formats an array of strings based on the specified format.\n *\n * @param {string[]} strings - The array of strings to format.\n *\n * @returns {string[]} The array of formatted strings.\n */\n public formatStrings(strings: string[]): string[] {\n return strings.map((str) => this.formatString(str));\n }\n\n /**\n * Generates a specified number of words and formats them.\n *\n * @param {number} [num] - The number of words to generate. If not provided, a random number is used.\n *\n * @returns {string} A formatted string of generated words.\n */\n public generateWords(num?: number): string {\n return this.formatString(this.generator.generateRandomWords(num));\n }\n\n /**\n * Generates a specified number of sentences and formats them.\n *\n * @param {number} [num] - The number of sentences to generate. If not provided, a random number is used.\n *\n * @returns {string} A formatted string of generated sentences.\n */\n public generateSentences(num?: number): string {\n return this.formatString(this.generator.generateRandomParagraph(num));\n }\n\n /**\n * Generates a specified number of paragraphs and formats them.\n *\n * @param {number} num - The number of paragraphs to generate.\n *\n * @returns {string} A formatted string of generated paragraphs.\n */\n public generateParagraphs(num: number): string {\n const makeString = this.generator.generateRandomParagraph.bind(this.generator);\n return this.formatStrings(fillArrayWith(num, makeString)).join(this.getLineEnding());\n }\n}\n\nexport default VeganIpsum;\n","import {\n type LoremUnit,\n type LoremFormat,\n FORMAT_PLAIN,\n UNIT_PARAGRAPHS,\n UNIT_SENTENCES,\n UNIT_WORDS,\n} from './constants';\nimport { WORDS } from './constants/words';\nimport { type Prng } from './lib/generator';\nimport VeganIpsum from './lib/VeganIpsum';\n\n/**\n * Parameters for generating vegan ipsum text.\n */\nexport interface VeganIpsumParams {\n /**\n * Number of units to generate (e.g., paragraphs, sentences, or words).\n *\n * @default 1\n */\n count?: number;\n\n /**\n * Format of the generated text (e.g., plain text or HTML).\n *\n * @default FORMAT_PLAIN\n */\n format?: LoremFormat;\n\n /**\n * Minimum number of sentences per paragraph.\n *\n * @default 3\n */\n paragraphLowerBound?: number;\n\n /**\n * Maximum number of sentences per paragraph.\n *\n * @default 7\n */\n paragraphUpperBound?: number;\n\n /**\n * Custom random number generator.\n */\n random?: Prng;\n\n /**\n * Minimum number of words per sentence.\n *\n * @default 5\n */\n sentenceLowerBound?: number;\n\n /**\n * Maximum number of words per sentence.\n *\n * @default 15\n */\n sentenceUpperBound?: number;\n\n /**\n * Unit type for the generated text (e.g., paragraphs, sentences, or words).\n *\n * @default UNIT_SENTENCES\n */\n units?: LoremUnit;\n\n /**\n * Custom word list to use for generating text.\n *\n * @default WORDS\n */\n words?: string[];\n\n /**\n * Suffix to append to the generated text.\n *\n * @default \"\"\n */\n suffix?: string;\n}\n\n/**\n * Generates vegan ipsum text based on the provided parameters.\n *\n * @param {VeganIpsumParams} params - Configuration options for generating vegan ipsum text.\n *\n * @returns {string} Generated vegan ipsum text as a string.\n */\nconst veganIpsum = ({\n count = 1,\n random,\n format = FORMAT_PLAIN,\n paragraphLowerBound = 3,\n paragraphUpperBound = 7,\n sentenceLowerBound = 5,\n sentenceUpperBound = 15,\n units = UNIT_SENTENCES,\n words = WORDS,\n suffix = '',\n}: VeganIpsumParams = {}): string => {\n const options: {\n random?: Prng;\n sentencesPerParagraph: { max: number; min: number };\n words: string[];\n wordsPerSentence: { max: number; min: number };\n } = {\n random,\n sentencesPerParagraph: { max: paragraphUpperBound, min: paragraphLowerBound },\n words,\n wordsPerSentence: { max: sentenceUpperBound, min: sentenceLowerBound },\n };\n\n const lorem: VeganIpsum = new VeganIpsum(options, format, suffix);\n\n switch (units) {\n case UNIT_PARAGRAPHS:\n return lorem.generateParagraphs(count);\n case UNIT_SENTENCES:\n return lorem.generateSentences(count);\n case UNIT_WORDS:\n return lorem.generateWords(count);\n default:\n return '';\n }\n};\n\nexport { veganIpsum, VeganIpsum };\n"],"mappings":";AACA,IAAa,IAAc,QAEd,IAAe,SAEf,IAAU,CAAC,GAAa,CAAY,GAUpC,IAAe;CAAE,OAAO;CAAM,OAAO;AAAO,GAS5C,IAAsB;CAAE,QAAQ;CAAU,OAAO;CAAS,OAAO;AAAQ,GAWzE,IAAa,SAEb,IAAiB,aAEjB,IAAkB,cCpClB,IAAgB,qbA+D7B,GAKa,IAAc,6cA2D3B,GAKa,IAAiB,iVAmC9B,GAKa,IAAmB,yQA8BhC,GAKa,IAAe,+VA6C5B,GAKa,IAAQ,MAAM,KACzB,IAAI,IAAI;CAAC,GAAG;CAAe,GAAG;CAAa,GAAG;CAAgB,GAAG;CAAkB,GAAG;AAAY,CAAC,CACrG,GC/Pa,UACJ,OAAO,SAAW,OAAe,CAAC,CAAC,OAAO,SAQtC,UAA+B;CAC1C,IAAI;EACF,OAAQ,UAA+C,YAAY;CAErE,QAAY;EACV,OAAO;CACT;AACF,GAOa,UAA2B;CACtC,IAAI;EACF,OAAO,QAAQ,aAAa,EAAoB;CAElD,QAAY;EACV,OAAO;CACT;AACF,GC9Ba,KAAc,MAAwB;CACjD,IAAM,IAAU,EAAI,KAAK;CACzB,OAAO,EAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,EAAQ,MAAM,CAAC;AAC1D,GASa,KAAc,IAAiB,MACnC,CAAC,GAAG,MAAM,CAAM,CAAC,EAAE,KAAK,GAAY,MAA0B,CAAK,GAW/D,KAAiB,GAAgB,MAChC,EAAW,CAChB,EAAI,UAAU,EAAW,CAAC,GCuB7B,IAAN,MAAgB;CACd;CACA;CACA;CACA;CASA,YAAY,EACV,2BAAwB;EAAE,KAAK;EAAG,KAAK;CAAE,GACzC,sBAAmB;EAAE,KAAK;EAAI,KAAK;CAAE,GACrC,WACA,WAAQ,MACY,CAAC,GAAG;EACxB,IAAI,EAAsB,MAAM,EAAsB,KACpD,MAAU,MACR,8CACE,EAAsB,IACvB,2BAA2B,EAAsB,IAAI,GACxD;EAGF,IAAI,EAAiB,MAAM,EAAiB,KAC1C,MAAU,MACR,yCACE,EAAiB,IAClB,2BAA2B,EAAiB,IAAI,GACnD;EAMF,AAHA,KAAK,wBAAwB,GAC7B,KAAK,QAAQ,GACb,KAAK,mBAAmB,GACxB,KAAK,SAAS,KAAU,KAAK;CAC/B;CAUA,sBAA6B,GAAa,GAAqB;EAC7D,OAAO,KAAK,MAAM,KAAK,OAAO,KAAK,IAAM,IAAM,KAAK,CAAG;CACzD;CASA,oBAA2B,GAAsB;EAC/C,IAAM,EAAE,QAAK,WAAQ,KAAK;EAE1B,OAAO,EADQ,KAAO,KAAK,sBAAsB,GAAK,CAAG,CACjC,EACrB,QAAQ,MACA,GAAG,KAAK,gBAAgB,EAAE,GAAG,KACnC,EAAE,EACJ,KAAK;CACV;CASA,uBAA8B,GAAsB;EAClD,OAAO,GAAG,EAAW,KAAK,oBAAoB,CAAG,CAAC,EAAE;CACtD;CASA,wBAA+B,GAAsB;EACnD,IAAM,EAAE,QAAK,WAAQ,KAAK;EAE1B,OAAO,EADQ,KAAO,KAAK,sBAAsB,GAAK,CAAG,CACjC,EACrB,QAAQ,MACA,GAAG,KAAK,uBAAuB,EAAE,GAAG,KAC1C,EAAE,EACJ,KAAK;CACV;CAOA,kBAAiC;EAC/B,IACM,IAAM,KAAK,MAAM,SAAS,GAC1B,IAAQ,KAAK,sBAAsB,GAAK,CAAG;EACjD,OAAO,KAAK,MAAM;CACpB;AACF,GC9JM,IAAN,MAAiB;CAcN;CACA;CAdT;CAWA,YACE,IAA4B,CAAC,GAC7B,IAA6B,GAC7B,GACA;EACA,IAHO,KAAA,SAAA,GACA,KAAA,SAAA,GAEH,EAAQ,QAAQ,EAAO,YAAY,CAAC,MAAM,IAC5C,MAAU,MAAM,GAAG,EAAO,oCAAoC,EAAQ,KAAK,MAAM,EAAE,EAAE;EAGvF,AADA,KAAK,YAAY,IAAI,EAAU,CAAO,GACtC,KAAK,SAAS;CAChB;CAOA,gBAA+B;EAS7B,OARI,KAAK,SACA,KAAK,SAGV,CAAC,EAAc,KAAK,EAAO,KAAK,EAAU,IACrC,EAAa,QAGf,EAAa;CACtB;CASA,aAAoB,GAAqB;EAIvC,OAHI,KAAK,WAAA,SACA,MAAM,EAAI,QAEZ;CACT;CASA,cAAqB,GAA6B;EAChD,OAAO,EAAQ,KAAK,MAAQ,KAAK,aAAa,CAAG,CAAC;CACpD;CASA,cAAqB,GAAsB;EACzC,OAAO,KAAK,aAAa,KAAK,UAAU,oBAAoB,CAAG,CAAC;CAClE;CASA,kBAAyB,GAAsB;EAC7C,OAAO,KAAK,aAAa,KAAK,UAAU,wBAAwB,CAAG,CAAC;CACtE;CASA,mBAA0B,GAAqB;EAC7C,IAAM,IAAa,KAAK,UAAU,wBAAwB,KAAK,KAAK,SAAS;EAC7E,OAAO,KAAK,cAAc,EAAc,GAAK,CAAU,CAAC,EAAE,KAAK,KAAK,cAAc,CAAC;CACrF;AACF,GCdM,KAAc,EAClB,WAAQ,GACR,WACA,YAAS,GACT,yBAAsB,GACtB,yBAAsB,GACtB,wBAAqB,GACrB,wBAAqB,IACrB,WAAQ,GACR,WAAQ,GACR,YAAS,OACW,CAAC,MAAc;CAanC,IAAM,IAAoB,IAAI,EAAW;EANvC;EACA,uBAAuB;GAAE,KAAK;GAAqB,KAAK;EAAoB;EAC5E;EACA,kBAAkB;GAAE,KAAK;GAAoB,KAAK;EAAmB;CAG9B,GAAS,GAAQ,CAAM;CAEhE,QAAQ,GAAR;EACE,KAAK,GACH,OAAO,EAAM,mBAAmB,CAAK;EACvC,KAAK,GACH,OAAO,EAAM,kBAAkB,CAAK;EACtC,KAAK,GACH,OAAO,EAAM,cAAc,CAAK;EAClC,SACE,OAAO;CACX;AACF"}