@dialpad/dialtone
Version:
Dialpad's Dialtone design system monorepo
1 lines • 19.3 kB
Source Map (JSON)
{"version":3,"file":"utils.cjs","sources":["../../common/utils/index.js"],"sourcesContent":["import {\n DEFAULT_PREFIX,\n DEFAULT_VALIDATION_MESSAGE_TYPE,\n VALIDATION_MESSAGE_TYPES,\n} from '../constants';\nimport Vue from 'vue';\n\nlet UNIQUE_ID_COUNTER = 0;\nlet TIMER;\n\n// selector to find focusable not hidden inputs\nconst FOCUSABLE_SELECTOR_NOT_HIDDEN = 'input:not([type=hidden]):not(:disabled)';\n// selector to find focusable not disables elements\nconst FOCUSABLE_SELECTOR_NOT_DISABLED = 'select:not(:disabled),textarea:not(:disabled),button:not(:disabled)';\n// // selector to find focusable not hidden and disabled elements\nconst FOCUSABLE_SELECTOR_NOT_HIDDEN_DISABLED = `${FOCUSABLE_SELECTOR_NOT_HIDDEN},${FOCUSABLE_SELECTOR_NOT_DISABLED}`;\n// selector to find focusable elements\nconst FOCUSABLE_SELECTOR = `a,frame,iframe,${FOCUSABLE_SELECTOR_NOT_HIDDEN_DISABLED},*[tabindex]`;\n\nconst scheduler = typeof setImmediate === 'function' ? setImmediate : setTimeout;\n\nexport function getUniqueString (prefix = DEFAULT_PREFIX) {\n return `${prefix}${UNIQUE_ID_COUNTER++}`;\n}\n\n/**\n * Returns a random element from array\n * @param array - the array to return a random element from\n * @param {string} seed - use a string to seed the randomization, so it returns the same element each time\n * based on that string.\n * @returns {*} - the random element\n */\nexport function getRandomElement (array, seed) {\n if (seed) {\n const hash = javaHashCode(seed);\n return array[Math.abs(hash) % array.length];\n } else {\n return array[getRandomInt(array.length)];\n }\n}\n\n/**\n * Returns a hash code for a string.\n * (Compatible to Java's String.hashCode())\n * We use this algo to be in sync with android.\n *\n * The hash code for a string object is computed as\n * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]\n * using number arithmetic, where s[i] is the i th character\n * of the given string, n is the length of the string,\n * and ^ indicates exponentiation.\n * (The hash value of the empty string is zero.)\n *\n * @param {string} str a string\n * @return {number} a hash code value for the given string.\n */\nexport function javaHashCode (str) {\n let h;\n for (let i = 0; i < str.length; i++) {\n h = Math.imul(31, h) + str.charCodeAt(i) | 0;\n }\n\n return h;\n}\n\n/**\n * Generate a random integer\n * @param {number} max - max range of integer to generate\n * @returns {number} randomly generated integer between 0 and max\n */\nexport function getRandomInt (max) {\n return Math.floor(Math.random() * max);\n}\n\nexport function formatMessages (messages) {\n if (!messages) {\n return [];\n }\n\n return messages.map(message => {\n if (typeof message === 'string') {\n return {\n message,\n type: DEFAULT_VALIDATION_MESSAGE_TYPE,\n };\n }\n\n return message;\n });\n}\n\nexport function filterFormattedMessages (formattedMessages) {\n const validationState = getValidationState(formattedMessages);\n\n if (!formattedMessages || !validationState) {\n return [];\n }\n\n return formattedMessages.filter(message => !!message.message && message.type === validationState);\n}\n\n/*\n * The priority order of message types is as flows: 'error' > 'warning' > 'success'.\n * If any message of type 'error' is present in messages, the input state is considered\n * to be 'error', then 'warning' and lastly 'success'.\n */\nexport function getValidationState (formattedMessages) {\n if (!formattedMessages) {\n return null;\n }\n\n if (hasFormattedMessageOfType(formattedMessages, VALIDATION_MESSAGE_TYPES.ERROR)) {\n return VALIDATION_MESSAGE_TYPES.ERROR;\n }\n if (hasFormattedMessageOfType(formattedMessages, VALIDATION_MESSAGE_TYPES.WARNING)) {\n return VALIDATION_MESSAGE_TYPES.WARNING;\n }\n if (hasFormattedMessageOfType(formattedMessages, VALIDATION_MESSAGE_TYPES.SUCCESS)) {\n return VALIDATION_MESSAGE_TYPES.SUCCESS;\n }\n\n return null;\n}\n\nexport function hasFormattedMessageOfType (formattedMessages, messageType) {\n if (!formattedMessages || !messageType) {\n return false;\n }\n\n return formattedMessages.some(message => message?.type === messageType);\n}\n\nexport function findFirstFocusableNode (element) {\n return element?.querySelector(FOCUSABLE_SELECTOR);\n}\n\n/* html-fragment component:\n * To render html without wrapping in another element as when using v-html.\n * props: html\n */\nexport const htmlFragment = {\n name: 'html-fragment',\n functional: true,\n props: ['html'],\n render (h, ctx) {\n return new Vue({\n // eslint-disable-next-line vue/multi-word-component-names\n name: 'Inner',\n beforeCreate () { this.$createElement = h; },\n template: `<div>${ctx.props.html}</div>`,\n }).$mount()._vnode.children;\n },\n};\n\nexport const flushPromises = () => {\n return new Promise((resolve) => {\n scheduler(resolve);\n });\n};\n\n/**\n * Transform a string from kebab-case to PascalCase\n * @param string\n * @returns {string}\n */\nexport const kebabCaseToPascalCase = (string) => {\n return string?.toLowerCase()\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n};\n\n/**\n * Transform a string from PascalCase to kebab-case\n * @param string\n * @returns {string}\n */\nexport const pascalCaseToKebabCase = (string) => {\n return string\n .replace(/\\.?([A-Z0-9]+)/g, (x, y) => '-' + y.toLowerCase())\n .replace(/^-/, '');\n};\n\n/*\n* Set's a global timer to debounce the execution of a function.\n* @param { object } func - the function that is going to be called after timeout\n* @param { number } [timeout=300] timeout\n* */\nexport function debounce (func, timeout = 300) {\n clearTimeout(TIMER);\n TIMER = setTimeout(func, timeout);\n}\n\n/**\n * Checks if the element is out of the viewport\n * https://gomakethings.com/how-to-check-if-any-part-of-an-element-is-out-of-the-viewport-with-vanilla-js/\n * @param {HTMLElement} element The element to check\n * @return {Object} A set of booleans for each side of the element\n */\n\nexport function isOutOfViewPort (element) {\n const bounding = element.getBoundingClientRect();\n\n const isOut = {\n top: bounding.top < 0,\n left: bounding.left < 0,\n bottom: bounding.bottom > (window.innerHeight || document.documentElement.clientHeight),\n right: bounding.right > (window.innerWidth || document.documentElement.clientWidth),\n };\n isOut.any = Object.values(isOut).some(val => val);\n isOut.all = Object.values(isOut).every(val => val);\n return isOut;\n}\n\n// match valid characters for a domain name followed by a dot, e.g. \"dialpad.\"\nconst domainNameRegex = /(?:(?:[^\\s!@#$%^&*()_=+[\\]{}\\\\|;:'\",.<>/?]+)\\.)/;\n\n// match valid TLDs for a hostname (outdated list from ~2017)\nconst tldRegerx = new RegExp(\n '(?:' +\n 'com|ru|org|net|de|jp|uk|br|it|pl|fr|in|au|ir|info|nl|cn|es|cz|kr|ca|eu|ua|co|gr|' +\n 'za|ro|biz|ch|se|tw|mx|vn|hu|be|tr|at|dk|tv|me|ar|sk|no|us|fi|id|cl|xyz|io|pt|by|' +\n 'il|ie|nz|kz|hk|lt|cc|my|sg|club|bg|edu|рф|pk|su|top|th|hr|rs|pe|pro|si|az|lv|pw|' +\n 'ae|ph|online|ng|ee|ws|ve|cat' +\n ')',\n);\n\n// match valid IPv4 addresses, e.g. \"192.158.1.38\"\nconst ipv4Regex = new RegExp(\n '(?:(?:[0-9]|[1-9]\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5])\\\\.){3}' +\n '(?:[0-9]|[1-9]\\\\d|1\\\\d{2}|2[0-4]\\\\d|25[0-5])',\n);\n\n// match hostnames OR IPv4 addresses, e.g. \"dialpad.com\" or \"192.158.1.38\"\nconst hostnameOrIpRegex = new RegExp(\n '(?:' +\n [\n [\n domainNameRegex.source,\n tldRegerx.source,\n ].join('+'),\n ipv4Regex.source,\n ].join('|') +\n ')',\n);\n\n// match URL paths, e.g. \"/news\"\nconst urlPathRegex = /(?:(?:[;/][^#?<>\\s]*)?)/;\n\n// match URL queries and fragments, e.g. \"?cache=1&new=true\" or \"#heading1\"\nconst urlQueryOrFragmentRegex = /(?:(?:\\?[^#<>\\s]+)?(?:#[^<>\\s]+)?)/;\n\n// match complete hostnames or IPv4 addresses without a protocol and with optional\n// URL paths, queries and fragments e.g. \"dialpad.com/news?cache=1#heading1\"\nconst urlWithoutProtocolRegex = new RegExp(\n '\\\\b' +\n [\n hostnameOrIpRegex.source,\n urlPathRegex.source,\n urlQueryOrFragmentRegex.source,\n '(?!\\\\w)',\n ].join('+'),\n);\n\n// match complete hostnames with protocols and optional URL paths, queries and fragments,\n// e.g. \"ws://localhost:9010\" or \"https://dialpad.com/news?cache=1#heading1\"\nconst urlWithProtocolRegex = /\\b[a-z\\d.-]+:\\/\\/[^<>\\s]+/;\n\n// match email addresses with an optional \"mailto:\" prefix and URL queries, e.g.\n// \"hey@dialpad.com\" or \"mailto:hey@dialpad.com?subject=Hi&body=Hey%20there\"\nconst emailAddressRegex = new RegExp(\n '(?:mailto:)?' +\n '[a-z0-9!#$%&\\'*+/=?^_`{|}~-]+(?:\\\\.[a-z0-9!#$%&\\'*+/=?^_`{|}~-]+)*@' +\n [\n hostnameOrIpRegex.source,\n urlQueryOrFragmentRegex.source,\n ].join('+') +\n '(?!\\\\w)',\n);\n\n/**\n * Match phone numbers, e.g. \"765-8813\", \"(778) 765-8813\" or \"+17787658813\".\n * @param {number} minLength\n * @param {number} maxLength\n * @returns {RegExp}\n */\nexport function getPhoneNumberRegex (minLength = 7, maxLength = 15) {\n // Some older browser versions don't support lookbehind, so provide a RegExp\n // version without it. It fails just one test case, so IMO it's still good\n // enough to use. https://caniuse.com/js-regexp-lookbehind\n try {\n return new RegExp(\n '(?:^|(?<=\\\\W))' +\n '(?![\\\\s\\\\-])\\\\+?(?:[0-9()\\\\- \\\\t]' +\n `{${minLength},${maxLength}}` +\n ')(?=\\\\b)(?=\\\\W(?=\\\\W|$)|\\\\s|$)',\n );\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn('This browser doesn\\'t support regex lookahead/lookbehind');\n }\n\n return new RegExp(\n '(?![\\\\s\\\\-])\\\\+?(?:[0-9()\\\\- \\\\t]' +\n `{${minLength},${maxLength}}` +\n ')(?=\\\\b)(?=\\\\W(?=\\\\W|$)|\\\\s|$)',\n );\n}\n\nconst phoneNumberRegex = getPhoneNumberRegex();\n\n// match all link types\nexport const linkRegex = new RegExp(\n [\n urlWithoutProtocolRegex.source,\n urlWithProtocolRegex.source,\n emailAddressRegex.source,\n phoneNumberRegex.source,\n ].join('|'),\n 'gi',\n);\n\n/**\n * Check if a string is a phone number. Validates only exact matches.\n * @param {string|number} input\n * @returns {boolean}\n */\nexport function isPhoneNumber (input) {\n if (!input || (!['string', 'number'].includes(typeof input))) return false;\n input = input.toString();\n return phoneNumberRegex.exec(input)?.[0] === input;\n}\n\n/**\n * Check if a string is an URL. Validates only exact matches.\n * @param {string} input\n * @returns {boolean}\n */\nexport function isURL (input) {\n if (!input || typeof input !== 'string') return false;\n return urlWithoutProtocolRegex.exec(input)?.[0] === input ||\n urlWithProtocolRegex.exec(input)?.[0] === input;\n}\n\n/**\n * Check if a string is an email address. Validates only exact matches.\n * @param {string} input\n * @returns {boolean}\n */\nexport function isEmailAddress (input) {\n if (!input || typeof input !== 'string') return false;\n return emailAddressRegex.exec(input)?.[0] === input;\n}\n\n/**\n * Concatenate a string removing null or undefined elements\n * avoiding parsing them as string with template strings\n * @param {Array} elements\n * @returns {String}\n */\nexport function safeConcatStrings (elements) {\n return elements.filter(str => !!str).join(' ');\n}\n\n/**\n * Locale safe function to capitalize the first letter of a string.\n * @param {string} str the string to capitalize the first letter of\n * @param {string} locale a string representing the locale to be used. Defaults to 'en-US'\n * @returns The passed in string with the first letter capitalized\n */\nexport function capitalizeFirstLetter (str, locale = 'en-US') {\n return str.replace(/^\\p{CWU}/u, char => char.toLocaleUpperCase(locale));\n}\n\n/**\n * Warns if the component is not mounted properly. Useful for tests.\n * @param {HTMLElement} componentRef - the component reference\n * @param {string} componentName - the component name\n */\n// eslint-disable-next-line complexity\nexport function warnIfUnmounted (componentRef, componentName) {\n if (typeof process === 'undefined') return;\n if (process.env.NODE_ENV !== 'test') return;\n if (!componentRef || !(componentRef instanceof HTMLElement) || !document?.body) return;\n if (!document.body.contains(componentRef)) {\n console.warn(`The ${componentName} component is not attached to the document body. This may cause issues.`);\n }\n}\n\n/**\n * checks whether the dt-scrollbar is being used on the root element.\n * @param rootElement {HTMLElement}\n * @returns {boolean}\n */\nfunction isDtScrollbarInUse (rootElement = document.documentElement) {\n if (rootElement.hasAttribute('data-overlayscrollbars')) {\n return true;\n }\n return false;\n}\n\n/**\n * This will disable scrolling on the root element regardless of whether you are using dt-scrollbar or not.\n * @param rootElement {HTMLElement}\n */\nexport function disableRootScrolling (rootElement = document.documentElement) {\n if (isDtScrollbarInUse(rootElement)) {\n rootElement.classList.add('d-scrollbar-disabled');\n } else {\n rootElement.classList.add('d-of-hidden');\n }\n}\n\n/**\n * This will enable scrolling on the root element regardless of whether you are using dt-scrollbar or not.\n * @param rootElement {HTMLElement}\n */\nexport function enableRootScrolling (rootElement = document.documentElement) {\n if (isDtScrollbarInUse(rootElement)) {\n rootElement.classList.remove('d-scrollbar-disabled');\n } else {\n rootElement.classList.remove('d-of-hidden');\n }\n}\n\nexport default {\n getUniqueString,\n getRandomElement,\n getRandomInt,\n formatMessages,\n filterFormattedMessages,\n hasFormattedMessageOfType,\n getValidationState,\n htmlFragment,\n flushPromises,\n kebabCaseToPascalCase,\n debounce,\n isOutOfViewPort,\n getPhoneNumberRegex,\n linkRegex,\n isEmailAddress,\n isPhoneNumber,\n isURL,\n safeConcatStrings,\n capitalizeFirstLetter,\n disableRootScrolling,\n enableRootScrolling,\n};\n"],"names":["DEFAULT_PREFIX","DEFAULT_VALIDATION_MESSAGE_TYPE","VALIDATION_MESSAGE_TYPES"],"mappings":";;;;AAOA,IAAI,oBAAoB;AACxB,IAAI;AAGJ,MAAM,gCAAgC;AAEtC,MAAM,kCAAkC;AAExC,MAAM,yCAAyC,GAAG,6BAA6B,IAAI,+BAA+B;AAElH,MAAM,qBAAqB,kBAAkB,sCAAsC;AAEnF,MAAM,YAAY,OAAO,iBAAiB,aAAa,eAAe;AAE/D,SAAS,gBAAiB,SAASA,iCAAgB;AACxD,SAAO,GAAG,MAAM,GAAG,mBAAmB;AACxC;AASO,SAAS,iBAAkB,OAAO,MAAM;AAC7C,MAAI,MAAM;AACR,UAAM,OAAO,aAAa,IAAI;AAC9B,WAAO,MAAM,KAAK,IAAI,IAAI,IAAI,MAAM,MAAM;AAAA,EAC9C,OAAS;AACL,WAAO,MAAM,aAAa,MAAM,MAAM,CAAC;AAAA,EACxC;AACH;AAiBO,SAAS,aAAc,KAAK;AACjC,MAAI;AACJ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,QAAI,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI;AAAA,EAC5C;AAED,SAAO;AACT;AAOO,SAAS,aAAc,KAAK;AACjC,SAAO,KAAK,MAAM,KAAK,OAAQ,IAAG,GAAG;AACvC;AAEO,SAAS,eAAgB,UAAU;AACxC,MAAI,CAAC,UAAU;AACb,WAAO;EACR;AAED,SAAO,SAAS,IAAI,aAAW;AAC7B,QAAI,OAAO,YAAY,UAAU;AAC/B,aAAO;AAAA,QACL;AAAA,QACA,MAAMC,iBAA+B;AAAA,MAC7C;AAAA,IACK;AAED,WAAO;AAAA,EACX,CAAG;AACH;AAEO,SAAS,wBAAyB,mBAAmB;AAC1D,QAAM,kBAAkB,mBAAmB,iBAAiB;AAE5D,MAAI,CAAC,qBAAqB,CAAC,iBAAiB;AAC1C,WAAO;EACR;AAED,SAAO,kBAAkB,OAAO,aAAW,CAAC,CAAC,QAAQ,WAAW,QAAQ,SAAS,eAAe;AAClG;AAOO,SAAS,mBAAoB,mBAAmB;AACrD,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACR;AAED,MAAI,0BAA0B,mBAAmBC,iBAAwB,yBAAC,KAAK,GAAG;AAChF,WAAOA,iBAAAA,yBAAyB;AAAA,EACjC;AACD,MAAI,0BAA0B,mBAAmBA,iBAAwB,yBAAC,OAAO,GAAG;AAClF,WAAOA,iBAAAA,yBAAyB;AAAA,EACjC;AACD,MAAI,0BAA0B,mBAAmBA,iBAAwB,yBAAC,OAAO,GAAG;AAClF,WAAOA,iBAAAA,yBAAyB;AAAA,EACjC;AAED,SAAO;AACT;AAEO,SAAS,0BAA2B,mBAAmB,aAAa;AACzE,MAAI,CAAC,qBAAqB,CAAC,aAAa;AACtC,WAAO;AAAA,EACR;AAED,SAAO,kBAAkB,KAAK,cAAW,mCAAS,UAAS,WAAW;AACxE;AAEO,SAAS,uBAAwB,SAAS;AAC/C,SAAO,mCAAS,cAAc;AAChC;AAMY,MAAC,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,OAAO,CAAC,MAAM;AAAA,EACd,OAAQ,GAAG,KAAK;AACd,WAAO,IAAI,IAAI;AAAA;AAAA,MAEb,MAAM;AAAA,MACN,eAAgB;AAAE,aAAK,iBAAiB;AAAA,MAAI;AAAA,MAC5C,UAAU,QAAQ,IAAI,MAAM,IAAI;AAAA,IACjC,CAAA,EAAE,OAAM,EAAG,OAAO;AAAA,EACpB;AACH;AAEY,MAAC,gBAAgB,MAAM;AACjC,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,cAAU,OAAO;AAAA,EACrB,CAAG;AACH;AAOY,MAAC,wBAAwB,CAAC,WAAW;AAC/C,SAAO,iCAAQ,cACZ,MAAM,KACN,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAW,IAAK,KAAK,MAAM,CAAC,GACvD,KAAK;AACV;AAOY,MAAC,wBAAwB,CAAC,WAAW;AAC/C,SAAO,OACJ,QAAQ,mBAAmB,CAAC,GAAG,MAAM,MAAM,EAAE,aAAa,EAC1D,QAAQ,MAAM,EAAE;AACrB;AAOO,SAAS,SAAU,MAAM,UAAU,KAAK;AAC7C,eAAa,KAAK;AAClB,UAAQ,WAAW,MAAM,OAAO;AAClC;AASO,SAAS,gBAAiB,SAAS;AACxC,QAAM,WAAW,QAAQ;AAEzB,QAAM,QAAQ;AAAA,IACZ,KAAK,SAAS,MAAM;AAAA,IACpB,MAAM,SAAS,OAAO;AAAA,IACtB,QAAQ,SAAS,UAAU,OAAO,eAAe,SAAS,gBAAgB;AAAA,IAC1E,OAAO,SAAS,SAAS,OAAO,cAAc,SAAS,gBAAgB;AAAA,EAC3E;AACE,QAAM,MAAM,OAAO,OAAO,KAAK,EAAE,KAAK,SAAO,GAAG;AAChD,QAAM,MAAM,OAAO,OAAO,KAAK,EAAE,MAAM,SAAO,GAAG;AACjD,SAAO;AACT;AAGA,MAAM,kBAAkB;AAGxB,MAAM,YAAY,IAAI;AAAA,EACpB;AAMF;AAGA,MAAM,YAAY,IAAI;AAAA,EACpB;AAEF;AAGA,MAAM,oBAAoB,IAAI;AAAA,EAC5B,QACA;AAAA,IACE;AAAA,MACE,gBAAgB;AAAA,MAChB,UAAU;AAAA,IAChB,EAAM,KAAK,GAAG;AAAA,IACV,UAAU;AAAA,EACd,EAAI,KAAK,GAAG,IACV;AACF;AAGA,MAAM,eAAe;AAGrB,MAAM,0BAA0B;AAIhC,MAAM,0BAA0B,IAAI;AAAA,EAClC,QACA;AAAA,IACE,kBAAkB;AAAA,IAClB,aAAa;AAAA,IACb,wBAAwB;AAAA,IACxB;AAAA,EACJ,EAAI,KAAK,GAAG;AACZ;AAIA,MAAM,uBAAuB;AAI7B,MAAM,oBAAoB,IAAI;AAAA,EAC5B,kFAEA;AAAA,IACE,kBAAkB;AAAA,IAClB,wBAAwB;AAAA,EAC5B,EAAI,KAAK,GAAG,IACV;AACF;AAQO,SAAS,oBAAqB,YAAY,GAAG,YAAY,IAAI;AAIlE,MAAI;AACF,WAAO,IAAI;AAAA,MACT,mDAEI,SAAS,IAAI,SAAS;AAAA,IAEhC;AAAA,EACG,SAAQ,GAAG;AAEV,YAAQ,KAAK,yDAA0D;AAAA,EACxE;AAED,SAAO,IAAI;AAAA,IACT,qCACM,SAAS,IAAI,SAAS;AAAA,EAEhC;AACA;AAEA,MAAM,mBAAmB,oBAAmB;AAGhC,MAAC,YAAY,IAAI;AAAA,EAC3B;AAAA,IACE,wBAAwB;AAAA,IACxB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,EACrB,EAAI,KAAK,GAAG;AAAA,EACV;AACF;AAOO,SAAS,cAAe,OAAO;;AACpC,MAAI,CAAC,SAAU,CAAC,CAAC,UAAU,QAAQ,EAAE,SAAS,OAAO,KAAK,EAAI,QAAO;AACrE,UAAQ,MAAM;AACd,WAAO,sBAAiB,KAAK,KAAK,MAA3B,mBAA+B,QAAO;AAC/C;AAOO,SAAS,MAAO,OAAO;;AAC5B,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,WAAO,6BAAwB,KAAK,KAAK,MAAlC,mBAAsC,QAAO,WAClD,0BAAqB,KAAK,KAAK,MAA/B,mBAAmC,QAAO;AAC9C;AAOO,SAAS,eAAgB,OAAO;;AACrC,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,WAAO,uBAAkB,KAAK,KAAK,MAA5B,mBAAgC,QAAO;AAChD;AAQO,SAAS,kBAAmB,UAAU;AAC3C,SAAO,SAAS,OAAO,SAAO,CAAC,CAAC,GAAG,EAAE,KAAK,GAAG;AAC/C;AAQO,SAAS,sBAAuB,KAAK,SAAS,SAAS;AAC5D,SAAO,IAAI,QAAQ,2BAAW,GAAE,UAAQ,KAAK,kBAAkB,MAAM,CAAC;AACxE;AAQO,SAAS,gBAAiB,cAAc,eAAe;AAC5D,MAAI,OAAO,YAAY,YAAa;AACpC,MAAI,QAAQ,IAAI,aAAa,OAAQ;AACrC,MAAI,CAAC,gBAAgB,EAAE,wBAAwB,gBAAgB,EAAC,qCAAU,MAAM;AAChF,MAAI,CAAC,SAAS,KAAK,SAAS,YAAY,GAAG;AACzC,YAAQ,KAAK,OAAO,aAAa,yEAAyE;AAAA,EAC3G;AACH;AAOA,SAAS,mBAAoB,cAAc,SAAS,iBAAiB;AACnE,MAAI,YAAY,aAAa,wBAAwB,GAAG;AACtD,WAAO;AAAA,EACR;AACD,SAAO;AACT;AAMO,SAAS,qBAAsB,cAAc,SAAS,iBAAiB;AAC5E,MAAI,mBAAmB,WAAW,GAAG;AACnC,gBAAY,UAAU,IAAI,sBAAsB;AAAA,EACpD,OAAS;AACL,gBAAY,UAAU,IAAI,aAAa;AAAA,EACxC;AACH;AAMO,SAAS,oBAAqB,cAAc,SAAS,iBAAiB;AAC3E,MAAI,mBAAmB,WAAW,GAAG;AACnC,gBAAY,UAAU,OAAO,sBAAsB;AAAA,EACvD,OAAS;AACL,gBAAY,UAAU,OAAO,aAAa;AAAA,EAC3C;AACH;AAEA,MAAe,QAAA;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;"}