{"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/schema.ts","../src/tools.ts"],"sourcesContent":["export * from './mongoose.types';\nexport * from './plugin';\n","import { Schema, type SchemaDefinition } from 'mongoose';\n\nimport type {\n  TranslatableDocument,\n  TranslatedDocumentMeta,\n  TranslatedPlainObject,\n  TranslationDocument,\n  TranslationDocumentMeta,\n  TranslationOptions\n} from './mongoose.types';\nimport { buildTranslationSchema, getTranslatablePaths } from './schema';\nimport { applyTranslation, generateAutoTranslation, generateObjectFromPathMap, hashMapStringValues, mapTranslationSource } from './tools';\n\nexport function translationPlugin<T>(schema: Schema, opts: TranslationOptions): void {\n  // check if provider is a Translation instance\n  if (opts.provider && typeof opts.provider.getTranslations !== 'function') throw new Error('[Options]: provider must implement getTranslations method');\n  // check if provided translator option is a function\n  if (opts.translator && typeof opts.translator !== 'function') throw new Error('[Options]: translator must be a function: ({ text, from, to }) => [String]');\n  // check if provided sanitizer option is a function\n  if (opts.sanitizer && typeof opts.sanitizer !== 'function') throw new Error('[Options]: sanitizer must be a function: (String) => String');\n  // check if provided defaultLanguage option is a string\n  if (opts.defaultLanguage && typeof opts.defaultLanguage !== 'string') throw new Error('[Options]: defaultLanguage must be a string');\n  // check if provided languageField option is a string\n  if (opts.languageField && typeof opts.languageField !== 'string') throw new Error('[Options]: languageField must be a string');\n  // check if provided hashField option is a string\n  if (opts.hashField && typeof opts.hashField !== 'string') throw new Error('[Options]: hashField must be a string');\n\n  // deprecate translator option\n  if (opts.translator) console.warn('[Options]: translator option is deprecated, use provider instead');\n\n  if (opts.provider && opts.translator) {\n    console.warn('[Options]: both provider and translator options are provided, translator option will be ignored');\n  }\n\n  const translator = opts.provider?.getTranslations || opts.translator;\n  if (!translator) throw new Error('[Options]: a translation option is required (provider or translator)');\n\n  const options: Required<Omit<TranslationOptions, 'provider'>> = {\n    translator,\n    sanitizer: opts.sanitizer || ((value: string): string => value),\n    defaultLanguage: opts.defaultLanguage || 'en',\n    languageField: opts.languageField || 'language',\n    hashField: opts.hashField || 'sourceHash'\n  };\n\n  const pathsToTranslate = getTranslatablePaths(schema);\n  // add translation array to schema, and the additional fields\n  // related to translation to be stored (hash, language, autoTranslated)\n\n  const schemaFields: SchemaDefinition = {\n    [options.hashField]: { type: String },\n    [options.languageField]: { type: String, default: options.defaultLanguage }\n  };\n\n  // add native entity translation related properties\n  schema.add(schemaFields);\n\n  // add translation schema to native entity based on translatable paths\n  const translationSchemaDefinition = buildTranslationSchema(schema, schemaFields, pathsToTranslate);\n  const translationSchema = new Schema(translationSchemaDefinition, { _id: false });\n  schema.add({ translation: [translationSchema] });\n\n  schema.pre<TranslatableDocument<T>>('save', function generateNativeHash() {\n    this.set(options.hashField, this.generateSourceHash());\n  });\n\n  schema.methods.getSupportedLanguages = function getSupportedLanguages(): string[] {\n    const supportedLanguages = [this.get(options.languageField)];\n    const translation = this.get('translation');\n    if (translation && Array.isArray(translation)) {\n      for (const tr of translation) {\n        supportedLanguages.push(tr[options.languageField]);\n      }\n    } else throw new Error('Incorrect translation field');\n    return supportedLanguages;\n  };\n\n  schema.methods.getExistingTranslationForLocale = function getExistingTranslationForLocale(locale: string): TranslationDocument<T> | undefined {\n    const translation = this.get('translation').find((trad: TranslationDocument<T>) => trad[options.languageField] === locale);\n    return translation?.toObject();\n  };\n\n  schema.methods.updateOrReplaceTranslation = async function updateOrReplaceTranslation(translation: TranslationDocument<T>): Promise<void> {\n    const translations = this.get('translation').filter((t: TranslationDocument<T>) => t[options.languageField] !== translation[options.languageField]);\n    translations.push(translation);\n    this.set('translation', translations);\n    await this.save();\n  };\n\n  schema.methods.translationSourceMap = function translationSourceMap(): Map<string, string> {\n    return mapTranslationSource(this.toObject(), pathsToTranslate, options.sanitizer);\n  };\n\n  schema.methods.generateSourceHash = function generateSourceHash(): string {\n    const translationSource = (this as TranslatableDocument<T>).translationSourceMap();\n    return hashMapStringValues(translationSource);\n  };\n\n  schema.methods.getTranslation = async function getTranslation(locale: string): Promise<TranslationDocument<T>> {\n    // flatten object\n    const _this = this as TranslatableDocument<T>;\n    const translationSource = _this.translationSourceMap();\n    const translationSourceHash = _this.generateSourceHash();\n    let translation = _this.getExistingTranslationForLocale(locale);\n    if (!translation || (translation.autoTranslated && translation[options.hashField] !== translationSourceHash))\n      try {\n        // retrieve a translation by provider\n        const nativeLanguage = this.get(options.languageField);\n        const translationsMap = await generateAutoTranslation(nativeLanguage, locale, translationSource, options.translator);\n        const translationOverrides = generateObjectFromPathMap<Partial<T>>(translationsMap);\n        const translationMeta = {\n          [options.hashField]: _this.generateSourceHash(),\n          [options.languageField]: locale\n        };\n        translation = { ...translationMeta, ...translationOverrides, autoTranslated: true };\n        await _this.updateOrReplaceTranslation(translation);\n      } catch (err) {\n        console.error(`An error occured while auto-translating an entity: ${err instanceof Error ? err.message : err}`);\n      }\n    return translation;\n  };\n\n  /**\n   * returns a plain object of the entity with translatable fields overriden\n   * @param locale\n   * @returns {Promise<Object>}\n   */\n  schema.methods.translate = async function translate(locale: string): Promise<TranslatedPlainObject<T>> {\n    const _this = this as TranslatableDocument<T>;\n    const nativeLanguage = this.get([options.languageField]);\n\n    let entityTranslation: TranslationDocument<T> | undefined;\n\n    if (nativeLanguage !== locale) {\n      entityTranslation = await _this.getTranslation(locale);\n    }\n\n    const translationMeta: TranslationDocumentMeta = {\n      [options.hashField]: entityTranslation?.[options.hashField] || _this.get(options.hashField),\n      [options.languageField]: entityTranslation?.[options.languageField] || nativeLanguage,\n      autoTranslated: entityTranslation?.autoTranslated || false\n    };\n\n    const { translation, _id, __v, ...entityToTranslate } = _this.toObject();\n\n    // in case no translation is returned, the native entity is returned as failsafe\n    const appliedTranslation = applyTranslation(entityToTranslate, entityTranslation);\n\n    // add supported languages at root level for translation actions\n    const translatedMeta: TranslatedDocumentMeta = {\n      supportedLanguages: _this.getSupportedLanguages(),\n      nativeLanguage\n    };\n\n    return Object.assign(appliedTranslation, translatedMeta, translationMeta) as TranslatedPlainObject<T>;\n  };\n}\n","import type { Schema, SchemaDefinition, SchemaDefinitionProperty, SchemaType } from 'mongoose';\n\nimport type { Tree } from './tools';\n\ndeclare module 'mongoose' {\n  interface Schema {\n    tree?: unknown; //nested object that can be an array or a property\n  }\n}\n\nfunction eachPathRecursive(schema: Schema, handler: (s: string, t: SchemaType) => void, path: string[] = []): void {\n  schema.eachPath((pathname, schemaType) => {\n    path.push(pathname);\n    if (schemaType.schema) eachPathRecursive(schemaType.schema, handler, path);\n    else handler(path.join('.'), schemaType);\n    path.pop();\n  });\n}\n\n/**\n * This function returns the list of entity's translatable paths as Strings.\n * If a property has option 'translatable' set to 'true' in the Schema, it will be\n * searched recursively in the object tree. Refer to mongoose implementation for\n * Schema instance scanning.\n * ex:\n * {\n *   aProp: {\n *     anArray: [\n *       {\n *         aKey: { type: String, translatable: true }\n *       }\n *     ]\n *   },\n *   aTranslatableProp: { type: String, translatable: true },\n *   anotherProp: String\n * }\n * will return ['aTranslatableProp', 'aProp.anArray.aKey']\n * @param schema\n * @returns {[String]}\n */\nexport function getTranslatablePaths(schema: Schema): string[] {\n  const pathsToTranslate: string[] = [];\n  eachPathRecursive(schema, (pathname: string, schemaType: SchemaType) => {\n    if (schemaType.options?.translatable || schemaType.options?.type?.[0]?.translatable) pathsToTranslate.push(pathname);\n  });\n  return pathsToTranslate;\n}\n\nfunction generateSchemaRecursive(pathnames: string[], tree: Tree, translationSchema: SchemaDefinition): SchemaDefinition {\n  const pathName = pathnames.shift() as string;\n\n  const treePath = tree[pathName];\n  const isLeaf = !pathnames.length;\n\n  // current path is an array in the model\n  if (Array.isArray(treePath) && treePath[0]) {\n    const branch = treePath[0] as Tree;\n\n    // get existing schema or initiate it.\n    const existingSchema = (translationSchema[pathName] as SchemaDefinitionProperty[])?.[0];\n    const nestedTranslationSchema = existingSchema || { _id: false };\n    if (isLeaf) {\n      // the array encloses simple values\n      const { translatable, required, ...options } = branch;\n      Object.assign(nestedTranslationSchema, options);\n    } else {\n      // the array encloses nested elements\n      Object.assign(nestedTranslationSchema, generateSchemaRecursive(pathnames, (branch.tree as Tree) || branch, nestedTranslationSchema as SchemaDefinition));\n    }\n    if (!translationSchema[pathName]) Object.assign(translationSchema, { [pathName]: [nestedTranslationSchema] });\n  }\n  // current path is a nested object\n  else if (!isLeaf) {\n    // assign property and process deeper\n    const nestedTranslationSchema = translationSchema[pathName] || {};\n    Object.assign(nestedTranslationSchema, generateSchemaRecursive(pathnames, treePath as Tree, nestedTranslationSchema as SchemaDefinition));\n    if (!translationSchema[pathName]) Object.assign(translationSchema, { [pathName]: nestedTranslationSchema });\n  }\n  // current path is a translatable value\n  else {\n    // add all schema options to this path except required and translatable\n    const { translatable, required, ...options } = treePath as Tree;\n    Object.assign(translationSchema, { [pathName]: options });\n  }\n  return translationSchema;\n}\n\nconst addSchemaForPath =\n  (schema: Schema) =>\n  (translationSchema: SchemaDefinition, path: string): SchemaDefinition => {\n    const pathnames = path.split('.');\n    const { tree } = schema;\n    return generateSchemaRecursive(pathnames, tree as Tree, translationSchema);\n  };\n\n/**\n * This function will generate a mongoose 'translation' sub-Schema based on\n * the list of paths, going recursively in the original Schema to determine\n * whether the property is a String an Array or an Object.\n * In the end, the sub-schema created reflects the original schema, filtered\n * by properties marked 'translatable' in their options.\n * The final translation schema which will hold all translated values also has\n * the following properties:\n * 'autoTranslated', Boolean: indicates whether the actual translation is generated automatically by external provider\n * 'sourceHash', String: is the hash of the original content to compare updates in the original content and trigger\n * another automatic translation when changed.\n * 'language' (by default), holds the locale of the contents stored in the translation instance.\n * @param schema\n * @param schemaFields\n * @param pathsToTranslate\n * @returns {Schema}\n */\nexport function buildTranslationSchema(schema: Schema, schemaFields: SchemaDefinition, pathsToTranslate: string[]): SchemaDefinition {\n  const translationSchema: SchemaDefinition = {\n    autoTranslated: { type: Boolean },\n    ...schemaFields\n  };\n  try {\n    pathsToTranslate.reduce(addSchemaForPath(schema), translationSchema);\n  } catch (error) {\n    console.error('The translation schema could not be build recursively:', error);\n  }\n  return translationSchema; // recursive sub-schema definition\n}\n","import { createHash } from 'node:crypto';\nimport objectPath from 'object-path';\n\nimport type { SanitizerFunction, TranslatorFunction } from './mongoose.types';\n\nfunction prefixMapKeys(map: Map<string, string>, prefix: string): Map<string, string> {\n  const result = new Map();\n  map.forEach((value, key) => result.set(`${prefix}.${key}`, value));\n  return result;\n}\n\n/**\n * Prints a map in a human-readable format\n * This is useful for debugging purposes\n * @param {Map} aMap\n * @returns {string}\n */\nexport function printMap(aMap: Map<string, string>): string {\n  let message = '\\nMap: [\\n';\n  aMap.forEach((val, key) => {\n    message += `\\t[${key}: ${val}]\\n`;\n  });\n  message += ']\\n';\n  return message;\n}\n\nfunction notEmpty<TValue>(value: TValue | null | undefined): value is TValue {\n  return Boolean(value);\n}\n\nfunction indexedMap(array: Array<unknown>, prefix: string): Map<string, string> {\n  const mappedArray = array\n    .map((value, index) => {\n      const key = [prefix, String(index)].filter(Boolean).join('.');\n      if (typeof value !== 'string') return null; // non string objects are skipped\n      return [key, value] as [string, string];\n    })\n    .filter(notEmpty);\n\n  return new Map(mappedArray);\n}\n\n/**\n * From a plain object and a path, will return a map of key/values where the key represents the unique identifiable\n * path of the value and the actual value. If the path lead to an array, then each path will include the index in the\n * array. ex:\n * - path = ['profile', 'workingLanguage', 'name']\n * - entity = { profile: { workingLanguage: [ { name: 'french' }, { name: 'english' } ] } }\n * yields the map :\n * [\n *   ['profile.workingLanguage.1.name', 'french'],\n *   ['profile.workingLanguage.2.name', 'english']\n * ]\n *\n * @param {[String]} [path] path to the requested value in the entity\n * @param {Object} [entity] a plain object within which the value is searched\n */\nexport type Tree = {\n  [key: string]: Array<Tree | string> | string | undefined | null | Tree;\n};\n\nexport function mapEntityPathValues(path: string[], entity: Tree): Map<string, string> {\n  let resultMap = new Map();\n\n  // no-op cases\n  if (!entity) return resultMap; //entity to parse cannot be null or undefined\n  if (!path?.length) return resultMap; //path cannot be empty array or null\n\n  const [root, ...subPath] = path;\n\n  const translatableValue = entity[root as string];\n\n  // leaf process, the element to translate is directly accessible onto the entity\n  if (!subPath.length) {\n    if (typeof translatableValue === 'string') {\n      resultMap.set(root, translatableValue);\n    } else if (Array.isArray(translatableValue)) {\n      resultMap = indexedMap(translatableValue, root as string);\n    } else {\n      // no-op\n      //return empty map if value is something else\n    }\n  } else {\n    // recursive process, step into the subpath\n    let subMap = new Map<string, string>();\n    if (Array.isArray(translatableValue)) {\n      translatableValue.forEach((subEntity, index) => {\n        const mappedSubEntity = prefixMapKeys(mapEntityPathValues(subPath, <Tree>subEntity), index.toString());\n        // copy values in the resulting supMap (flatten)\n        mappedSubEntity.forEach((value, key) => subMap.set(key, value));\n      });\n    } else {\n      subMap = mapEntityPathValues(subPath, <Tree>translatableValue);\n    }\n    resultMap = prefixMapKeys(subMap, root as string);\n  }\n  return resultMap;\n}\n\nexport function generateObjectFromPathMap<T>(objectMap: Map<string, string>): T {\n  const resultObject = {};\n  objectMap.forEach((value, path) => {\n    objectPath.set(resultObject, path, value);\n  });\n  return resultObject as T;\n}\n\n/**\n * Recursively overrides an object's properties with its translations.\n * @param document a plain object\n * @param translation a plain object containing overrides\n * @returns the translated object\n */\nexport function applyTranslation<D extends Tree>(document: D, translation?: Partial<D>): D {\n  if (!translation) return document;\n\n  const localized: D = Object.assign({}, document);\n\n  // biome-ignore lint/complexity/noForEach: <explanation>\n  Object.keys(translation).forEach((key) => {\n    const override = translation[key];\n    if (override && typeof override === 'string') {\n      // if simple string, just replace with translation.\n      // empty values are skipped\n      Object.assign(localized, { [key]: override });\n    } else if (Array.isArray(override)) {\n      // for arrays, each translation shall be mapped to the original item by its index\n      // resulting array\n      type ArrayItem = string | Tree;\n      const translatedArray: ArrayItem[] = [];\n      // go through all items of the array\n\n      (localized[key] as ArrayItem[]).forEach((arrayItem: ArrayItem, index: number) => {\n        const itemTranslation = override[index];\n        // skip empty values\n        if (itemTranslation) {\n          if (typeof arrayItem === 'string') {\n            // place translation value, respecting index\n            translatedArray[index] = itemTranslation;\n          } else if (Array.isArray(arrayItem)) {\n            throw new Error('Nested arrays are not managed for applyTranslation, please consider nesting objects instead');\n          } else if (typeof arrayItem === 'object') {\n            // retrieve the translation of the nested object\n            translatedArray[index] = applyTranslation(arrayItem, itemTranslation as Tree);\n          }\n          // put any non-translated element in the array\n          else translatedArray[index] = arrayItem;\n        }\n      });\n      Object.assign(localized, { [key]: translatedArray });\n    } else if (typeof override === 'object') {\n      // for nested objects, step in\n      const nestedTranslation = applyTranslation(localized[key] as Tree, override as Tree);\n      Object.assign(localized, { [key]: nestedTranslation });\n    }\n  });\n\n  return localized;\n}\n\n/**\n * Takes all String values of a map<String, String>, concatenates them and generate a checksum.\n * @param {Map} aMap\n * @returns {string}\n */\nexport function hashMapStringValues(aMap: Map<string, string>): string {\n  return createHash('md5').update(Array.from(aMap.values()).join('')).digest('base64');\n}\n\n/**\n * Generates an object which given a source map, key being an object path, and value being the text to translate\n * sends\n * @param {String} from\n * @param {String} to\n * @param {String} source\n * @param {Function} translator\n * @returns {Promise<Map>}\n */\nexport async function generateAutoTranslation(\n  from: string,\n  to: string,\n  source: Map<string, string>,\n  translatorFunction: TranslatorFunction\n): Promise<Map<string, string>> {\n  const translationsResult = new Map();\n  try {\n    // Get translations from provider\n    const autoTranslations = await translatorFunction({\n      from,\n      to,\n      text: Array.from(source.values())\n    });\n    if (Array.isArray(autoTranslations)) {\n      // If the translation provider returns an array, we map the translations to the source keys\n      Array.from(source.keys()).forEach((key, index) => translationsResult.set(key, autoTranslations[index]));\n    } else {\n      // If the translation provider returns a single string, we map the translation to the source keys\n      throw new Error('Invalid response from translator');\n    }\n  } catch (error) {\n    throw new Error(`Translation failed form ${from} to ${to}: ${(error as Error).message}`);\n  }\n  return translationsResult;\n}\n\n/**\n * Generates a mapped list of values to send to the translation service\n * @returns {Map}\n */\nexport function mapTranslationSource(entity: Tree, paths: string[], sanitizer: SanitizerFunction): Map<string, string> {\n  const translationSourceMap = new Map();\n  for (const path of paths) {\n    const pathSegments = path.split('.');\n    const pathValuesMap = mapEntityPathValues(pathSegments, entity);\n    pathValuesMap.forEach((value, key) => translationSourceMap.set(key, sanitizer(value)));\n  }\n  return translationSourceMap;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,sBAA8C;;;ACU9C,SAAS,kBAAkB,QAAgB,SAA6C,OAAiB,CAAC,GAAS;AACjH,SAAO,SAAS,CAAC,UAAU,eAAe;AACxC,SAAK,KAAK,QAAQ;AAClB,QAAI,WAAW,OAAQ,mBAAkB,WAAW,QAAQ,SAAS,IAAI;AAAA,QACpE,SAAQ,KAAK,KAAK,GAAG,GAAG,UAAU;AACvC,SAAK,IAAI;AAAA,EACX,CAAC;AACH;AAuBO,SAAS,qBAAqB,QAA0B;AAC7D,QAAM,mBAA6B,CAAC;AACpC,oBAAkB,QAAQ,CAAC,UAAkB,eAA2B;AACtE,QAAI,WAAW,SAAS,gBAAgB,WAAW,SAAS,OAAO,CAAC,GAAG,aAAc,kBAAiB,KAAK,QAAQ;AAAA,EACrH,CAAC;AACD,SAAO;AACT;AAEA,SAAS,wBAAwB,WAAqB,MAAY,mBAAuD;AACvH,QAAM,WAAW,UAAU,MAAM;AAEjC,QAAM,WAAW,KAAK,QAAQ;AAC9B,QAAM,SAAS,CAAC,UAAU;AAG1B,MAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,CAAC,GAAG;AAC1C,UAAM,SAAS,SAAS,CAAC;AAGzB,UAAM,iBAAkB,kBAAkB,QAAQ,IAAmC,CAAC;AACtF,UAAM,0BAA0B,kBAAkB,EAAE,KAAK,MAAM;AAC/D,QAAI,QAAQ;AAEV,YAAM,EAAE,cAAc,UAAU,GAAG,QAAQ,IAAI;AAC/C,aAAO,OAAO,yBAAyB,OAAO;AAAA,IAChD,OAAO;AAEL,aAAO,OAAO,yBAAyB,wBAAwB,WAAY,OAAO,QAAiB,QAAQ,uBAA2C,CAAC;AAAA,IACzJ;AACA,QAAI,CAAC,kBAAkB,QAAQ,EAAG,QAAO,OAAO,mBAAmB,EAAE,CAAC,QAAQ,GAAG,CAAC,uBAAuB,EAAE,CAAC;AAAA,EAC9G,WAES,CAAC,QAAQ;AAEhB,UAAM,0BAA0B,kBAAkB,QAAQ,KAAK,CAAC;AAChE,WAAO,OAAO,yBAAyB,wBAAwB,WAAW,UAAkB,uBAA2C,CAAC;AACxI,QAAI,CAAC,kBAAkB,QAAQ,EAAG,QAAO,OAAO,mBAAmB,EAAE,CAAC,QAAQ,GAAG,wBAAwB,CAAC;AAAA,EAC5G,OAEK;AAEH,UAAM,EAAE,cAAc,UAAU,GAAG,QAAQ,IAAI;AAC/C,WAAO,OAAO,mBAAmB,EAAE,CAAC,QAAQ,GAAG,QAAQ,CAAC;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,IAAM,mBACJ,CAAC,WACD,CAAC,mBAAqC,SAAmC;AACvE,QAAM,YAAY,KAAK,MAAM,GAAG;AAChC,QAAM,EAAE,KAAK,IAAI;AACjB,SAAO,wBAAwB,WAAW,MAAc,iBAAiB;AAC3E;AAmBK,SAAS,uBAAuB,QAAgB,cAAgC,kBAA8C;AACnI,QAAM,oBAAsC;AAAA,IAC1C,gBAAgB,EAAE,MAAM,QAAQ;AAAA,IAChC,GAAG;AAAA,EACL;AACA,MAAI;AACF,qBAAiB,OAAO,iBAAiB,MAAM,GAAG,iBAAiB;AAAA,EACrE,SAAS,OAAO;AACd,YAAQ,MAAM,0DAA0D,KAAK;AAAA,EAC/E;AACA,SAAO;AACT;;;AC3HA,yBAA2B;AAC3B,yBAAuB;AAIvB,SAAS,cAAc,KAA0B,QAAqC;AACpF,QAAM,SAAS,oBAAI,IAAI;AACvB,MAAI,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,GAAG,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC;AACjE,SAAO;AACT;AAiBA,SAAS,SAAiB,OAAmD;AAC3E,SAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,WAAW,OAAuB,QAAqC;AAC9E,QAAM,cAAc,MACjB,IAAI,CAAC,OAAO,UAAU;AACrB,UAAM,MAAM,CAAC,QAAQ,OAAO,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC5D,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,WAAO,CAAC,KAAK,KAAK;AAAA,EACpB,CAAC,EACA,OAAO,QAAQ;AAElB,SAAO,IAAI,IAAI,WAAW;AAC5B;AAqBO,SAAS,oBAAoB,MAAgB,QAAmC;AACrF,MAAI,YAAY,oBAAI,IAAI;AAGxB,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,CAAC,MAAM,OAAQ,QAAO;AAE1B,QAAM,CAAC,MAAM,GAAG,OAAO,IAAI;AAE3B,QAAM,oBAAoB,OAAO,IAAc;AAG/C,MAAI,CAAC,QAAQ,QAAQ;AACnB,QAAI,OAAO,sBAAsB,UAAU;AACzC,gBAAU,IAAI,MAAM,iBAAiB;AAAA,IACvC,WAAW,MAAM,QAAQ,iBAAiB,GAAG;AAC3C,kBAAY,WAAW,mBAAmB,IAAc;AAAA,IAC1D,OAAO;AAAA,IAGP;AAAA,EACF,OAAO;AAEL,QAAI,SAAS,oBAAI,IAAoB;AACrC,QAAI,MAAM,QAAQ,iBAAiB,GAAG;AACpC,wBAAkB,QAAQ,CAAC,WAAW,UAAU;AAC9C,cAAM,kBAAkB,cAAc,oBAAoB,SAAe,SAAS,GAAG,MAAM,SAAS,CAAC;AAErG,wBAAgB,QAAQ,CAAC,OAAO,QAAQ,OAAO,IAAI,KAAK,KAAK,CAAC;AAAA,MAChE,CAAC;AAAA,IACH,OAAO;AACL,eAAS,oBAAoB,SAAe,iBAAiB;AAAA,IAC/D;AACA,gBAAY,cAAc,QAAQ,IAAc;AAAA,EAClD;AACA,SAAO;AACT;AAEO,SAAS,0BAA6B,WAAmC;AAC9E,QAAM,eAAe,CAAC;AACtB,YAAU,QAAQ,CAAC,OAAO,SAAS;AACjC,uBAAAA,QAAW,IAAI,cAAc,MAAM,KAAK;AAAA,EAC1C,CAAC;AACD,SAAO;AACT;AAQO,SAAS,iBAAiC,UAAa,aAA6B;AACzF,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,YAAe,OAAO,OAAO,CAAC,GAAG,QAAQ;AAG/C,SAAO,KAAK,WAAW,EAAE,QAAQ,CAAC,QAAQ;AACxC,UAAM,WAAW,YAAY,GAAG;AAChC,QAAI,YAAY,OAAO,aAAa,UAAU;AAG5C,aAAO,OAAO,WAAW,EAAE,CAAC,GAAG,GAAG,SAAS,CAAC;AAAA,IAC9C,WAAW,MAAM,QAAQ,QAAQ,GAAG;AAIlC,YAAM,kBAA+B,CAAC;AAGtC,MAAC,UAAU,GAAG,EAAkB,QAAQ,CAAC,WAAsB,UAAkB;AAC/E,cAAM,kBAAkB,SAAS,KAAK;AAEtC,YAAI,iBAAiB;AACnB,cAAI,OAAO,cAAc,UAAU;AAEjC,4BAAgB,KAAK,IAAI;AAAA,UAC3B,WAAW,MAAM,QAAQ,SAAS,GAAG;AACnC,kBAAM,IAAI,MAAM,6FAA6F;AAAA,UAC/G,WAAW,OAAO,cAAc,UAAU;AAExC,4BAAgB,KAAK,IAAI,iBAAiB,WAAW,eAAuB;AAAA,UAC9E,MAEK,iBAAgB,KAAK,IAAI;AAAA,QAChC;AAAA,MACF,CAAC;AACD,aAAO,OAAO,WAAW,EAAE,CAAC,GAAG,GAAG,gBAAgB,CAAC;AAAA,IACrD,WAAW,OAAO,aAAa,UAAU;AAEvC,YAAM,oBAAoB,iBAAiB,UAAU,GAAG,GAAW,QAAgB;AACnF,aAAO,OAAO,WAAW,EAAE,CAAC,GAAG,GAAG,kBAAkB,CAAC;AAAA,IACvD;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAOO,SAAS,oBAAoB,MAAmC;AACrE,aAAO,+BAAW,KAAK,EAAE,OAAO,MAAM,KAAK,KAAK,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,QAAQ;AACrF;AAWA,eAAsB,wBACpB,MACA,IACA,QACA,oBAC8B;AAC9B,QAAM,qBAAqB,oBAAI,IAAI;AACnC,MAAI;AAEF,UAAM,mBAAmB,MAAM,mBAAmB;AAAA,MAChD;AAAA,MACA;AAAA,MACA,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC;AAAA,IAClC,CAAC;AACD,QAAI,MAAM,QAAQ,gBAAgB,GAAG;AAEnC,YAAM,KAAK,OAAO,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,UAAU,mBAAmB,IAAI,KAAK,iBAAiB,KAAK,CAAC,CAAC;AAAA,IACxG,OAAO;AAEL,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAAA,EACF,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,2BAA2B,IAAI,OAAO,EAAE,KAAM,MAAgB,OAAO,EAAE;AAAA,EACzF;AACA,SAAO;AACT;AAMO,SAAS,qBAAqB,QAAc,OAAiB,WAAmD;AACrH,QAAM,uBAAuB,oBAAI,IAAI;AACrC,aAAW,QAAQ,OAAO;AACxB,UAAM,eAAe,KAAK,MAAM,GAAG;AACnC,UAAM,gBAAgB,oBAAoB,cAAc,MAAM;AAC9D,kBAAc,QAAQ,CAAC,OAAO,QAAQ,qBAAqB,IAAI,KAAK,UAAU,KAAK,CAAC,CAAC;AAAA,EACvF;AACA,SAAO;AACT;;;AF5MO,SAAS,kBAAqB,QAAgB,MAAgC;AAEnF,MAAI,KAAK,YAAY,OAAO,KAAK,SAAS,oBAAoB,WAAY,OAAM,IAAI,MAAM,2DAA2D;AAErJ,MAAI,KAAK,cAAc,OAAO,KAAK,eAAe,WAAY,OAAM,IAAI,MAAM,4EAA4E;AAE1J,MAAI,KAAK,aAAa,OAAO,KAAK,cAAc,WAAY,OAAM,IAAI,MAAM,6DAA6D;AAEzI,MAAI,KAAK,mBAAmB,OAAO,KAAK,oBAAoB,SAAU,OAAM,IAAI,MAAM,6CAA6C;AAEnI,MAAI,KAAK,iBAAiB,OAAO,KAAK,kBAAkB,SAAU,OAAM,IAAI,MAAM,2CAA2C;AAE7H,MAAI,KAAK,aAAa,OAAO,KAAK,cAAc,SAAU,OAAM,IAAI,MAAM,uCAAuC;AAGjH,MAAI,KAAK,WAAY,SAAQ,KAAK,kEAAkE;AAEpG,MAAI,KAAK,YAAY,KAAK,YAAY;AACpC,YAAQ,KAAK,iGAAiG;AAAA,EAChH;AAEA,QAAM,aAAa,KAAK,UAAU,mBAAmB,KAAK;AAC1D,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,sEAAsE;AAEvG,QAAM,UAA0D;AAAA,IAC9D;AAAA,IACA,WAAW,KAAK,cAAc,CAAC,UAA0B;AAAA,IACzD,iBAAiB,KAAK,mBAAmB;AAAA,IACzC,eAAe,KAAK,iBAAiB;AAAA,IACrC,WAAW,KAAK,aAAa;AAAA,EAC/B;AAEA,QAAM,mBAAmB,qBAAqB,MAAM;AAIpD,QAAM,eAAiC;AAAA,IACrC,CAAC,QAAQ,SAAS,GAAG,EAAE,MAAM,OAAO;AAAA,IACpC,CAAC,QAAQ,aAAa,GAAG,EAAE,MAAM,QAAQ,SAAS,QAAQ,gBAAgB;AAAA,EAC5E;AAGA,SAAO,IAAI,YAAY;AAGvB,QAAM,8BAA8B,uBAAuB,QAAQ,cAAc,gBAAgB;AACjG,QAAM,oBAAoB,IAAI,uBAAO,6BAA6B,EAAE,KAAK,MAAM,CAAC;AAChF,SAAO,IAAI,EAAE,aAAa,CAAC,iBAAiB,EAAE,CAAC;AAE/C,SAAO,IAA6B,QAAQ,SAAS,qBAAqB;AACxE,SAAK,IAAI,QAAQ,WAAW,KAAK,mBAAmB,CAAC;AAAA,EACvD,CAAC;AAED,SAAO,QAAQ,wBAAwB,SAAS,wBAAkC;AAChF,UAAM,qBAAqB,CAAC,KAAK,IAAI,QAAQ,aAAa,CAAC;AAC3D,UAAM,cAAc,KAAK,IAAI,aAAa;AAC1C,QAAI,eAAe,MAAM,QAAQ,WAAW,GAAG;AAC7C,iBAAW,MAAM,aAAa;AAC5B,2BAAmB,KAAK,GAAG,QAAQ,aAAa,CAAC;AAAA,MACnD;AAAA,IACF,MAAO,OAAM,IAAI,MAAM,6BAA6B;AACpD,WAAO;AAAA,EACT;AAEA,SAAO,QAAQ,kCAAkC,SAAS,gCAAgC,QAAoD;AAC5I,UAAM,cAAc,KAAK,IAAI,aAAa,EAAE,KAAK,CAAC,SAAiC,KAAK,QAAQ,aAAa,MAAM,MAAM;AACzH,WAAO,aAAa,SAAS;AAAA,EAC/B;AAEA,SAAO,QAAQ,6BAA6B,eAAe,2BAA2B,aAAoD;AACxI,UAAM,eAAe,KAAK,IAAI,aAAa,EAAE,OAAO,CAAC,MAA8B,EAAE,QAAQ,aAAa,MAAM,YAAY,QAAQ,aAAa,CAAC;AAClJ,iBAAa,KAAK,WAAW;AAC7B,SAAK,IAAI,eAAe,YAAY;AACpC,UAAM,KAAK,KAAK;AAAA,EAClB;AAEA,SAAO,QAAQ,uBAAuB,SAAS,uBAA4C;AACzF,WAAO,qBAAqB,KAAK,SAAS,GAAG,kBAAkB,QAAQ,SAAS;AAAA,EAClF;AAEA,SAAO,QAAQ,qBAAqB,SAAS,qBAA6B;AACxE,UAAM,oBAAqB,KAAiC,qBAAqB;AACjF,WAAO,oBAAoB,iBAAiB;AAAA,EAC9C;AAEA,SAAO,QAAQ,iBAAiB,eAAe,eAAe,QAAiD;AAE7G,UAAM,QAAQ;AACd,UAAM,oBAAoB,MAAM,qBAAqB;AACrD,UAAM,wBAAwB,MAAM,mBAAmB;AACvD,QAAI,cAAc,MAAM,gCAAgC,MAAM;AAC9D,QAAI,CAAC,eAAgB,YAAY,kBAAkB,YAAY,QAAQ,SAAS,MAAM;AACpF,UAAI;AAEF,cAAM,iBAAiB,KAAK,IAAI,QAAQ,aAAa;AACrD,cAAM,kBAAkB,MAAM,wBAAwB,gBAAgB,QAAQ,mBAAmB,QAAQ,UAAU;AACnH,cAAM,uBAAuB,0BAAsC,eAAe;AAClF,cAAM,kBAAkB;AAAA,UACtB,CAAC,QAAQ,SAAS,GAAG,MAAM,mBAAmB;AAAA,UAC9C,CAAC,QAAQ,aAAa,GAAG;AAAA,QAC3B;AACA,sBAAc,EAAE,GAAG,iBAAiB,GAAG,sBAAsB,gBAAgB,KAAK;AAClF,cAAM,MAAM,2BAA2B,WAAW;AAAA,MACpD,SAAS,KAAK;AACZ,gBAAQ,MAAM,sDAAsD,eAAe,QAAQ,IAAI,UAAU,GAAG,EAAE;AAAA,MAChH;AACF,WAAO;AAAA,EACT;AAOA,SAAO,QAAQ,YAAY,eAAe,UAAU,QAAmD;AACrG,UAAM,QAAQ;AACd,UAAM,iBAAiB,KAAK,IAAI,CAAC,QAAQ,aAAa,CAAC;AAEvD,QAAI;AAEJ,QAAI,mBAAmB,QAAQ;AAC7B,0BAAoB,MAAM,MAAM,eAAe,MAAM;AAAA,IACvD;AAEA,UAAM,kBAA2C;AAAA,MAC/C,CAAC,QAAQ,SAAS,GAAG,oBAAoB,QAAQ,SAAS,KAAK,MAAM,IAAI,QAAQ,SAAS;AAAA,MAC1F,CAAC,QAAQ,aAAa,GAAG,oBAAoB,QAAQ,aAAa,KAAK;AAAA,MACvE,gBAAgB,mBAAmB,kBAAkB;AAAA,IACvD;AAEA,UAAM,EAAE,aAAa,KAAK,KAAK,GAAG,kBAAkB,IAAI,MAAM,SAAS;AAGvE,UAAM,qBAAqB,iBAAiB,mBAAmB,iBAAiB;AAGhF,UAAM,iBAAyC;AAAA,MAC7C,oBAAoB,MAAM,sBAAsB;AAAA,MAChD;AAAA,IACF;AAEA,WAAO,OAAO,OAAO,oBAAoB,gBAAgB,eAAe;AAAA,EAC1E;AACF;","names":["objectPath"]}