Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,56 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, not, Name} from "../../compile/codegen"
+import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
+
+export type AdditionalItemsError = ErrorObject<"additionalItems", {limit: number}, AnySchema>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {len}}) => str`must NOT have more than ${len} items`,
+  params: ({params: {len}}) => _`{limit: ${len}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "additionalItems" as const,
+  type: "array",
+  schemaType: ["boolean", "object"],
+  before: "uniqueItems",
+  error,
+  code(cxt: KeywordCxt) {
+    const {parentSchema, it} = cxt
+    const {items} = parentSchema
+    if (!Array.isArray(items)) {
+      checkStrictMode(it, '"additionalItems" is ignored when "items" is not an array of schemas')
+      return
+    }
+    validateAdditionalItems(cxt, items)
+  },
+}
+
+export function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): void {
+  const {gen, schema, data, keyword, it} = cxt
+  it.items = true
+  const len = gen.const("len", _`${data}.length`)
+  if (schema === false) {
+    cxt.setParams({len: items.length})
+    cxt.pass(_`${len} <= ${items.length}`)
+  } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
+    const valid = gen.var("valid", _`${len} <= ${items.length}`) // TODO var
+    gen.if(not(valid), () => validateItems(valid))
+    cxt.ok(valid)
+  }
+
+  function validateItems(valid: Name): void {
+    gen.forRange("i", items.length, len, (i) => {
+      cxt.subschema({keyword, dataProp: i, dataPropType: Type.Num}, valid)
+      if (!it.allErrors) gen.if(not(valid), () => gen.break())
+    })
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,118 @@
+import type {
+  CodeKeywordDefinition,
+  AddedKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import {allSchemaProperties, usePattern, isOwnProperty} from "../code"
+import {_, nil, or, not, Code, Name} from "../../compile/codegen"
+import N from "../../compile/names"
+import type {SubschemaArgs} from "../../compile/validate/subschema"
+import {alwaysValidSchema, schemaRefOrVal, Type} from "../../compile/util"
+
+export type AdditionalPropertiesError = ErrorObject<
+  "additionalProperties",
+  {additionalProperty: string},
+  AnySchema
+>
+
+const error: KeywordErrorDefinition = {
+  message: "must NOT have additional properties",
+  params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
+}
+
+const def: CodeKeywordDefinition & AddedKeywordDefinition = {
+  keyword: "additionalProperties",
+  type: ["object"],
+  schemaType: ["boolean", "object"],
+  allowUndefined: true,
+  trackErrors: true,
+  error,
+  code(cxt) {
+    const {gen, schema, parentSchema, data, errsCount, it} = cxt
+    /* istanbul ignore if */
+    if (!errsCount) throw new Error("ajv implementation error")
+    const {allErrors, opts} = it
+    it.props = true
+    if (opts.removeAdditional !== "all" && alwaysValidSchema(it, schema)) return
+    const props = allSchemaProperties(parentSchema.properties)
+    const patProps = allSchemaProperties(parentSchema.patternProperties)
+    checkAdditionalProperties()
+    cxt.ok(_`${errsCount} === ${N.errors}`)
+
+    function checkAdditionalProperties(): void {
+      gen.forIn("key", data, (key: Name) => {
+        if (!props.length && !patProps.length) additionalPropertyCode(key)
+        else gen.if(isAdditional(key), () => additionalPropertyCode(key))
+      })
+    }
+
+    function isAdditional(key: Name): Code {
+      let definedProp: Code
+      if (props.length > 8) {
+        // TODO maybe an option instead of hard-coded 8?
+        const propsSchema = schemaRefOrVal(it, parentSchema.properties, "properties")
+        definedProp = isOwnProperty(gen, propsSchema as Code, key)
+      } else if (props.length) {
+        definedProp = or(...props.map((p) => _`${key} === ${p}`))
+      } else {
+        definedProp = nil
+      }
+      if (patProps.length) {
+        definedProp = or(definedProp, ...patProps.map((p) => _`${usePattern(cxt, p)}.test(${key})`))
+      }
+      return not(definedProp)
+    }
+
+    function deleteAdditional(key: Name): void {
+      gen.code(_`delete ${data}[${key}]`)
+    }
+
+    function additionalPropertyCode(key: Name): void {
+      if (opts.removeAdditional === "all" || (opts.removeAdditional && schema === false)) {
+        deleteAdditional(key)
+        return
+      }
+
+      if (schema === false) {
+        cxt.setParams({additionalProperty: key})
+        cxt.error()
+        if (!allErrors) gen.break()
+        return
+      }
+
+      if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
+        const valid = gen.name("valid")
+        if (opts.removeAdditional === "failing") {
+          applyAdditionalSchema(key, valid, false)
+          gen.if(not(valid), () => {
+            cxt.reset()
+            deleteAdditional(key)
+          })
+        } else {
+          applyAdditionalSchema(key, valid)
+          if (!allErrors) gen.if(not(valid), () => gen.break())
+        }
+      }
+    }
+
+    function applyAdditionalSchema(key: Name, valid: Name, errors?: false): void {
+      const subschema: SubschemaArgs = {
+        keyword: "additionalProperties",
+        dataProp: key,
+        dataPropType: Type.Str,
+      }
+      if (errors === false) {
+        Object.assign(subschema, {
+          compositeRule: true,
+          createErrors: false,
+          allErrors: false,
+        })
+      }
+      cxt.subschema(subschema, valid)
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/allOf.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/allOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/allOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,22 @@
+import type {CodeKeywordDefinition, AnySchema} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {alwaysValidSchema} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: "allOf",
+  schemaType: "array",
+  code(cxt: KeywordCxt) {
+    const {gen, schema, it} = cxt
+    /* istanbul ignore if */
+    if (!Array.isArray(schema)) throw new Error("ajv implementation error")
+    const valid = gen.name("valid")
+    schema.forEach((sch: AnySchema, i: number) => {
+      if (alwaysValidSchema(it, sch)) return
+      const schCxt = cxt.subschema({keyword: "allOf", schemaProp: i}, valid)
+      cxt.ok(valid)
+      cxt.mergeEvaluated(schCxt)
+    })
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,14 @@
+import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types"
+import {validateUnion} from "../code"
+
+export type AnyOfError = ErrorNoParams<"anyOf", AnySchema[]>
+
+const def: CodeKeywordDefinition = {
+  keyword: "anyOf",
+  schemaType: "array",
+  trackErrors: true,
+  code: validateUnion,
+  error: {message: "must match a schema in anyOf"},
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/contains.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/contains.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/contains.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,109 @@
+import type {
+  CodeKeywordDefinition,
+  KeywordErrorDefinition,
+  ErrorObject,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, Name} from "../../compile/codegen"
+import {alwaysValidSchema, checkStrictMode, Type} from "../../compile/util"
+
+export type ContainsError = ErrorObject<
+  "contains",
+  {minContains: number; maxContains?: number},
+  AnySchema
+>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {min, max}}) =>
+    max === undefined
+      ? str`must contain at least ${min} valid item(s)`
+      : str`must contain at least ${min} and no more than ${max} valid item(s)`,
+  params: ({params: {min, max}}) =>
+    max === undefined ? _`{minContains: ${min}}` : _`{minContains: ${min}, maxContains: ${max}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "contains",
+  type: "array",
+  schemaType: ["object", "boolean"],
+  before: "uniqueItems",
+  trackErrors: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, parentSchema, data, it} = cxt
+    let min: number
+    let max: number | undefined
+    const {minContains, maxContains} = parentSchema
+    if (it.opts.next) {
+      min = minContains === undefined ? 1 : minContains
+      max = maxContains
+    } else {
+      min = 1
+    }
+    const len = gen.const("len", _`${data}.length`)
+    cxt.setParams({min, max})
+    if (max === undefined && min === 0) {
+      checkStrictMode(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`)
+      return
+    }
+    if (max !== undefined && min > max) {
+      checkStrictMode(it, `"minContains" > "maxContains" is always invalid`)
+      cxt.fail()
+      return
+    }
+    if (alwaysValidSchema(it, schema)) {
+      let cond = _`${len} >= ${min}`
+      if (max !== undefined) cond = _`${cond} && ${len} <= ${max}`
+      cxt.pass(cond)
+      return
+    }
+
+    it.items = true
+    const valid = gen.name("valid")
+    if (max === undefined && min === 1) {
+      validateItems(valid, () => gen.if(valid, () => gen.break()))
+    } else if (min === 0) {
+      gen.let(valid, true)
+      if (max !== undefined) gen.if(_`${data}.length > 0`, validateItemsWithCount)
+    } else {
+      gen.let(valid, false)
+      validateItemsWithCount()
+    }
+    cxt.result(valid, () => cxt.reset())
+
+    function validateItemsWithCount(): void {
+      const schValid = gen.name("_valid")
+      const count = gen.let("count", 0)
+      validateItems(schValid, () => gen.if(schValid, () => checkLimits(count)))
+    }
+
+    function validateItems(_valid: Name, block: () => void): void {
+      gen.forRange("i", 0, len, (i) => {
+        cxt.subschema(
+          {
+            keyword: "contains",
+            dataProp: i,
+            dataPropType: Type.Num,
+            compositeRule: true,
+          },
+          _valid
+        )
+        block()
+      })
+    }
+
+    function checkLimits(count: Name): void {
+      gen.code(_`${count}++`)
+      if (max === undefined) {
+        gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true).break())
+      } else {
+        gen.if(_`${count} > ${max}`, () => gen.assign(valid, false).break())
+        if (min === 1) gen.assign(valid, true)
+        else gen.if(_`${count} >= ${min}`, () => gen.assign(valid, true))
+      }
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,112 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  SchemaMap,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str} from "../../compile/codegen"
+import {alwaysValidSchema} from "../../compile/util"
+import {checkReportMissingProp, checkMissingProp, reportMissingProp, propertyInData} from "../code"
+
+export type PropertyDependencies = {[K in string]?: string[]}
+
+export interface DependenciesErrorParams {
+  property: string
+  missingProperty: string
+  depsCount: number
+  deps: string // TODO change to string[]
+}
+
+type SchemaDependencies = SchemaMap
+
+export type DependenciesError = ErrorObject<
+  "dependencies",
+  DependenciesErrorParams,
+  {[K in string]?: string[] | AnySchema}
+>
+
+export const error: KeywordErrorDefinition = {
+  message: ({params: {property, depsCount, deps}}) => {
+    const property_ies = depsCount === 1 ? "property" : "properties"
+    return str`must have ${property_ies} ${deps} when property ${property} is present`
+  },
+  params: ({params: {property, depsCount, deps, missingProperty}}) =>
+    _`{property: ${property},
+    missingProperty: ${missingProperty},
+    depsCount: ${depsCount},
+    deps: ${deps}}`, // TODO change to reference
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "dependencies",
+  type: "object",
+  schemaType: "object",
+  error,
+  code(cxt: KeywordCxt) {
+    const [propDeps, schDeps] = splitDependencies(cxt)
+    validatePropertyDeps(cxt, propDeps)
+    validateSchemaDeps(cxt, schDeps)
+  },
+}
+
+function splitDependencies({schema}: KeywordCxt): [PropertyDependencies, SchemaDependencies] {
+  const propertyDeps: PropertyDependencies = {}
+  const schemaDeps: SchemaDependencies = {}
+  for (const key in schema) {
+    if (key === "__proto__") continue
+    const deps = Array.isArray(schema[key]) ? propertyDeps : schemaDeps
+    deps[key] = schema[key]
+  }
+  return [propertyDeps, schemaDeps]
+}
+
+export function validatePropertyDeps(
+  cxt: KeywordCxt,
+  propertyDeps: {[K in string]?: string[]} = cxt.schema
+): void {
+  const {gen, data, it} = cxt
+  if (Object.keys(propertyDeps).length === 0) return
+  const missing = gen.let("missing")
+  for (const prop in propertyDeps) {
+    const deps = propertyDeps[prop] as string[]
+    if (deps.length === 0) continue
+    const hasProperty = propertyInData(gen, data, prop, it.opts.ownProperties)
+    cxt.setParams({
+      property: prop,
+      depsCount: deps.length,
+      deps: deps.join(", "),
+    })
+    if (it.allErrors) {
+      gen.if(hasProperty, () => {
+        for (const depProp of deps) {
+          checkReportMissingProp(cxt, depProp)
+        }
+      })
+    } else {
+      gen.if(_`${hasProperty} && (${checkMissingProp(cxt, deps, missing)})`)
+      reportMissingProp(cxt, missing)
+      gen.else()
+    }
+  }
+}
+
+export function validateSchemaDeps(cxt: KeywordCxt, schemaDeps: SchemaMap = cxt.schema): void {
+  const {gen, data, keyword, it} = cxt
+  const valid = gen.name("valid")
+  for (const prop in schemaDeps) {
+    if (alwaysValidSchema(it, schemaDeps[prop] as AnySchema)) continue
+    gen.if(
+      propertyInData(gen, data, prop, it.opts.ownProperties),
+      () => {
+        const schCxt = cxt.subschema({keyword, schemaProp: prop}, valid)
+        cxt.mergeValidEvaluated(schCxt, valid)
+      },
+      () => gen.var(valid, true) // TODO var
+    )
+    cxt.ok(valid)
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,11 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {validateSchemaDeps} from "./dependencies"
+
+const def: CodeKeywordDefinition = {
+  keyword: "dependentSchemas",
+  type: "object",
+  schemaType: "object",
+  code: (cxt) => validateSchemaDeps(cxt),
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/if.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/if.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/if.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,80 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import type {SchemaObjCxt} from "../../compile"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, not, Name} from "../../compile/codegen"
+import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
+
+export type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySchema>
+
+const error: KeywordErrorDefinition = {
+  message: ({params}) => str`must match "${params.ifClause}" schema`,
+  params: ({params}) => _`{failingKeyword: ${params.ifClause}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "if",
+  schemaType: ["object", "boolean"],
+  trackErrors: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, parentSchema, it} = cxt
+    if (parentSchema.then === undefined && parentSchema.else === undefined) {
+      checkStrictMode(it, '"if" without "then" and "else" is ignored')
+    }
+    const hasThen = hasSchema(it, "then")
+    const hasElse = hasSchema(it, "else")
+    if (!hasThen && !hasElse) return
+
+    const valid = gen.let("valid", true)
+    const schValid = gen.name("_valid")
+    validateIf()
+    cxt.reset()
+
+    if (hasThen && hasElse) {
+      const ifClause = gen.let("ifClause")
+      cxt.setParams({ifClause})
+      gen.if(schValid, validateClause("then", ifClause), validateClause("else", ifClause))
+    } else if (hasThen) {
+      gen.if(schValid, validateClause("then"))
+    } else {
+      gen.if(not(schValid), validateClause("else"))
+    }
+
+    cxt.pass(valid, () => cxt.error(true))
+
+    function validateIf(): void {
+      const schCxt = cxt.subschema(
+        {
+          keyword: "if",
+          compositeRule: true,
+          createErrors: false,
+          allErrors: false,
+        },
+        schValid
+      )
+      cxt.mergeEvaluated(schCxt)
+    }
+
+    function validateClause(keyword: string, ifClause?: Name): () => void {
+      return () => {
+        const schCxt = cxt.subschema({keyword}, schValid)
+        gen.assign(valid, schValid)
+        cxt.mergeValidEvaluated(schCxt, valid)
+        if (ifClause) gen.assign(ifClause, _`${keyword}`)
+        else cxt.setParams({ifClause: keyword})
+      }
+    }
+  },
+}
+
+function hasSchema(it: SchemaObjCxt, keyword: string): boolean {
+  const schema = it.schema[keyword]
+  return schema !== undefined && !alwaysValidSchema(it, schema)
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,53 @@
+import type {ErrorNoParams, Vocabulary} from "../../types"
+import additionalItems, {AdditionalItemsError} from "./additionalItems"
+import prefixItems from "./prefixItems"
+import items from "./items"
+import items2020, {ItemsError} from "./items2020"
+import contains, {ContainsError} from "./contains"
+import dependencies, {DependenciesError} from "./dependencies"
+import propertyNames, {PropertyNamesError} from "./propertyNames"
+import additionalProperties, {AdditionalPropertiesError} from "./additionalProperties"
+import properties from "./properties"
+import patternProperties from "./patternProperties"
+import notKeyword, {NotKeywordError} from "./not"
+import anyOf, {AnyOfError} from "./anyOf"
+import oneOf, {OneOfError} from "./oneOf"
+import allOf from "./allOf"
+import ifKeyword, {IfKeywordError} from "./if"
+import thenElse from "./thenElse"
+
+export default function getApplicator(draft2020 = false): Vocabulary {
+  const applicator = [
+    // any
+    notKeyword,
+    anyOf,
+    oneOf,
+    allOf,
+    ifKeyword,
+    thenElse,
+    // object
+    propertyNames,
+    additionalProperties,
+    dependencies,
+    properties,
+    patternProperties,
+  ]
+  // array
+  if (draft2020) applicator.push(prefixItems, items2020)
+  else applicator.push(additionalItems, items)
+  applicator.push(contains)
+  return applicator
+}
+
+export type ApplicatorKeywordError =
+  | ErrorNoParams<"false schema">
+  | AdditionalItemsError
+  | ItemsError
+  | ContainsError
+  | AdditionalPropertiesError
+  | DependenciesError
+  | IfKeywordError
+  | AnyOfError
+  | OneOfError
+  | NotKeywordError
+  | PropertyNamesError
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,59 @@
+import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_} from "../../compile/codegen"
+import {alwaysValidSchema, mergeEvaluated, checkStrictMode} from "../../compile/util"
+import {validateArray} from "../code"
+
+const def: CodeKeywordDefinition = {
+  keyword: "items",
+  type: "array",
+  schemaType: ["object", "array", "boolean"],
+  before: "uniqueItems",
+  code(cxt: KeywordCxt) {
+    const {schema, it} = cxt
+    if (Array.isArray(schema)) return validateTuple(cxt, "additionalItems", schema)
+    it.items = true
+    if (alwaysValidSchema(it, schema)) return
+    cxt.ok(validateArray(cxt))
+  },
+}
+
+export function validateTuple(
+  cxt: KeywordCxt,
+  extraItems: string,
+  schArr: AnySchema[] = cxt.schema
+): void {
+  const {gen, parentSchema, data, keyword, it} = cxt
+  checkStrictTuple(parentSchema)
+  if (it.opts.unevaluated && schArr.length && it.items !== true) {
+    it.items = mergeEvaluated.items(gen, schArr.length, it.items)
+  }
+  const valid = gen.name("valid")
+  const len = gen.const("len", _`${data}.length`)
+  schArr.forEach((sch: AnySchema, i: number) => {
+    if (alwaysValidSchema(it, sch)) return
+    gen.if(_`${len} > ${i}`, () =>
+      cxt.subschema(
+        {
+          keyword,
+          schemaProp: i,
+          dataProp: i,
+        },
+        valid
+      )
+    )
+    cxt.ok(valid)
+  })
+
+  function checkStrictTuple(sch: AnySchemaObject): void {
+    const {opts, errSchemaPath} = it
+    const l = schArr.length
+    const fullTuple = l === sch.minItems && (l === sch.maxItems || sch[extraItems] === false)
+    if (opts.strictTuples && !fullTuple) {
+      const msg = `"${keyword}" is ${l}-tuple, but minItems or maxItems/${extraItems} are not specified or different at path "${errSchemaPath}"`
+      checkStrictMode(it, msg, opts.strictTuples)
+    }
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items2020.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items2020.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/items2020.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,36 @@
+import type {
+  CodeKeywordDefinition,
+  KeywordErrorDefinition,
+  ErrorObject,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str} from "../../compile/codegen"
+import {alwaysValidSchema} from "../../compile/util"
+import {validateArray} from "../code"
+import {validateAdditionalItems} from "./additionalItems"
+
+export type ItemsError = ErrorObject<"items", {limit: number}, AnySchema>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {len}}) => str`must NOT have more than ${len} items`,
+  params: ({params: {len}}) => _`{limit: ${len}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "items",
+  type: "array",
+  schemaType: ["object", "boolean"],
+  before: "uniqueItems",
+  error,
+  code(cxt: KeywordCxt) {
+    const {schema, parentSchema, it} = cxt
+    const {prefixItems} = parentSchema
+    it.items = true
+    if (alwaysValidSchema(it, schema)) return
+    if (prefixItems) validateAdditionalItems(cxt, prefixItems)
+    else cxt.ok(validateArray(cxt))
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/not.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/not.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/not.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,38 @@
+import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {alwaysValidSchema} from "../../compile/util"
+
+export type NotKeywordError = ErrorNoParams<"not", AnySchema>
+
+const def: CodeKeywordDefinition = {
+  keyword: "not",
+  schemaType: ["object", "boolean"],
+  trackErrors: true,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, it} = cxt
+    if (alwaysValidSchema(it, schema)) {
+      cxt.fail()
+      return
+    }
+
+    const valid = gen.name("valid")
+    cxt.subschema(
+      {
+        keyword: "not",
+        compositeRule: true,
+        createErrors: false,
+        allErrors: false,
+      },
+      valid
+    )
+
+    cxt.failResult(
+      valid,
+      () => cxt.reset(),
+      () => cxt.error()
+    )
+  },
+  error: {message: "must NOT be valid"},
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,82 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, Name} from "../../compile/codegen"
+import {alwaysValidSchema} from "../../compile/util"
+import {SchemaCxt} from "../../compile"
+
+export type OneOfError = ErrorObject<
+  "oneOf",
+  {passingSchemas: [number, number] | null},
+  AnySchema[]
+>
+
+const error: KeywordErrorDefinition = {
+  message: "must match exactly one schema in oneOf",
+  params: ({params}) => _`{passingSchemas: ${params.passing}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "oneOf",
+  schemaType: "array",
+  trackErrors: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, parentSchema, it} = cxt
+    /* istanbul ignore if */
+    if (!Array.isArray(schema)) throw new Error("ajv implementation error")
+    if (it.opts.discriminator && parentSchema.discriminator) return
+    const schArr: AnySchema[] = schema
+    const valid = gen.let("valid", false)
+    const passing = gen.let("passing", null)
+    const schValid = gen.name("_valid")
+    cxt.setParams({passing})
+    // TODO possibly fail straight away (with warning or exception) if there are two empty always valid schemas
+
+    gen.block(validateOneOf)
+
+    cxt.result(
+      valid,
+      () => cxt.reset(),
+      () => cxt.error(true)
+    )
+
+    function validateOneOf(): void {
+      schArr.forEach((sch: AnySchema, i: number) => {
+        let schCxt: SchemaCxt | undefined
+        if (alwaysValidSchema(it, sch)) {
+          gen.var(schValid, true)
+        } else {
+          schCxt = cxt.subschema(
+            {
+              keyword: "oneOf",
+              schemaProp: i,
+              compositeRule: true,
+            },
+            schValid
+          )
+        }
+
+        if (i > 0) {
+          gen
+            .if(_`${schValid} && ${valid}`)
+            .assign(valid, false)
+            .assign(passing, _`[${passing}, ${i}]`)
+            .else()
+        }
+
+        gen.if(schValid, () => {
+          gen.assign(valid, true)
+          gen.assign(passing, i)
+          if (schCxt) cxt.mergeEvaluated(schCxt, Name)
+        })
+      })
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,91 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {allSchemaProperties, usePattern} from "../code"
+import {_, not, Name} from "../../compile/codegen"
+import {alwaysValidSchema, checkStrictMode} from "../../compile/util"
+import {evaluatedPropsToName, Type} from "../../compile/util"
+import {AnySchema} from "../../types"
+
+const def: CodeKeywordDefinition = {
+  keyword: "patternProperties",
+  type: "object",
+  schemaType: "object",
+  code(cxt: KeywordCxt) {
+    const {gen, schema, data, parentSchema, it} = cxt
+    const {opts} = it
+    const patterns = allSchemaProperties(schema)
+    const alwaysValidPatterns = patterns.filter((p) =>
+      alwaysValidSchema(it, schema[p] as AnySchema)
+    )
+
+    if (
+      patterns.length === 0 ||
+      (alwaysValidPatterns.length === patterns.length &&
+        (!it.opts.unevaluated || it.props === true))
+    ) {
+      return
+    }
+
+    const checkProperties =
+      opts.strictSchema && !opts.allowMatchingProperties && parentSchema.properties
+    const valid = gen.name("valid")
+    if (it.props !== true && !(it.props instanceof Name)) {
+      it.props = evaluatedPropsToName(gen, it.props)
+    }
+    const {props} = it
+    validatePatternProperties()
+
+    function validatePatternProperties(): void {
+      for (const pat of patterns) {
+        if (checkProperties) checkMatchingProperties(pat)
+        if (it.allErrors) {
+          validateProperties(pat)
+        } else {
+          gen.var(valid, true) // TODO var
+          validateProperties(pat)
+          gen.if(valid)
+        }
+      }
+    }
+
+    function checkMatchingProperties(pat: string): void {
+      for (const prop in checkProperties) {
+        if (new RegExp(pat).test(prop)) {
+          checkStrictMode(
+            it,
+            `property ${prop} matches pattern ${pat} (use allowMatchingProperties)`
+          )
+        }
+      }
+    }
+
+    function validateProperties(pat: string): void {
+      gen.forIn("key", data, (key) => {
+        gen.if(_`${usePattern(cxt, pat)}.test(${key})`, () => {
+          const alwaysValid = alwaysValidPatterns.includes(pat)
+          if (!alwaysValid) {
+            cxt.subschema(
+              {
+                keyword: "patternProperties",
+                schemaProp: pat,
+                dataProp: key,
+                dataPropType: Type.Str,
+              },
+              valid
+            )
+          }
+
+          if (it.opts.unevaluated && props !== true) {
+            gen.assign(_`${props}[${key}]`, true)
+          } else if (!alwaysValid && !it.allErrors) {
+            // can short-circuit if `unevaluatedProperties` is not supported (opts.next === false)
+            // or if all properties were evaluated (props === true)
+            gen.if(not(valid), () => gen.break())
+          }
+        })
+      })
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,12 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {validateTuple} from "./items"
+
+const def: CodeKeywordDefinition = {
+  keyword: "prefixItems",
+  type: "array",
+  schemaType: ["array"],
+  before: "uniqueItems",
+  code: (cxt) => validateTuple(cxt, "items"),
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/properties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/properties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/properties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,57 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {KeywordCxt} from "../../compile/validate"
+import {propertyInData, allSchemaProperties} from "../code"
+import {alwaysValidSchema, toHash, mergeEvaluated} from "../../compile/util"
+import apDef from "./additionalProperties"
+
+const def: CodeKeywordDefinition = {
+  keyword: "properties",
+  type: "object",
+  schemaType: "object",
+  code(cxt: KeywordCxt) {
+    const {gen, schema, parentSchema, data, it} = cxt
+    if (it.opts.removeAdditional === "all" && parentSchema.additionalProperties === undefined) {
+      apDef.code(new KeywordCxt(it, apDef, "additionalProperties"))
+    }
+    const allProps = allSchemaProperties(schema)
+    for (const prop of allProps) {
+      it.definedProperties.add(prop)
+    }
+    if (it.opts.unevaluated && allProps.length && it.props !== true) {
+      it.props = mergeEvaluated.props(gen, toHash(allProps), it.props)
+    }
+    const properties = allProps.filter((p) => !alwaysValidSchema(it, schema[p]))
+    if (properties.length === 0) return
+    const valid = gen.name("valid")
+
+    for (const prop of properties) {
+      if (hasDefault(prop)) {
+        applyPropertySchema(prop)
+      } else {
+        gen.if(propertyInData(gen, data, prop, it.opts.ownProperties))
+        applyPropertySchema(prop)
+        if (!it.allErrors) gen.else().var(valid, true)
+        gen.endIf()
+      }
+      cxt.it.definedProperties.add(prop)
+      cxt.ok(valid)
+    }
+
+    function hasDefault(prop: string): boolean | undefined {
+      return it.opts.useDefaults && !it.compositeRule && schema[prop].default !== undefined
+    }
+
+    function applyPropertySchema(prop: string): void {
+      cxt.subschema(
+        {
+          keyword: "properties",
+          schemaProp: prop,
+          dataProp: prop,
+        },
+        valid
+      )
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,50 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, not} from "../../compile/codegen"
+import {alwaysValidSchema} from "../../compile/util"
+
+export type PropertyNamesError = ErrorObject<"propertyNames", {propertyName: string}, AnySchema>
+
+const error: KeywordErrorDefinition = {
+  message: "property name must be valid",
+  params: ({params}) => _`{propertyName: ${params.propertyName}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "propertyNames",
+  type: "object",
+  schemaType: ["object", "boolean"],
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, data, it} = cxt
+    if (alwaysValidSchema(it, schema)) return
+    const valid = gen.name("valid")
+
+    gen.forIn("key", data, (key) => {
+      cxt.setParams({propertyName: key})
+      cxt.subschema(
+        {
+          keyword: "propertyNames",
+          data: key,
+          dataTypes: ["string"],
+          propertyName: key,
+          compositeRule: true,
+        },
+        valid
+      )
+      gen.if(not(valid), () => {
+        cxt.error(true)
+        if (!it.allErrors) gen.break()
+      })
+    })
+
+    cxt.ok(valid)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,13 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {checkStrictMode} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: ["then", "else"],
+  schemaType: ["object", "boolean"],
+  code({keyword, parentSchema, it}: KeywordCxt) {
+    if (parentSchema.if === undefined) checkStrictMode(it, `"${keyword}" without "if" is ignored`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/code.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/code.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/code.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,168 @@
+import type {AnySchema, SchemaMap} from "../types"
+import type {SchemaCxt} from "../compile"
+import type {KeywordCxt} from "../compile/validate"
+import {CodeGen, _, and, or, not, nil, strConcat, getProperty, Code, Name} from "../compile/codegen"
+import {alwaysValidSchema, Type} from "../compile/util"
+import N from "../compile/names"
+import {useFunc} from "../compile/util"
+export function checkReportMissingProp(cxt: KeywordCxt, prop: string): void {
+  const {gen, data, it} = cxt
+  gen.if(noPropertyInData(gen, data, prop, it.opts.ownProperties), () => {
+    cxt.setParams({missingProperty: _`${prop}`}, true)
+    cxt.error()
+  })
+}
+
+export function checkMissingProp(
+  {gen, data, it: {opts}}: KeywordCxt,
+  properties: string[],
+  missing: Name
+): Code {
+  return or(
+    ...properties.map((prop) =>
+      and(noPropertyInData(gen, data, prop, opts.ownProperties), _`${missing} = ${prop}`)
+    )
+  )
+}
+
+export function reportMissingProp(cxt: KeywordCxt, missing: Name): void {
+  cxt.setParams({missingProperty: missing}, true)
+  cxt.error()
+}
+
+export function hasPropFunc(gen: CodeGen): Name {
+  return gen.scopeValue("func", {
+    // eslint-disable-next-line @typescript-eslint/unbound-method
+    ref: Object.prototype.hasOwnProperty,
+    code: _`Object.prototype.hasOwnProperty`,
+  })
+}
+
+export function isOwnProperty(gen: CodeGen, data: Name, property: Name | string): Code {
+  return _`${hasPropFunc(gen)}.call(${data}, ${property})`
+}
+
+export function propertyInData(
+  gen: CodeGen,
+  data: Name,
+  property: Name | string,
+  ownProperties?: boolean
+): Code {
+  const cond = _`${data}${getProperty(property)} !== undefined`
+  return ownProperties ? _`${cond} && ${isOwnProperty(gen, data, property)}` : cond
+}
+
+export function noPropertyInData(
+  gen: CodeGen,
+  data: Name,
+  property: Name | string,
+  ownProperties?: boolean
+): Code {
+  const cond = _`${data}${getProperty(property)} === undefined`
+  return ownProperties ? or(cond, not(isOwnProperty(gen, data, property))) : cond
+}
+
+export function allSchemaProperties(schemaMap?: SchemaMap): string[] {
+  return schemaMap ? Object.keys(schemaMap).filter((p) => p !== "__proto__") : []
+}
+
+export function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] {
+  return allSchemaProperties(schemaMap).filter(
+    (p) => !alwaysValidSchema(it, schemaMap[p] as AnySchema)
+  )
+}
+
+export function callValidateCode(
+  {schemaCode, data, it: {gen, topSchemaRef, schemaPath, errorPath}, it}: KeywordCxt,
+  func: Code,
+  context: Code,
+  passSchema?: boolean
+): Code {
+  const dataAndSchema = passSchema ? _`${schemaCode}, ${data}, ${topSchemaRef}${schemaPath}` : data
+  const valCxt: [Name, Code | number][] = [
+    [N.instancePath, strConcat(N.instancePath, errorPath)],
+    [N.parentData, it.parentData],
+    [N.parentDataProperty, it.parentDataProperty],
+    [N.rootData, N.rootData],
+  ]
+  if (it.opts.dynamicRef) valCxt.push([N.dynamicAnchors, N.dynamicAnchors])
+  const args = _`${dataAndSchema}, ${gen.object(...valCxt)}`
+  return context !== nil ? _`${func}.call(${context}, ${args})` : _`${func}(${args})`
+}
+
+const newRegExp = _`new RegExp`
+
+export function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name {
+  const u = opts.unicodeRegExp ? "u" : ""
+  const {regExp} = opts.code
+  const rx = regExp(pattern, u)
+
+  return gen.scopeValue("pattern", {
+    key: rx.toString(),
+    ref: rx,
+    code: _`${regExp.code === "new RegExp" ? newRegExp : useFunc(gen, regExp)}(${pattern}, ${u})`,
+  })
+}
+
+export function validateArray(cxt: KeywordCxt): Name {
+  const {gen, data, keyword, it} = cxt
+  const valid = gen.name("valid")
+  if (it.allErrors) {
+    const validArr = gen.let("valid", true)
+    validateItems(() => gen.assign(validArr, false))
+    return validArr
+  }
+  gen.var(valid, true)
+  validateItems(() => gen.break())
+  return valid
+
+  function validateItems(notValid: () => void): void {
+    const len = gen.const("len", _`${data}.length`)
+    gen.forRange("i", 0, len, (i) => {
+      cxt.subschema(
+        {
+          keyword,
+          dataProp: i,
+          dataPropType: Type.Num,
+        },
+        valid
+      )
+      gen.if(not(valid), notValid)
+    })
+  }
+}
+
+export function validateUnion(cxt: KeywordCxt): void {
+  const {gen, schema, keyword, it} = cxt
+  /* istanbul ignore if */
+  if (!Array.isArray(schema)) throw new Error("ajv implementation error")
+  const alwaysValid = schema.some((sch: AnySchema) => alwaysValidSchema(it, sch))
+  if (alwaysValid && !it.opts.unevaluated) return
+
+  const valid = gen.let("valid", false)
+  const schValid = gen.name("_valid")
+
+  gen.block(() =>
+    schema.forEach((_sch: AnySchema, i: number) => {
+      const schCxt = cxt.subschema(
+        {
+          keyword,
+          schemaProp: i,
+          compositeRule: true,
+        },
+        schValid
+      )
+      gen.assign(valid, _`${valid} || ${schValid}`)
+      const merged = cxt.mergeValidEvaluated(schCxt, schValid)
+      // can short-circuit if `unevaluatedProperties/Items` not supported (opts.unevaluated !== true)
+      // or if all properties and items were evaluated (it.props === true && it.items === true)
+      if (!merged) gen.if(not(valid))
+    })
+  )
+
+  cxt.result(
+    valid,
+    () => cxt.reset(),
+    () => cxt.error(true)
+  )
+}
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/core/id.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/core/id.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/core/id.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,10 @@
+import type {CodeKeywordDefinition} from "../../types"
+
+const def: CodeKeywordDefinition = {
+  keyword: "id",
+  code() {
+    throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schema ID')
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/core/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/core/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/core/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,16 @@
+import type {Vocabulary} from "../../types"
+import idKeyword from "./id"
+import refKeyword from "./ref"
+
+const core: Vocabulary = [
+  "$schema",
+  "$id",
+  "$defs",
+  "$vocabulary",
+  {keyword: "$comment"},
+  "definitions",
+  idKeyword,
+  refKeyword,
+]
+
+export default core
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/core/ref.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/core/ref.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/core/ref.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,129 @@
+import type {CodeKeywordDefinition, AnySchema} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import MissingRefError from "../../compile/ref_error"
+import {callValidateCode} from "../code"
+import {_, nil, stringify, Code, Name} from "../../compile/codegen"
+import N from "../../compile/names"
+import {SchemaEnv, resolveRef} from "../../compile"
+import {mergeEvaluated} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: "$ref",
+  schemaType: "string",
+  code(cxt: KeywordCxt): void {
+    const {gen, schema: $ref, it} = cxt
+    const {baseId, schemaEnv: env, validateName, opts, self} = it
+    const {root} = env
+    if (($ref === "#" || $ref === "#/") && baseId === root.baseId) return callRootRef()
+    const schOrEnv = resolveRef.call(self, root, baseId, $ref)
+    if (schOrEnv === undefined) throw new MissingRefError(it.opts.uriResolver, baseId, $ref)
+    if (schOrEnv instanceof SchemaEnv) return callValidate(schOrEnv)
+    return inlineRefSchema(schOrEnv)
+
+    function callRootRef(): void {
+      if (env === root) return callRef(cxt, validateName, env, env.$async)
+      const rootName = gen.scopeValue("root", {ref: root})
+      return callRef(cxt, _`${rootName}.validate`, root, root.$async)
+    }
+
+    function callValidate(sch: SchemaEnv): void {
+      const v = getValidate(cxt, sch)
+      callRef(cxt, v, sch, sch.$async)
+    }
+
+    function inlineRefSchema(sch: AnySchema): void {
+      const schName = gen.scopeValue(
+        "schema",
+        opts.code.source === true ? {ref: sch, code: stringify(sch)} : {ref: sch}
+      )
+      const valid = gen.name("valid")
+      const schCxt = cxt.subschema(
+        {
+          schema: sch,
+          dataTypes: [],
+          schemaPath: nil,
+          topSchemaRef: schName,
+          errSchemaPath: $ref,
+        },
+        valid
+      )
+      cxt.mergeEvaluated(schCxt)
+      cxt.ok(valid)
+    }
+  },
+}
+
+export function getValidate(cxt: KeywordCxt, sch: SchemaEnv): Code {
+  const {gen} = cxt
+  return sch.validate
+    ? gen.scopeValue("validate", {ref: sch.validate})
+    : _`${gen.scopeValue("wrapper", {ref: sch})}.validate`
+}
+
+export function callRef(cxt: KeywordCxt, v: Code, sch?: SchemaEnv, $async?: boolean): void {
+  const {gen, it} = cxt
+  const {allErrors, schemaEnv: env, opts} = it
+  const passCxt = opts.passContext ? N.this : nil
+  if ($async) callAsyncRef()
+  else callSyncRef()
+
+  function callAsyncRef(): void {
+    if (!env.$async) throw new Error("async schema referenced by sync schema")
+    const valid = gen.let("valid")
+    gen.try(
+      () => {
+        gen.code(_`await ${callValidateCode(cxt, v, passCxt)}`)
+        addEvaluatedFrom(v) // TODO will not work with async, it has to be returned with the result
+        if (!allErrors) gen.assign(valid, true)
+      },
+      (e) => {
+        gen.if(_`!(${e} instanceof ${it.ValidationError as Name})`, () => gen.throw(e))
+        addErrorsFrom(e)
+        if (!allErrors) gen.assign(valid, false)
+      }
+    )
+    cxt.ok(valid)
+  }
+
+  function callSyncRef(): void {
+    cxt.result(
+      callValidateCode(cxt, v, passCxt),
+      () => addEvaluatedFrom(v),
+      () => addErrorsFrom(v)
+    )
+  }
+
+  function addErrorsFrom(source: Code): void {
+    const errs = _`${source}.errors`
+    gen.assign(N.vErrors, _`${N.vErrors} === null ? ${errs} : ${N.vErrors}.concat(${errs})`) // TODO tagged
+    gen.assign(N.errors, _`${N.vErrors}.length`)
+  }
+
+  function addEvaluatedFrom(source: Code): void {
+    if (!it.opts.unevaluated) return
+    const schEvaluated = sch?.validate?.evaluated
+    // TODO refactor
+    if (it.props !== true) {
+      if (schEvaluated && !schEvaluated.dynamicProps) {
+        if (schEvaluated.props !== undefined) {
+          it.props = mergeEvaluated.props(gen, schEvaluated.props, it.props)
+        }
+      } else {
+        const props = gen.var("props", _`${source}.evaluated.props`)
+        it.props = mergeEvaluated.props(gen, props, it.props, Name)
+      }
+    }
+    if (it.items !== true) {
+      if (schEvaluated && !schEvaluated.dynamicItems) {
+        if (schEvaluated.items !== undefined) {
+          it.items = mergeEvaluated.items(gen, schEvaluated.items, it.items)
+        }
+      } else {
+        const items = gen.var("items", _`${source}.evaluated.items`)
+        it.items = mergeEvaluated.items(gen, items, it.items, Name)
+      }
+    }
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,113 @@
+import type {CodeKeywordDefinition, AnySchemaObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, getProperty, Name} from "../../compile/codegen"
+import {DiscrError, DiscrErrorObj} from "../discriminator/types"
+import {resolveRef, SchemaEnv} from "../../compile"
+import MissingRefError from "../../compile/ref_error"
+import {schemaHasRulesButRef} from "../../compile/util"
+
+export type DiscriminatorError = DiscrErrorObj<DiscrError.Tag> | DiscrErrorObj<DiscrError.Mapping>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {discrError, tagName}}) =>
+    discrError === DiscrError.Tag
+      ? `tag "${tagName}" must be string`
+      : `value of tag "${tagName}" must be in oneOf`,
+  params: ({params: {discrError, tag, tagName}}) =>
+    _`{error: ${discrError}, tag: ${tagName}, tagValue: ${tag}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "discriminator",
+  type: "object",
+  schemaType: "object",
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, data, schema, parentSchema, it} = cxt
+    const {oneOf} = parentSchema
+    if (!it.opts.discriminator) {
+      throw new Error("discriminator: requires discriminator option")
+    }
+    const tagName = schema.propertyName
+    if (typeof tagName != "string") throw new Error("discriminator: requires propertyName")
+    if (schema.mapping) throw new Error("discriminator: mapping is not supported")
+    if (!oneOf) throw new Error("discriminator: requires oneOf keyword")
+    const valid = gen.let("valid", false)
+    const tag = gen.const("tag", _`${data}${getProperty(tagName)}`)
+    gen.if(
+      _`typeof ${tag} == "string"`,
+      () => validateMapping(),
+      () => cxt.error(false, {discrError: DiscrError.Tag, tag, tagName})
+    )
+    cxt.ok(valid)
+
+    function validateMapping(): void {
+      const mapping = getMapping()
+      gen.if(false)
+      for (const tagValue in mapping) {
+        gen.elseIf(_`${tag} === ${tagValue}`)
+        gen.assign(valid, applyTagSchema(mapping[tagValue]))
+      }
+      gen.else()
+      cxt.error(false, {discrError: DiscrError.Mapping, tag, tagName})
+      gen.endIf()
+    }
+
+    function applyTagSchema(schemaProp?: number): Name {
+      const _valid = gen.name("valid")
+      const schCxt = cxt.subschema({keyword: "oneOf", schemaProp}, _valid)
+      cxt.mergeEvaluated(schCxt, Name)
+      return _valid
+    }
+
+    function getMapping(): {[T in string]?: number} {
+      const oneOfMapping: {[T in string]?: number} = {}
+      const topRequired = hasRequired(parentSchema)
+      let tagRequired = true
+      for (let i = 0; i < oneOf.length; i++) {
+        let sch = oneOf[i]
+        if (sch?.$ref && !schemaHasRulesButRef(sch, it.self.RULES)) {
+          const ref = sch.$ref
+          sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, ref)
+          if (sch instanceof SchemaEnv) sch = sch.schema
+          if (sch === undefined) throw new MissingRefError(it.opts.uriResolver, it.baseId, ref)
+        }
+        const propSch = sch?.properties?.[tagName]
+        if (typeof propSch != "object") {
+          throw new Error(
+            `discriminator: oneOf subschemas (or referenced schemas) must have "properties/${tagName}"`
+          )
+        }
+        tagRequired = tagRequired && (topRequired || hasRequired(sch))
+        addMappings(propSch, i)
+      }
+      if (!tagRequired) throw new Error(`discriminator: "${tagName}" must be required`)
+      return oneOfMapping
+
+      function hasRequired({required}: AnySchemaObject): boolean {
+        return Array.isArray(required) && required.includes(tagName)
+      }
+
+      function addMappings(sch: AnySchemaObject, i: number): void {
+        if (sch.const) {
+          addMapping(sch.const, i)
+        } else if (sch.enum) {
+          for (const tagValue of sch.enum) {
+            addMapping(tagValue, i)
+          }
+        } else {
+          throw new Error(`discriminator: "properties/${tagName}" must have "const" or "enum"`)
+        }
+      }
+
+      function addMapping(tagValue: unknown, i: number): void {
+        if (typeof tagValue != "string" || tagValue in oneOfMapping) {
+          throw new Error(`discriminator: "${tagName}" values must be unique strings`)
+        }
+        oneOfMapping[tagValue] = i
+      }
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/types.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/types.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/discriminator/types.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,12 @@
+import type {ErrorObject} from "../../types"
+
+export enum DiscrError {
+  Tag = "tag",
+  Mapping = "mapping",
+}
+
+export type DiscrErrorObj<E extends DiscrError> = ErrorObject<
+  "discriminator",
+  {error: E; tag: string; tagValue: unknown},
+  string
+>
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/draft2020.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/draft2020.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/draft2020.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,23 @@
+import type {Vocabulary} from "../types"
+import coreVocabulary from "./core"
+import validationVocabulary from "./validation"
+import getApplicatorVocabulary from "./applicator"
+import dynamicVocabulary from "./dynamic"
+import nextVocabulary from "./next"
+import unevaluatedVocabulary from "./unevaluated"
+import formatVocabulary from "./format"
+import {metadataVocabulary, contentVocabulary} from "./metadata"
+
+const draft2020Vocabularies: Vocabulary[] = [
+  dynamicVocabulary,
+  coreVocabulary,
+  validationVocabulary,
+  getApplicatorVocabulary(true),
+  formatVocabulary,
+  metadataVocabulary,
+  contentVocabulary,
+  nextVocabulary,
+  unevaluatedVocabulary,
+]
+
+export default draft2020Vocabularies
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/draft7.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/draft7.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/draft7.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,17 @@
+import type {Vocabulary} from "../types"
+import coreVocabulary from "./core"
+import validationVocabulary from "./validation"
+import getApplicatorVocabulary from "./applicator"
+import formatVocabulary from "./format"
+import {metadataVocabulary, contentVocabulary} from "./metadata"
+
+const draft7Vocabularies: Vocabulary[] = [
+  coreVocabulary,
+  validationVocabulary,
+  getApplicatorVocabulary(),
+  formatVocabulary,
+  metadataVocabulary,
+  contentVocabulary,
+]
+
+export default draft7Vocabularies
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,31 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, getProperty, Code} from "../../compile/codegen"
+import N from "../../compile/names"
+import {SchemaEnv, compileSchema} from "../../compile"
+import {getValidate} from "../core/ref"
+
+const def: CodeKeywordDefinition = {
+  keyword: "$dynamicAnchor",
+  schemaType: "string",
+  code: (cxt) => dynamicAnchor(cxt, cxt.schema),
+}
+
+export function dynamicAnchor(cxt: KeywordCxt, anchor: string): void {
+  const {gen, it} = cxt
+  it.schemaEnv.root.dynamicAnchors[anchor] = true
+  const v = _`${N.dynamicAnchors}${getProperty(anchor)}`
+  const validate = it.errSchemaPath === "#" ? it.validateName : _getValidate(cxt)
+  gen.if(_`!${v}`, () => gen.assign(v, validate))
+}
+
+function _getValidate(cxt: KeywordCxt): Code {
+  const {schemaEnv, schema, self} = cxt.it
+  const {root, baseId, localRefs, meta} = schemaEnv.root
+  const {schemaId} = self.opts
+  const sch = new SchemaEnv({schema, schemaId, root, baseId, localRefs, meta})
+  compileSchema.call(self, sch)
+  return getValidate(cxt, sch)
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,51 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, getProperty, Code, Name} from "../../compile/codegen"
+import N from "../../compile/names"
+import {callRef} from "../core/ref"
+
+const def: CodeKeywordDefinition = {
+  keyword: "$dynamicRef",
+  schemaType: "string",
+  code: (cxt) => dynamicRef(cxt, cxt.schema),
+}
+
+export function dynamicRef(cxt: KeywordCxt, ref: string): void {
+  const {gen, keyword, it} = cxt
+  if (ref[0] !== "#") throw new Error(`"${keyword}" only supports hash fragment reference`)
+  const anchor = ref.slice(1)
+  if (it.allErrors) {
+    _dynamicRef()
+  } else {
+    const valid = gen.let("valid", false)
+    _dynamicRef(valid)
+    cxt.ok(valid)
+  }
+
+  function _dynamicRef(valid?: Name): void {
+    // TODO the assumption here is that `recursiveRef: #` always points to the root
+    // of the schema object, which is not correct, because there may be $id that
+    // makes # point to it, and the target schema may not contain dynamic/recursiveAnchor.
+    // Because of that 2 tests in recursiveRef.json fail.
+    // This is a similar problem to #815 (`$id` doesn't alter resolution scope for `{ "$ref": "#" }`).
+    // (This problem is not tested in JSON-Schema-Test-Suite)
+    if (it.schemaEnv.root.dynamicAnchors[anchor]) {
+      const v = gen.let("_v", _`${N.dynamicAnchors}${getProperty(anchor)}`)
+      gen.if(v, _callRef(v, valid), _callRef(it.validateName, valid))
+    } else {
+      _callRef(it.validateName, valid)()
+    }
+  }
+
+  function _callRef(validate: Code, valid?: Name): () => void {
+    return valid
+      ? () =>
+          gen.block(() => {
+            callRef(cxt, validate)
+            gen.let(valid, true)
+          })
+      : () => callRef(cxt, validate)
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,9 @@
+import type {Vocabulary} from "../../types"
+import dynamicAnchor from "./dynamicAnchor"
+import dynamicRef from "./dynamicRef"
+import recursiveAnchor from "./recursiveAnchor"
+import recursiveRef from "./recursiveRef"
+
+const dynamic: Vocabulary = [dynamicAnchor, dynamicRef, recursiveAnchor, recursiveRef]
+
+export default dynamic
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,14 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {dynamicAnchor} from "./dynamicAnchor"
+import {checkStrictMode} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: "$recursiveAnchor",
+  schemaType: "boolean",
+  code(cxt) {
+    if (cxt.schema) dynamicAnchor(cxt, "")
+    else checkStrictMode(cxt.it, "$recursiveAnchor: false is ignored")
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,10 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {dynamicRef} from "./dynamicRef"
+
+const def: CodeKeywordDefinition = {
+  keyword: "$recursiveRef",
+  schemaType: "string",
+  code: (cxt) => dynamicRef(cxt, cxt.schema),
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/errors.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/errors.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/errors.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,18 @@
+import type {TypeError} from "../compile/validate/dataType"
+import type {ApplicatorKeywordError} from "./applicator"
+import type {ValidationKeywordError} from "./validation"
+import type {FormatError} from "./format/format"
+import type {UnevaluatedPropertiesError} from "./unevaluated/unevaluatedProperties"
+import type {UnevaluatedItemsError} from "./unevaluated/unevaluatedItems"
+import type {DependentRequiredError} from "./validation/dependentRequired"
+import type {DiscriminatorError} from "./discriminator"
+
+export type DefinedError =
+  | TypeError
+  | ApplicatorKeywordError
+  | ValidationKeywordError
+  | FormatError
+  | UnevaluatedPropertiesError
+  | UnevaluatedItemsError
+  | DependentRequiredError
+  | DiscriminatorError
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/format/format.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/format/format.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/format/format.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,120 @@
+import type {
+  AddedFormat,
+  FormatValidator,
+  AsyncFormatValidator,
+  CodeKeywordDefinition,
+  KeywordErrorDefinition,
+  ErrorObject,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, nil, or, Code, getProperty, regexpCode} from "../../compile/codegen"
+
+type FormatValidate =
+  | FormatValidator<string>
+  | FormatValidator<number>
+  | AsyncFormatValidator<string>
+  | AsyncFormatValidator<number>
+  | RegExp
+  | string
+  | true
+
+export type FormatError = ErrorObject<"format", {format: string}, string | {$data: string}>
+
+const error: KeywordErrorDefinition = {
+  message: ({schemaCode}) => str`must match format "${schemaCode}"`,
+  params: ({schemaCode}) => _`{format: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "format",
+  type: ["number", "string"],
+  schemaType: "string",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt, ruleType?: string) {
+    const {gen, data, $data, schema, schemaCode, it} = cxt
+    const {opts, errSchemaPath, schemaEnv, self} = it
+    if (!opts.validateFormats) return
+
+    if ($data) validate$DataFormat()
+    else validateFormat()
+
+    function validate$DataFormat(): void {
+      const fmts = gen.scopeValue("formats", {
+        ref: self.formats,
+        code: opts.code.formats,
+      })
+      const fDef = gen.const("fDef", _`${fmts}[${schemaCode}]`)
+      const fType = gen.let("fType")
+      const format = gen.let("format")
+      // TODO simplify
+      gen.if(
+        _`typeof ${fDef} == "object" && !(${fDef} instanceof RegExp)`,
+        () => gen.assign(fType, _`${fDef}.type || "string"`).assign(format, _`${fDef}.validate`),
+        () => gen.assign(fType, _`"string"`).assign(format, fDef)
+      )
+      cxt.fail$data(or(unknownFmt(), invalidFmt()))
+
+      function unknownFmt(): Code {
+        if (opts.strictSchema === false) return nil
+        return _`${schemaCode} && !${format}`
+      }
+
+      function invalidFmt(): Code {
+        const callFormat = schemaEnv.$async
+          ? _`(${fDef}.async ? await ${format}(${data}) : ${format}(${data}))`
+          : _`${format}(${data})`
+        const validData = _`(typeof ${format} == "function" ? ${callFormat} : ${format}.test(${data}))`
+        return _`${format} && ${format} !== true && ${fType} === ${ruleType} && !${validData}`
+      }
+    }
+
+    function validateFormat(): void {
+      const formatDef: AddedFormat | undefined = self.formats[schema]
+      if (!formatDef) {
+        unknownFormat()
+        return
+      }
+      if (formatDef === true) return
+      const [fmtType, format, fmtRef] = getFormat(formatDef)
+      if (fmtType === ruleType) cxt.pass(validCondition())
+
+      function unknownFormat(): void {
+        if (opts.strictSchema === false) {
+          self.logger.warn(unknownMsg())
+          return
+        }
+        throw new Error(unknownMsg())
+
+        function unknownMsg(): string {
+          return `unknown format "${schema as string}" ignored in schema at path "${errSchemaPath}"`
+        }
+      }
+
+      function getFormat(fmtDef: AddedFormat): [string, FormatValidate, Code] {
+        const code =
+          fmtDef instanceof RegExp
+            ? regexpCode(fmtDef)
+            : opts.code.formats
+            ? _`${opts.code.formats}${getProperty(schema)}`
+            : undefined
+        const fmt = gen.scopeValue("formats", {key: schema, ref: fmtDef, code})
+        if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
+          return [fmtDef.type || "string", fmtDef.validate, _`${fmt}.validate`]
+        }
+
+        return ["string", fmtDef, fmt]
+      }
+
+      function validCondition(): Code {
+        if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
+          if (!schemaEnv.$async) throw new Error("async format in sync schema")
+          return _`await ${fmtRef}(${data})`
+        }
+        return typeof format == "function" ? _`${fmtRef}(${data})` : _`${fmtRef}.test(${data})`
+      }
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/format/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/format/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/format/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,6 @@
+import type {Vocabulary} from "../../types"
+import formatKeyword from "./format"
+
+const format: Vocabulary = [formatKeyword]
+
+export default format
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,89 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, not, getProperty, Name} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullableObject} from "./nullable"
+import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
+import {DiscrError, DiscrErrorObj} from "../discriminator/types"
+
+export type JTDDiscriminatorError =
+  | _JTDTypeError<"discriminator", "object", string>
+  | DiscrErrorObj<DiscrError.Tag>
+  | DiscrErrorObj<DiscrError.Mapping>
+
+const error: KeywordErrorDefinition = {
+  message: (cxt) => {
+    const {schema, params} = cxt
+    return params.discrError
+      ? params.discrError === DiscrError.Tag
+        ? `tag "${schema}" must be string`
+        : `value of tag "${schema}" must be in mapping`
+      : typeErrorMessage(cxt, "object")
+  },
+  params: (cxt) => {
+    const {schema, params} = cxt
+    return params.discrError
+      ? _`{error: ${params.discrError}, tag: ${schema}, tagValue: ${params.tag}}`
+      : typeErrorParams(cxt, "object")
+  },
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "discriminator",
+  schemaType: "string",
+  implements: ["mapping"],
+  error,
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema, parentSchema} = cxt
+    const [valid, cond] = checkNullableObject(cxt, data)
+
+    gen.if(cond)
+    validateDiscriminator()
+    gen.elseIf(not(valid))
+    cxt.error()
+    gen.endIf()
+    cxt.ok(valid)
+
+    function validateDiscriminator(): void {
+      const tag = gen.const("tag", _`${data}${getProperty(schema)}`)
+      gen.if(_`${tag} === undefined`)
+      cxt.error(false, {discrError: DiscrError.Tag, tag})
+      gen.elseIf(_`typeof ${tag} == "string"`)
+      validateMapping(tag)
+      gen.else()
+      cxt.error(false, {discrError: DiscrError.Tag, tag}, {instancePath: schema})
+      gen.endIf()
+    }
+
+    function validateMapping(tag: Name): void {
+      gen.if(false)
+      for (const tagValue in parentSchema.mapping) {
+        gen.elseIf(_`${tag} === ${tagValue}`)
+        gen.assign(valid, applyTagSchema(tagValue))
+      }
+      gen.else()
+      cxt.error(
+        false,
+        {discrError: DiscrError.Mapping, tag},
+        {instancePath: schema, schemaPath: "mapping", parentSchema: true}
+      )
+      gen.endIf()
+    }
+
+    function applyTagSchema(schemaProp: string): Name {
+      const _valid = gen.name("valid")
+      cxt.subschema(
+        {
+          keyword: "mapping",
+          schemaProp,
+          jtdDiscriminator: schema,
+        },
+        _valid
+      )
+      return _valid
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/elements.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/elements.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/elements.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,32 @@
+import type {CodeKeywordDefinition, SchemaObject} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {alwaysValidSchema} from "../../compile/util"
+import {validateArray} from "../code"
+import {_, not} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullable} from "./nullable"
+import {typeError, _JTDTypeError} from "./error"
+
+export type JTDElementsError = _JTDTypeError<"elements", "array", SchemaObject>
+
+const def: CodeKeywordDefinition = {
+  keyword: "elements",
+  schemaType: "object",
+  error: typeError("array"),
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema, it} = cxt
+    if (alwaysValidSchema(it, schema)) return
+    const [valid] = checkNullable(cxt)
+    gen.if(not(valid), () =>
+      gen.if(
+        _`Array.isArray(${data})`,
+        () => gen.assign(valid, validateArray(cxt)),
+        () => cxt.error()
+      )
+    )
+    cxt.ok(valid)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/enum.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/enum.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/enum.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,45 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition, ErrorObject} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, or, and, Code} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullable} from "./nullable"
+
+export type JTDEnumError = ErrorObject<"enum", {allowedValues: string[]}, string[]>
+
+const error: KeywordErrorDefinition = {
+  message: "must be equal to one of the allowed values",
+  params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "enum",
+  schemaType: "array",
+  error,
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema, schemaValue, parentSchema, it} = cxt
+    if (schema.length === 0) throw new Error("enum must have non-empty array")
+    if (schema.length !== new Set(schema).size) throw new Error("enum items must be unique")
+    let valid: Code
+    const isString = _`typeof ${data} == "string"`
+    if (schema.length >= it.opts.loopEnum) {
+      let cond: Code
+      ;[valid, cond] = checkNullable(cxt, isString)
+      gen.if(cond, loopEnum)
+    } else {
+      /* istanbul ignore if */
+      if (!Array.isArray(schema)) throw new Error("ajv implementation error")
+      valid = and(isString, or(...schema.map((value: string) => _`${data} === ${value}`)))
+      if (parentSchema.nullable) valid = or(_`${data} === null`, valid)
+    }
+    cxt.pass(valid)
+
+    function loopEnum(): void {
+      gen.forOf("v", schemaValue as Code, (v) =>
+        gen.if(_`${valid} = ${data} === ${v}`, () => gen.break())
+      )
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/error.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/error.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/error.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,23 @@
+import type {KeywordErrorDefinition, KeywordErrorCxt, ErrorObject} from "../../types"
+import {_, Code} from "../../compile/codegen"
+
+export type _JTDTypeError<K extends string, T extends string, S> = ErrorObject<
+  K,
+  {type: T; nullable: boolean},
+  S
+>
+
+export function typeError(t: string): KeywordErrorDefinition {
+  return {
+    message: (cxt) => typeErrorMessage(cxt, t),
+    params: (cxt) => typeErrorParams(cxt, t),
+  }
+}
+
+export function typeErrorMessage({parentSchema}: KeywordErrorCxt, t: string): string {
+  return parentSchema?.nullable ? `must be ${t} or null` : `must be ${t}`
+}
+
+export function typeErrorParams({parentSchema}: KeywordErrorCxt, t: string): Code {
+  return _`{type: ${t}, nullable: ${!!parentSchema?.nullable}}`
+}
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,37 @@
+import type {Vocabulary} from "../../types"
+import refKeyword from "./ref"
+import typeKeyword, {JTDTypeError} from "./type"
+import enumKeyword, {JTDEnumError} from "./enum"
+import elements, {JTDElementsError} from "./elements"
+import properties, {JTDPropertiesError} from "./properties"
+import optionalProperties from "./optionalProperties"
+import discriminator, {JTDDiscriminatorError} from "./discriminator"
+import values, {JTDValuesError} from "./values"
+import union from "./union"
+import metadata from "./metadata"
+
+const jtdVocabulary: Vocabulary = [
+  "definitions",
+  refKeyword,
+  typeKeyword,
+  enumKeyword,
+  elements,
+  properties,
+  optionalProperties,
+  discriminator,
+  values,
+  union,
+  metadata,
+  {keyword: "additionalProperties", schemaType: "boolean"},
+  {keyword: "nullable", schemaType: "boolean"},
+]
+
+export default jtdVocabulary
+
+export type JTDErrorObject =
+  | JTDTypeError
+  | JTDEnumError
+  | JTDElementsError
+  | JTDPropertiesError
+  | JTDDiscriminatorError
+  | JTDValuesError
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/metadata.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/metadata.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/metadata.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,24 @@
+import {KeywordCxt} from "../../ajv"
+import type {CodeKeywordDefinition} from "../../types"
+import {alwaysValidSchema} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: "metadata",
+  schemaType: "object",
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, schema, it} = cxt
+    if (alwaysValidSchema(it, schema)) return
+    const valid = gen.name("valid")
+    cxt.subschema({keyword: "metadata", jtdMetadata: true}, valid)
+    cxt.ok(valid)
+  },
+}
+
+export function checkMetadata({it, keyword}: KeywordCxt, metadata?: boolean): void {
+  if (it.jtdMetadata !== metadata) {
+    throw new Error(`JTD: "${keyword}" cannot be used in this schema location`)
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/nullable.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/nullable.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/nullable.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,21 @@
+import type {KeywordCxt} from "../../compile/validate"
+import {_, not, nil, Code, Name} from "../../compile/codegen"
+
+export function checkNullable(
+  {gen, data, parentSchema}: KeywordCxt,
+  cond: Code = nil
+): [Name, Code] {
+  const valid = gen.name("valid")
+  if (parentSchema.nullable) {
+    gen.let(valid, _`${data} === null`)
+    cond = not(valid)
+  } else {
+    gen.let(valid, false)
+  }
+  return [valid, cond]
+}
+
+export function checkNullableObject(cxt: KeywordCxt, cond: Code): [Name, Code] {
+  const [valid, cond_] = checkNullable(cxt, cond)
+  return [valid, _`${cond_} && typeof ${cxt.data} == "object" && !Array.isArray(${cxt.data})`]
+}
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,15 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {validateProperties, error} from "./properties"
+
+const def: CodeKeywordDefinition = {
+  keyword: "optionalProperties",
+  schemaType: "object",
+  error,
+  code(cxt: KeywordCxt) {
+    if (cxt.parentSchema.properties) return
+    validateProperties(cxt)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/properties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/properties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/properties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,184 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  SchemaObject,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {propertyInData, allSchemaProperties, isOwnProperty} from "../code"
+import {alwaysValidSchema, schemaRefOrVal} from "../../compile/util"
+import {_, and, not, Code, Name} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullableObject} from "./nullable"
+import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
+
+enum PropError {
+  Additional = "additional",
+  Missing = "missing",
+}
+
+type PropKeyword = "properties" | "optionalProperties"
+
+type PropSchema = {[P in string]?: SchemaObject}
+
+export type JTDPropertiesError =
+  | _JTDTypeError<PropKeyword, "object", PropSchema>
+  | ErrorObject<PropKeyword, {error: PropError.Additional; additionalProperty: string}, PropSchema>
+  | ErrorObject<PropKeyword, {error: PropError.Missing; missingProperty: string}, PropSchema>
+
+export const error: KeywordErrorDefinition = {
+  message: (cxt) => {
+    const {params} = cxt
+    return params.propError
+      ? params.propError === PropError.Additional
+        ? "must NOT have additional properties"
+        : `must have property '${params.missingProperty}'`
+      : typeErrorMessage(cxt, "object")
+  },
+  params: (cxt) => {
+    const {params} = cxt
+    return params.propError
+      ? params.propError === PropError.Additional
+        ? _`{error: ${params.propError}, additionalProperty: ${params.additionalProperty}}`
+        : _`{error: ${params.propError}, missingProperty: ${params.missingProperty}}`
+      : typeErrorParams(cxt, "object")
+  },
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "properties",
+  schemaType: "object",
+  error,
+  code: validateProperties,
+}
+
+// const error: KeywordErrorDefinition = {
+//   message: "should NOT have additional properties",
+//   params: ({params}) => _`{additionalProperty: ${params.additionalProperty}}`,
+// }
+
+export function validateProperties(cxt: KeywordCxt): void {
+  checkMetadata(cxt)
+  const {gen, data, parentSchema, it} = cxt
+  const {additionalProperties, nullable} = parentSchema
+  if (it.jtdDiscriminator && nullable) throw new Error("JTD: nullable inside discriminator mapping")
+  if (commonProperties()) {
+    throw new Error("JTD: properties and optionalProperties have common members")
+  }
+  const [allProps, properties] = schemaProperties("properties")
+  const [allOptProps, optProperties] = schemaProperties("optionalProperties")
+  if (properties.length === 0 && optProperties.length === 0 && additionalProperties) {
+    return
+  }
+
+  const [valid, cond] =
+    it.jtdDiscriminator === undefined
+      ? checkNullableObject(cxt, data)
+      : [gen.let("valid", false), true]
+  gen.if(cond, () =>
+    gen.assign(valid, true).block(() => {
+      validateProps(properties, "properties", true)
+      validateProps(optProperties, "optionalProperties")
+      if (!additionalProperties) validateAdditional()
+    })
+  )
+  cxt.pass(valid)
+
+  function commonProperties(): boolean {
+    const props = parentSchema.properties as Record<string, any> | undefined
+    const optProps = parentSchema.optionalProperties as Record<string, any> | undefined
+    if (!(props && optProps)) return false
+    for (const p in props) {
+      if (Object.prototype.hasOwnProperty.call(optProps, p)) return true
+    }
+    return false
+  }
+
+  function schemaProperties(keyword: string): [string[], string[]] {
+    const schema = parentSchema[keyword]
+    const allPs = schema ? allSchemaProperties(schema) : []
+    if (it.jtdDiscriminator && allPs.some((p) => p === it.jtdDiscriminator)) {
+      throw new Error(`JTD: discriminator tag used in ${keyword}`)
+    }
+    const ps = allPs.filter((p) => !alwaysValidSchema(it, schema[p]))
+    return [allPs, ps]
+  }
+
+  function validateProps(props: string[], keyword: string, required?: boolean): void {
+    const _valid = gen.var("valid")
+    for (const prop of props) {
+      gen.if(
+        propertyInData(gen, data, prop, it.opts.ownProperties),
+        () => applyPropertySchema(prop, keyword, _valid),
+        () => missingProperty(prop)
+      )
+      cxt.ok(_valid)
+    }
+
+    function missingProperty(prop: string): void {
+      if (required) {
+        gen.assign(_valid, false)
+        cxt.error(false, {propError: PropError.Missing, missingProperty: prop}, {schemaPath: prop})
+      } else {
+        gen.assign(_valid, true)
+      }
+    }
+  }
+
+  function applyPropertySchema(prop: string, keyword: string, _valid: Name): void {
+    cxt.subschema(
+      {
+        keyword,
+        schemaProp: prop,
+        dataProp: prop,
+      },
+      _valid
+    )
+  }
+
+  function validateAdditional(): void {
+    gen.forIn("key", data, (key: Name) => {
+      const addProp = isAdditional(key, allProps, "properties", it.jtdDiscriminator)
+      const addOptProp = isAdditional(key, allOptProps, "optionalProperties")
+      const extra =
+        addProp === true ? addOptProp : addOptProp === true ? addProp : and(addProp, addOptProp)
+      gen.if(extra, () => {
+        if (it.opts.removeAdditional) {
+          gen.code(_`delete ${data}[${key}]`)
+        } else {
+          cxt.error(
+            false,
+            {propError: PropError.Additional, additionalProperty: key},
+            {instancePath: key, parentSchema: true}
+          )
+          if (!it.opts.allErrors) gen.break()
+        }
+      })
+    })
+  }
+
+  function isAdditional(
+    key: Name,
+    props: string[],
+    keyword: string,
+    jtdDiscriminator?: string
+  ): Code | true {
+    let additional: Code | boolean
+    if (props.length > 8) {
+      // TODO maybe an option instead of hard-coded 8?
+      const propsSchema = schemaRefOrVal(it, parentSchema[keyword], keyword)
+      additional = not(isOwnProperty(gen, propsSchema as Code, key))
+      if (jtdDiscriminator !== undefined) {
+        additional = and(additional, _`${key} !== ${jtdDiscriminator}`)
+      }
+    } else if (props.length || jtdDiscriminator !== undefined) {
+      const ps = jtdDiscriminator === undefined ? props : [jtdDiscriminator].concat(props)
+      additional = and(...ps.map((p) => _`${key} !== ${p}`))
+    } else {
+      additional = true
+    }
+    return additional
+  }
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/ref.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/ref.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/ref.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,76 @@
+import type {CodeKeywordDefinition, AnySchemaObject} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {compileSchema, SchemaEnv} from "../../compile"
+import {_, not, nil, stringify} from "../../compile/codegen"
+import MissingRefError from "../../compile/ref_error"
+import N from "../../compile/names"
+import {getValidate, callRef} from "../core/ref"
+import {checkMetadata} from "./metadata"
+
+const def: CodeKeywordDefinition = {
+  keyword: "ref",
+  schemaType: "string",
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema: ref, parentSchema, it} = cxt
+    const {
+      schemaEnv: {root},
+    } = it
+    const valid = gen.name("valid")
+    if (parentSchema.nullable) {
+      gen.var(valid, _`${data} === null`)
+      gen.if(not(valid), validateJtdRef)
+    } else {
+      gen.var(valid, false)
+      validateJtdRef()
+    }
+    cxt.ok(valid)
+
+    function validateJtdRef(): void {
+      const refSchema = (root.schema as AnySchemaObject).definitions?.[ref]
+      if (!refSchema) {
+        throw new MissingRefError(it.opts.uriResolver, "", ref, `No definition ${ref}`)
+      }
+      if (hasRef(refSchema) || !it.opts.inlineRefs) callValidate(refSchema)
+      else inlineRefSchema(refSchema)
+    }
+
+    function callValidate(schema: AnySchemaObject): void {
+      const sch = compileSchema.call(
+        it.self,
+        new SchemaEnv({schema, root, schemaPath: `/definitions/${ref}`})
+      )
+      const v = getValidate(cxt, sch)
+      const errsCount = gen.const("_errs", N.errors)
+      callRef(cxt, v, sch, sch.$async)
+      gen.assign(valid, _`${errsCount} === ${N.errors}`)
+    }
+
+    function inlineRefSchema(schema: AnySchemaObject): void {
+      const schName = gen.scopeValue(
+        "schema",
+        it.opts.code.source === true ? {ref: schema, code: stringify(schema)} : {ref: schema}
+      )
+      cxt.subschema(
+        {
+          schema,
+          dataTypes: [],
+          schemaPath: nil,
+          topSchemaRef: schName,
+          errSchemaPath: `/definitions/${ref}`,
+        },
+        valid
+      )
+    }
+  },
+}
+
+export function hasRef(schema: AnySchemaObject): boolean {
+  for (const key in schema) {
+    let sch: AnySchemaObject
+    if (key === "ref" || (typeof (sch = schema[key]) == "object" && hasRef(sch))) return true
+  }
+  return false
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/type.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/type.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/type.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,75 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, nil, or, Code} from "../../compile/codegen"
+import validTimestamp from "../../runtime/timestamp"
+import {useFunc} from "../../compile/util"
+import {checkMetadata} from "./metadata"
+import {typeErrorMessage, typeErrorParams, _JTDTypeError} from "./error"
+
+export type JTDTypeError = _JTDTypeError<"type", JTDType, JTDType>
+
+export type IntType = "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32"
+
+export const intRange: {[T in IntType]: [number, number, number]} = {
+  int8: [-128, 127, 3],
+  uint8: [0, 255, 3],
+  int16: [-32768, 32767, 5],
+  uint16: [0, 65535, 5],
+  int32: [-2147483648, 2147483647, 10],
+  uint32: [0, 4294967295, 10],
+}
+
+export type JTDType = "boolean" | "string" | "timestamp" | "float32" | "float64" | IntType
+
+const error: KeywordErrorDefinition = {
+  message: (cxt) => typeErrorMessage(cxt, cxt.schema),
+  params: (cxt) => typeErrorParams(cxt, cxt.schema),
+}
+
+function timestampCode(cxt: KeywordCxt): Code {
+  const {gen, data, it} = cxt
+  const {timestamp, allowDate} = it.opts
+  if (timestamp === "date") return _`${data} instanceof Date `
+  const vts = useFunc(gen, validTimestamp)
+  const allowDateArg = allowDate ? _`, true` : nil
+  const validString = _`typeof ${data} == "string" && ${vts}(${data}${allowDateArg})`
+  return timestamp === "string" ? validString : or(_`${data} instanceof Date`, validString)
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "type",
+  schemaType: "string",
+  error,
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {data, schema, parentSchema, it} = cxt
+    let cond: Code
+    switch (schema) {
+      case "boolean":
+      case "string":
+        cond = _`typeof ${data} == ${schema}`
+        break
+      case "timestamp": {
+        cond = timestampCode(cxt)
+        break
+      }
+      case "float32":
+      case "float64":
+        cond = _`typeof ${data} == "number"`
+        break
+      default: {
+        const sch = schema as IntType
+        cond = _`typeof ${data} == "number" && isFinite(${data}) && !(${data} % 1)`
+        if (!it.opts.int32range && (sch === "int32" || sch === "uint32")) {
+          if (sch === "uint32") cond = _`${cond} && ${data} >= 0`
+        } else {
+          const [min, max] = intRange[sch]
+          cond = _`${cond} && ${data} >= ${min} && ${data} <= ${max}`
+        }
+      }
+    }
+    cxt.pass(parentSchema.nullable ? or(_`${data} === null`, cond) : cond)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/union.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/union.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/union.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,12 @@
+import type {CodeKeywordDefinition} from "../../types"
+import {validateUnion} from "../code"
+
+const def: CodeKeywordDefinition = {
+  keyword: "union",
+  schemaType: "array",
+  trackErrors: true,
+  code: validateUnion,
+  error: {message: "must match a schema in union"},
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/values.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/values.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/jtd/values.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,58 @@
+import type {CodeKeywordDefinition, SchemaObject} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {alwaysValidSchema, Type} from "../../compile/util"
+import {not, or, Name} from "../../compile/codegen"
+import {checkMetadata} from "./metadata"
+import {checkNullableObject} from "./nullable"
+import {typeError, _JTDTypeError} from "./error"
+
+export type JTDValuesError = _JTDTypeError<"values", "object", SchemaObject>
+
+const def: CodeKeywordDefinition = {
+  keyword: "values",
+  schemaType: "object",
+  error: typeError("object"),
+  code(cxt: KeywordCxt) {
+    checkMetadata(cxt)
+    const {gen, data, schema, it} = cxt
+    const [valid, cond] = checkNullableObject(cxt, data)
+    if (alwaysValidSchema(it, schema)) {
+      gen.if(not(or(cond, valid)), () => cxt.error())
+    } else {
+      gen.if(cond)
+      gen.assign(valid, validateMap())
+      gen.elseIf(not(valid))
+      cxt.error()
+      gen.endIf()
+    }
+    cxt.ok(valid)
+
+    function validateMap(): Name | boolean {
+      const _valid = gen.name("valid")
+      if (it.allErrors) {
+        const validMap = gen.let("valid", true)
+        validateValues(() => gen.assign(validMap, false))
+        return validMap
+      }
+      gen.var(_valid, true)
+      validateValues(() => gen.break())
+      return _valid
+
+      function validateValues(notValid: () => void): void {
+        gen.forIn("key", data, (key) => {
+          cxt.subschema(
+            {
+              keyword: "values",
+              dataProp: key,
+              dataPropType: Type.Str,
+            },
+            _valid
+          )
+          gen.if(not(_valid), notValid)
+        })
+      }
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/metadata.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/metadata.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/metadata.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,17 @@
+import type {Vocabulary} from "../types"
+
+export const metadataVocabulary: Vocabulary = [
+  "title",
+  "description",
+  "default",
+  "deprecated",
+  "readOnly",
+  "writeOnly",
+  "examples",
+]
+
+export const contentVocabulary: Vocabulary = [
+  "contentMediaType",
+  "contentEncoding",
+  "contentSchema",
+]
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/next.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/next.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/next.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,8 @@
+import type {Vocabulary} from "../types"
+import dependentRequired from "./validation/dependentRequired"
+import dependentSchemas from "./applicator/dependentSchemas"
+import limitContains from "./validation/limitContains"
+
+const next: Vocabulary = [dependentRequired, dependentSchemas, limitContains]
+
+export default next
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,7 @@
+import type {Vocabulary} from "../../types"
+import unevaluatedProperties from "./unevaluatedProperties"
+import unevaluatedItems from "./unevaluatedItems"
+
+const unevaluated: Vocabulary = [unevaluatedProperties, unevaluatedItems]
+
+export default unevaluated
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,47 @@
+import type {
+  CodeKeywordDefinition,
+  ErrorObject,
+  KeywordErrorDefinition,
+  AnySchema,
+} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, not, Name} from "../../compile/codegen"
+import {alwaysValidSchema, Type} from "../../compile/util"
+
+export type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: number}, AnySchema>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {len}}) => str`must NOT have more than ${len} items`,
+  params: ({params: {len}}) => _`{limit: ${len}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "unevaluatedItems",
+  type: "array",
+  schemaType: ["boolean", "object"],
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, data, it} = cxt
+    const items = it.items || 0
+    if (items === true) return
+    const len = gen.const("len", _`${data}.length`)
+    if (schema === false) {
+      cxt.setParams({len: items})
+      cxt.fail(_`${len} > ${items}`)
+    } else if (typeof schema == "object" && !alwaysValidSchema(it, schema)) {
+      const valid = gen.var("valid", _`${len} <= ${items}`)
+      gen.if(not(valid), () => validateItems(valid, items))
+      cxt.ok(valid)
+    }
+    it.items = true
+
+    function validateItems(valid: Name, from: Name | number): void {
+      gen.forRange("i", from, len, (i) => {
+        cxt.subschema({keyword: "unevaluatedItems", dataProp: i, dataPropType: Type.Num}, valid)
+        if (!it.allErrors) gen.if(not(valid), () => gen.break())
+      })
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,85 @@
+import type {
+  CodeKeywordDefinition,
+  KeywordErrorDefinition,
+  ErrorObject,
+  AnySchema,
+} from "../../types"
+import {_, not, and, Name, Code} from "../../compile/codegen"
+import {alwaysValidSchema, Type} from "../../compile/util"
+import N from "../../compile/names"
+
+export type UnevaluatedPropertiesError = ErrorObject<
+  "unevaluatedProperties",
+  {unevaluatedProperty: string},
+  AnySchema
+>
+
+const error: KeywordErrorDefinition = {
+  message: "must NOT have unevaluated properties",
+  params: ({params}) => _`{unevaluatedProperty: ${params.unevaluatedProperty}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "unevaluatedProperties",
+  type: "object",
+  schemaType: ["boolean", "object"],
+  trackErrors: true,
+  error,
+  code(cxt) {
+    const {gen, schema, data, errsCount, it} = cxt
+    /* istanbul ignore if */
+    if (!errsCount) throw new Error("ajv implementation error")
+    const {allErrors, props} = it
+    if (props instanceof Name) {
+      gen.if(_`${props} !== true`, () =>
+        gen.forIn("key", data, (key: Name) =>
+          gen.if(unevaluatedDynamic(props, key), () => unevaluatedPropCode(key))
+        )
+      )
+    } else if (props !== true) {
+      gen.forIn("key", data, (key: Name) =>
+        props === undefined
+          ? unevaluatedPropCode(key)
+          : gen.if(unevaluatedStatic(props, key), () => unevaluatedPropCode(key))
+      )
+    }
+    it.props = true
+    cxt.ok(_`${errsCount} === ${N.errors}`)
+
+    function unevaluatedPropCode(key: Name): void {
+      if (schema === false) {
+        cxt.setParams({unevaluatedProperty: key})
+        cxt.error()
+        if (!allErrors) gen.break()
+        return
+      }
+
+      if (!alwaysValidSchema(it, schema)) {
+        const valid = gen.name("valid")
+        cxt.subschema(
+          {
+            keyword: "unevaluatedProperties",
+            dataProp: key,
+            dataPropType: Type.Str,
+          },
+          valid
+        )
+        if (!allErrors) gen.if(not(valid), () => gen.break())
+      }
+    }
+
+    function unevaluatedDynamic(evaluatedProps: Name, key: Name): Code {
+      return _`!${evaluatedProps} || !${evaluatedProps}[${key}]`
+    }
+
+    function unevaluatedStatic(evaluatedProps: {[K in string]?: true}, key: Name): Code {
+      const ps: Code[] = []
+      for (const p in evaluatedProps) {
+        if (evaluatedProps[p] === true) ps.push(_`${key} !== ${p}`)
+      }
+      return and(...ps)
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/const.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/const.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/const.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,28 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_} from "../../compile/codegen"
+import {useFunc} from "../../compile/util"
+import equal from "../../runtime/equal"
+
+export type ConstError = ErrorObject<"const", {allowedValue: any}>
+
+const error: KeywordErrorDefinition = {
+  message: "must be equal to constant",
+  params: ({schemaCode}) => _`{allowedValue: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "const",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, data, $data, schemaCode, schema} = cxt
+    if ($data || (schema && typeof schema == "object")) {
+      cxt.fail$data(_`!${useFunc(gen, equal)}(${data}, ${schemaCode})`)
+    } else {
+      cxt.fail(_`${schema} !== ${data}`)
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,23 @@
+import type {CodeKeywordDefinition, ErrorObject} from "../../types"
+import {
+  validatePropertyDeps,
+  error,
+  DependenciesErrorParams,
+  PropertyDependencies,
+} from "../applicator/dependencies"
+
+export type DependentRequiredError = ErrorObject<
+  "dependentRequired",
+  DependenciesErrorParams,
+  PropertyDependencies
+>
+
+const def: CodeKeywordDefinition = {
+  keyword: "dependentRequired",
+  type: "object",
+  schemaType: "object",
+  error,
+  code: (cxt) => validatePropertyDeps(cxt),
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/enum.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/enum.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/enum.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,54 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, or, Name, Code} from "../../compile/codegen"
+import {useFunc} from "../../compile/util"
+import equal from "../../runtime/equal"
+
+export type EnumError = ErrorObject<"enum", {allowedValues: any[]}, any[] | {$data: string}>
+
+const error: KeywordErrorDefinition = {
+  message: "must be equal to one of the allowed values",
+  params: ({schemaCode}) => _`{allowedValues: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "enum",
+  schemaType: "array",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, data, $data, schema, schemaCode, it} = cxt
+    if (!$data && schema.length === 0) throw new Error("enum must have non-empty array")
+    const useLoop = schema.length >= it.opts.loopEnum
+    let eql: Name | undefined
+    const getEql = (): Name => (eql ??= useFunc(gen, equal))
+
+    let valid: Code
+    if (useLoop || $data) {
+      valid = gen.let("valid")
+      cxt.block$data(valid, loopEnum)
+    } else {
+      /* istanbul ignore if */
+      if (!Array.isArray(schema)) throw new Error("ajv implementation error")
+      const vSchema = gen.const("vSchema", schemaCode)
+      valid = or(...schema.map((_x: unknown, i: number) => equalCode(vSchema, i)))
+    }
+    cxt.pass(valid)
+
+    function loopEnum(): void {
+      gen.assign(valid, false)
+      gen.forOf("v", schemaCode as Code, (v) =>
+        gen.if(_`${getEql()}(${data}, ${v})`, () => gen.assign(valid, true).break())
+      )
+    }
+
+    function equalCode(vSchema: Name, i: number): Code {
+      const sch = schema[i]
+      return typeof sch === "object" && sch !== null
+        ? _`${getEql()}(${data}, ${vSchema}[${i}])`
+        : _`${data} === ${sch}`
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/index.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/index.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,49 @@
+import type {ErrorObject, Vocabulary} from "../../types"
+import limitNumber, {LimitNumberError} from "./limitNumber"
+import multipleOf, {MultipleOfError} from "./multipleOf"
+import limitLength from "./limitLength"
+import pattern, {PatternError} from "./pattern"
+import limitProperties from "./limitProperties"
+import required, {RequiredError} from "./required"
+import limitItems from "./limitItems"
+import uniqueItems, {UniqueItemsError} from "./uniqueItems"
+import constKeyword, {ConstError} from "./const"
+import enumKeyword, {EnumError} from "./enum"
+
+const validation: Vocabulary = [
+  // number
+  limitNumber,
+  multipleOf,
+  // string
+  limitLength,
+  pattern,
+  // object
+  limitProperties,
+  required,
+  // array
+  limitItems,
+  uniqueItems,
+  // any
+  {keyword: "type", schemaType: ["string", "array"]},
+  {keyword: "nullable", schemaType: "boolean"},
+  constKeyword,
+  enumKeyword,
+]
+
+export default validation
+
+type LimitError = ErrorObject<
+  "maxItems" | "minItems" | "minProperties" | "maxProperties" | "minLength" | "maxLength",
+  {limit: number},
+  number | {$data: string}
+>
+
+export type ValidationKeywordError =
+  | LimitError
+  | LimitNumberError
+  | MultipleOfError
+  | PatternError
+  | RequiredError
+  | UniqueItemsError
+  | ConstError
+  | EnumError
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitContains.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitContains.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitContains.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,16 @@
+import type {CodeKeywordDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {checkStrictMode} from "../../compile/util"
+
+const def: CodeKeywordDefinition = {
+  keyword: ["maxContains", "minContains"],
+  type: "array",
+  schemaType: "number",
+  code({keyword, parentSchema, it}: KeywordCxt) {
+    if (parentSchema.contains === undefined) {
+      checkStrictMode(it, `"${keyword}" without "contains" is ignored`)
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitItems.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,26 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, operators} from "../../compile/codegen"
+
+const error: KeywordErrorDefinition = {
+  message({keyword, schemaCode}) {
+    const comp = keyword === "maxItems" ? "more" : "fewer"
+    return str`must NOT have ${comp} than ${schemaCode} items`
+  },
+  params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: ["maxItems", "minItems"],
+  type: "array",
+  schemaType: "number",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {keyword, data, schemaCode} = cxt
+    const op = keyword === "maxItems" ? operators.GT : operators.LT
+    cxt.fail$data(_`${data}.length ${op} ${schemaCode}`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitLength.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitLength.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitLength.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,30 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, operators} from "../../compile/codegen"
+import {useFunc} from "../../compile/util"
+import ucs2length from "../../runtime/ucs2length"
+
+const error: KeywordErrorDefinition = {
+  message({keyword, schemaCode}) {
+    const comp = keyword === "maxLength" ? "more" : "fewer"
+    return str`must NOT have ${comp} than ${schemaCode} characters`
+  },
+  params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: ["maxLength", "minLength"],
+  type: "string",
+  schemaType: "number",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {keyword, data, schemaCode, it} = cxt
+    const op = keyword === "maxLength" ? operators.GT : operators.LT
+    const len =
+      it.opts.unicode === false ? _`${data}.length` : _`${useFunc(cxt.gen, ucs2length)}(${data})`
+    cxt.fail$data(_`${len} ${op} ${schemaCode}`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,42 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, operators, Code} from "../../compile/codegen"
+
+const ops = operators
+
+type Kwd = "maximum" | "minimum" | "exclusiveMaximum" | "exclusiveMinimum"
+
+type Comparison = "<=" | ">=" | "<" | ">"
+
+const KWDs: {[K in Kwd]: {okStr: Comparison; ok: Code; fail: Code}} = {
+  maximum: {okStr: "<=", ok: ops.LTE, fail: ops.GT},
+  minimum: {okStr: ">=", ok: ops.GTE, fail: ops.LT},
+  exclusiveMaximum: {okStr: "<", ok: ops.LT, fail: ops.GTE},
+  exclusiveMinimum: {okStr: ">", ok: ops.GT, fail: ops.LTE},
+}
+
+export type LimitNumberError = ErrorObject<
+  Kwd,
+  {limit: number; comparison: Comparison},
+  number | {$data: string}
+>
+
+const error: KeywordErrorDefinition = {
+  message: ({keyword, schemaCode}) => str`must be ${KWDs[keyword as Kwd].okStr} ${schemaCode}`,
+  params: ({keyword, schemaCode}) =>
+    _`{comparison: ${KWDs[keyword as Kwd].okStr}, limit: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: Object.keys(KWDs),
+  type: "number",
+  schemaType: "number",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {keyword, data, schemaCode} = cxt
+    cxt.fail$data(_`${data} ${KWDs[keyword as Kwd].fail} ${schemaCode} || isNaN(${data})`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,26 @@
+import type {CodeKeywordDefinition, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str, operators} from "../../compile/codegen"
+
+const error: KeywordErrorDefinition = {
+  message({keyword, schemaCode}) {
+    const comp = keyword === "maxProperties" ? "more" : "fewer"
+    return str`must NOT have ${comp} than ${schemaCode} properties`
+  },
+  params: ({schemaCode}) => _`{limit: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: ["maxProperties", "minProperties"],
+  type: "object",
+  schemaType: "number",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {keyword, data, schemaCode} = cxt
+    const op = keyword === "maxProperties" ? operators.GT : operators.LT
+    cxt.fail$data(_`Object.keys(${data}).length ${op} ${schemaCode}`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,34 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {_, str} from "../../compile/codegen"
+
+export type MultipleOfError = ErrorObject<
+  "multipleOf",
+  {multipleOf: number},
+  number | {$data: string}
+>
+
+const error: KeywordErrorDefinition = {
+  message: ({schemaCode}) => str`must be multiple of ${schemaCode}`,
+  params: ({schemaCode}) => _`{multipleOf: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "multipleOf",
+  type: "number",
+  schemaType: "number",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, data, schemaCode, it} = cxt
+    // const bdt = bad$DataType(schemaCode, <string>def.schemaType, $data)
+    const prec = it.opts.multipleOfPrecision
+    const res = gen.let("res")
+    const invalid = prec
+      ? _`Math.abs(Math.round(${res}) - ${res}) > 1e-${prec}`
+      : _`${res} !== parseInt(${res})`
+    cxt.fail$data(_`(${schemaCode} === 0 || (${res} = ${data}/${schemaCode}, ${invalid}))`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/pattern.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/pattern.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/pattern.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,28 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {usePattern} from "../code"
+import {_, str} from "../../compile/codegen"
+
+export type PatternError = ErrorObject<"pattern", {pattern: string}, string | {$data: string}>
+
+const error: KeywordErrorDefinition = {
+  message: ({schemaCode}) => str`must match pattern "${schemaCode}"`,
+  params: ({schemaCode}) => _`{pattern: ${schemaCode}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "pattern",
+  type: "string",
+  schemaType: "string",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {data, $data, schema, schemaCode, it} = cxt
+    // TODO regexp should be wrapped in try/catchs
+    const u = it.opts.unicodeRegExp ? "u" : ""
+    const regExp = $data ? _`(new RegExp(${schemaCode}, ${u}))` : usePattern(cxt, schema)
+    cxt.fail$data(_`!${regExp}.test(${data})`)
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/required.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/required.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/required.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,98 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {
+  checkReportMissingProp,
+  checkMissingProp,
+  reportMissingProp,
+  propertyInData,
+  noPropertyInData,
+} from "../code"
+import {_, str, nil, not, Name, Code} from "../../compile/codegen"
+import {checkStrictMode} from "../../compile/util"
+
+export type RequiredError = ErrorObject<
+  "required",
+  {missingProperty: string},
+  string[] | {$data: string}
+>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {missingProperty}}) => str`must have required property '${missingProperty}'`,
+  params: ({params: {missingProperty}}) => _`{missingProperty: ${missingProperty}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "required",
+  type: "object",
+  schemaType: "array",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, schema, schemaCode, data, $data, it} = cxt
+    const {opts} = it
+    if (!$data && schema.length === 0) return
+    const useLoop = schema.length >= opts.loopRequired
+    if (it.allErrors) allErrorsMode()
+    else exitOnErrorMode()
+
+    if (opts.strictRequired) {
+      const props = cxt.parentSchema.properties
+      const {definedProperties} = cxt.it
+      for (const requiredKey of schema) {
+        if (props?.[requiredKey] === undefined && !definedProperties.has(requiredKey)) {
+          const schemaPath = it.schemaEnv.baseId + it.errSchemaPath
+          const msg = `required property "${requiredKey}" is not defined at "${schemaPath}" (strictRequired)`
+          checkStrictMode(it, msg, it.opts.strictRequired)
+        }
+      }
+    }
+
+    function allErrorsMode(): void {
+      if (useLoop || $data) {
+        cxt.block$data(nil, loopAllRequired)
+      } else {
+        for (const prop of schema) {
+          checkReportMissingProp(cxt, prop)
+        }
+      }
+    }
+
+    function exitOnErrorMode(): void {
+      const missing = gen.let("missing")
+      if (useLoop || $data) {
+        const valid = gen.let("valid", true)
+        cxt.block$data(valid, () => loopUntilMissing(missing, valid))
+        cxt.ok(valid)
+      } else {
+        gen.if(checkMissingProp(cxt, schema, missing))
+        reportMissingProp(cxt, missing)
+        gen.else()
+      }
+    }
+
+    function loopAllRequired(): void {
+      gen.forOf("prop", schemaCode as Code, (prop) => {
+        cxt.setParams({missingProperty: prop})
+        gen.if(noPropertyInData(gen, data, prop, opts.ownProperties), () => cxt.error())
+      })
+    }
+
+    function loopUntilMissing(missing: Name, valid: Name): void {
+      cxt.setParams({missingProperty: missing})
+      gen.forOf(
+        missing,
+        schemaCode as Code,
+        () => {
+          gen.assign(valid, propertyInData(gen, data, missing, opts.ownProperties))
+          gen.if(not(valid), () => {
+            cxt.error()
+            gen.break()
+          })
+        },
+        nil
+      )
+    }
+  },
+}
+
+export default def
Index: imaps-frontend/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts
===================================================================
--- imaps-frontend/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
+++ imaps-frontend/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts	(revision 79a03170cdde4e801d12257ee86723774970427b)
@@ -0,0 +1,79 @@
+import type {CodeKeywordDefinition, ErrorObject, KeywordErrorDefinition} from "../../types"
+import type {KeywordCxt} from "../../compile/validate"
+import {checkDataTypes, getSchemaTypes, DataType} from "../../compile/validate/dataType"
+import {_, str, Name} from "../../compile/codegen"
+import {useFunc} from "../../compile/util"
+import equal from "../../runtime/equal"
+
+export type UniqueItemsError = ErrorObject<
+  "uniqueItems",
+  {i: number; j: number},
+  boolean | {$data: string}
+>
+
+const error: KeywordErrorDefinition = {
+  message: ({params: {i, j}}) =>
+    str`must NOT have duplicate items (items ## ${j} and ${i} are identical)`,
+  params: ({params: {i, j}}) => _`{i: ${i}, j: ${j}}`,
+}
+
+const def: CodeKeywordDefinition = {
+  keyword: "uniqueItems",
+  type: "array",
+  schemaType: "boolean",
+  $data: true,
+  error,
+  code(cxt: KeywordCxt) {
+    const {gen, data, $data, schema, parentSchema, schemaCode, it} = cxt
+    if (!$data && !schema) return
+    const valid = gen.let("valid")
+    const itemTypes = parentSchema.items ? getSchemaTypes(parentSchema.items) : []
+    cxt.block$data(valid, validateUniqueItems, _`${schemaCode} === false`)
+    cxt.ok(valid)
+
+    function validateUniqueItems(): void {
+      const i = gen.let("i", _`${data}.length`)
+      const j = gen.let("j")
+      cxt.setParams({i, j})
+      gen.assign(valid, true)
+      gen.if(_`${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j))
+    }
+
+    function canOptimize(): boolean {
+      return itemTypes.length > 0 && !itemTypes.some((t) => t === "object" || t === "array")
+    }
+
+    function loopN(i: Name, j: Name): void {
+      const item = gen.name("item")
+      const wrongType = checkDataTypes(itemTypes, item, it.opts.strictNumbers, DataType.Wrong)
+      const indices = gen.const("indices", _`{}`)
+      gen.for(_`;${i}--;`, () => {
+        gen.let(item, _`${data}[${i}]`)
+        gen.if(wrongType, _`continue`)
+        if (itemTypes.length > 1) gen.if(_`typeof ${item} == "string"`, _`${item} += "_"`)
+        gen
+          .if(_`typeof ${indices}[${item}] == "number"`, () => {
+            gen.assign(j, _`${indices}[${item}]`)
+            cxt.error()
+            gen.assign(valid, false).break()
+          })
+          .code(_`${indices}[${item}] = ${i}`)
+      })
+    }
+
+    function loopN2(i: Name, j: Name): void {
+      const eql = useFunc(gen, equal)
+      const outer = gen.name("outer")
+      gen.label(outer).for(_`;${i}--;`, () =>
+        gen.for(_`${j} = ${i}; ${j}--;`, () =>
+          gen.if(_`${eql}(${data}[${i}], ${data}[${j}])`, () => {
+            cxt.error()
+            gen.assign(valid, false).break(outer)
+          })
+        )
+      )
+    }
+  },
+}
+
+export default def
