Full Code of ajv-validator/ajv for AI

master 142ce84b807c cached
433 files
1.8 MB
574.5k tokens
1013 symbols
1 requests
Download .txt
Showing preview only (1,939K chars total). Download the full file or copy to clipboard to get everything.
Repository: ajv-validator/ajv
Branch: master
Commit: 142ce84b807c
Files: 433
Total size: 1.8 MB

Directory structure:
gitextract_hfo2xbb4/

├── .eslintrc.js
├── .github/
│   ├── CODEOWNERS
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-or-error-report.md
│   │   ├── change.md
│   │   ├── compatibility.md
│   │   ├── installation.md
│   │   └── typescript.md
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── config.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── build.yml
│       └── publish.yml
├── .gitignore
├── .gitmodules
├── .npmrc
├── .prettierignore
├── .runkit_example.js
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── benchmark/
│   ├── jtd.js
│   └── package.json
├── bower.json
├── docs/
│   ├── .vuepress/
│   │   ├── components/
│   │   │   ├── Button.vue
│   │   │   ├── Column.vue
│   │   │   ├── Columns.vue
│   │   │   ├── Contributors.vue
│   │   │   ├── Feature.vue
│   │   │   ├── Features.vue
│   │   │   ├── FooterColumn.vue
│   │   │   ├── FooterColumns.vue
│   │   │   ├── GitHub.vue
│   │   │   ├── HeroSection.vue
│   │   │   ├── HomePage.vue
│   │   │   ├── HomeSection.vue
│   │   │   ├── NewsHome.vue
│   │   │   ├── NewsIndex.vue
│   │   │   ├── NewsPost.vue
│   │   │   ├── NewsPostMeta.vue
│   │   │   ├── Projects.vue
│   │   │   ├── Sponsors.vue
│   │   │   ├── Subscribe.vue
│   │   │   ├── Testimonial.vue
│   │   │   └── Testimonials.vue
│   │   ├── config.js
│   │   ├── styles/
│   │   │   ├── index.styl
│   │   │   └── palette.styl
│   │   └── theme/
│   │       ├── LICENSE
│   │       ├── components/
│   │       │   ├── AlgoliaSearchBox.vue
│   │       │   ├── DropdownLink.vue
│   │       │   ├── DropdownTransition.vue
│   │       │   ├── Home.vue
│   │       │   ├── NavLink.vue
│   │       │   ├── NavLinks.vue
│   │       │   ├── Navbar.vue
│   │       │   ├── Page.vue
│   │       │   ├── PageEdit.vue
│   │       │   ├── PageNav.vue
│   │       │   ├── Sidebar.vue
│   │       │   ├── SidebarButton.vue
│   │       │   ├── SidebarGroup.vue
│   │       │   ├── SidebarLink.vue
│   │       │   └── SidebarLinks.vue
│   │       ├── global-components/
│   │       │   ├── Badge.vue
│   │       │   ├── CodeBlock.vue
│   │       │   └── CodeGroup.vue
│   │       ├── index.js
│   │       ├── layouts/
│   │       │   ├── 404.vue
│   │       │   └── Layout.vue
│   │       ├── noopModule.js
│   │       ├── styles/
│   │       │   ├── arrow.styl
│   │       │   ├── code.styl
│   │       │   ├── config.styl
│   │       │   ├── custom-blocks.styl
│   │       │   ├── index.styl
│   │       │   ├── mobile.styl
│   │       │   ├── toc.styl
│   │       │   └── wrapper.styl
│   │       └── util/
│   │           └── index.js
│   ├── README.md
│   ├── api.md
│   ├── codegen.md
│   ├── coercion.md
│   ├── components.md
│   ├── faq.md
│   ├── guide/
│   │   ├── async-validation.md
│   │   ├── combining-schemas.md
│   │   ├── environments.md
│   │   ├── formats.md
│   │   ├── getting-started.md
│   │   ├── managing-schemas.md
│   │   ├── modifying-data.md
│   │   ├── schema-language.md
│   │   ├── typescript.md
│   │   ├── user-keywords.md
│   │   └── why-ajv.md
│   ├── json-schema.md
│   ├── json-type-definition.md
│   ├── keywords.md
│   ├── news/
│   │   ├── 2020-08-14-mozilla-grant-openjs-foundation.md
│   │   ├── 2020-12-15-ajv-version-7-released.md
│   │   ├── 2021-03-07-ajv-supports-json-type-definition.md
│   │   ├── 2021-03-27-ajv-version-8-released.md
│   │   ├── 2021-04-24-ajv-online-event.md
│   │   ├── 2021-05-24-ajv-online-event-video.md
│   │   ├── 2021-07-22-ajv-microsoft-foss-fund-award.md
│   │   └── README.md
│   ├── options.md
│   ├── packages/
│   │   └── README.md
│   ├── security.md
│   ├── standalone.md
│   ├── strict-mode.md
│   ├── testimonials.md
│   └── v6-to-v8-migration.md
├── karma.conf.js
├── lib/
│   ├── 2019.ts
│   ├── 2020.ts
│   ├── ajv.ts
│   ├── compile/
│   │   ├── codegen/
│   │   │   ├── code.ts
│   │   │   ├── index.ts
│   │   │   └── scope.ts
│   │   ├── errors.ts
│   │   ├── index.ts
│   │   ├── jtd/
│   │   │   ├── parse.ts
│   │   │   ├── serialize.ts
│   │   │   └── types.ts
│   │   ├── names.ts
│   │   ├── ref_error.ts
│   │   ├── resolve.ts
│   │   ├── rules.ts
│   │   ├── util.ts
│   │   └── validate/
│   │       ├── applicability.ts
│   │       ├── boolSchema.ts
│   │       ├── dataType.ts
│   │       ├── defaults.ts
│   │       ├── index.ts
│   │       ├── keyword.ts
│   │       └── subschema.ts
│   ├── core.ts
│   ├── jtd.ts
│   ├── refs/
│   │   ├── data.json
│   │   ├── json-schema-2019-09/
│   │   │   ├── index.ts
│   │   │   ├── meta/
│   │   │   │   ├── applicator.json
│   │   │   │   ├── content.json
│   │   │   │   ├── core.json
│   │   │   │   ├── format.json
│   │   │   │   ├── meta-data.json
│   │   │   │   └── validation.json
│   │   │   └── schema.json
│   │   ├── json-schema-2020-12/
│   │   │   ├── index.ts
│   │   │   ├── meta/
│   │   │   │   ├── applicator.json
│   │   │   │   ├── content.json
│   │   │   │   ├── core.json
│   │   │   │   ├── format-annotation.json
│   │   │   │   ├── meta-data.json
│   │   │   │   ├── unevaluated.json
│   │   │   │   └── validation.json
│   │   │   └── schema.json
│   │   ├── json-schema-draft-06.json
│   │   ├── json-schema-draft-07.json
│   │   ├── json-schema-secure.json
│   │   └── jtd-schema.ts
│   ├── runtime/
│   │   ├── equal.ts
│   │   ├── parseJson.ts
│   │   ├── quote.ts
│   │   ├── re2.ts
│   │   ├── timestamp.ts
│   │   ├── ucs2length.ts
│   │   ├── uri.ts
│   │   └── validation_error.ts
│   ├── standalone/
│   │   ├── index.ts
│   │   └── instance.ts
│   ├── types/
│   │   ├── index.ts
│   │   ├── json-schema.ts
│   │   └── jtd-schema.ts
│   └── vocabularies/
│       ├── applicator/
│       │   ├── additionalItems.ts
│       │   ├── additionalProperties.ts
│       │   ├── allOf.ts
│       │   ├── anyOf.ts
│       │   ├── contains.ts
│       │   ├── dependencies.ts
│       │   ├── dependentSchemas.ts
│       │   ├── if.ts
│       │   ├── index.ts
│       │   ├── items.ts
│       │   ├── items2020.ts
│       │   ├── not.ts
│       │   ├── oneOf.ts
│       │   ├── patternProperties.ts
│       │   ├── prefixItems.ts
│       │   ├── properties.ts
│       │   ├── propertyNames.ts
│       │   └── thenElse.ts
│       ├── code.ts
│       ├── core/
│       │   ├── id.ts
│       │   ├── index.ts
│       │   └── ref.ts
│       ├── discriminator/
│       │   ├── index.ts
│       │   └── types.ts
│       ├── draft2020.ts
│       ├── draft7.ts
│       ├── dynamic/
│       │   ├── dynamicAnchor.ts
│       │   ├── dynamicRef.ts
│       │   ├── index.ts
│       │   ├── recursiveAnchor.ts
│       │   └── recursiveRef.ts
│       ├── errors.ts
│       ├── format/
│       │   ├── format.ts
│       │   └── index.ts
│       ├── jtd/
│       │   ├── discriminator.ts
│       │   ├── elements.ts
│       │   ├── enum.ts
│       │   ├── error.ts
│       │   ├── index.ts
│       │   ├── metadata.ts
│       │   ├── nullable.ts
│       │   ├── optionalProperties.ts
│       │   ├── properties.ts
│       │   ├── ref.ts
│       │   ├── type.ts
│       │   ├── union.ts
│       │   └── values.ts
│       ├── metadata.ts
│       ├── next.ts
│       ├── unevaluated/
│       │   ├── index.ts
│       │   ├── unevaluatedItems.ts
│       │   └── unevaluatedProperties.ts
│       └── validation/
│           ├── const.ts
│           ├── dependentRequired.ts
│           ├── enum.ts
│           ├── index.ts
│           ├── limitContains.ts
│           ├── limitItems.ts
│           ├── limitLength.ts
│           ├── limitNumber.ts
│           ├── limitProperties.ts
│           ├── multipleOf.ts
│           ├── pattern.ts
│           ├── required.ts
│           └── uniqueItems.ts
├── package.json
├── rollup.config.js
├── scripts/
│   ├── .eslintrc.yml
│   ├── bundle.js
│   ├── get-ajv-packages
│   ├── get-contributors.js
│   ├── jsontests.js
│   ├── prepare-site
│   ├── prepare-tests
│   ├── publish-bundles
│   └── publish-site
├── spec/
│   ├── .eslintrc.yml
│   ├── _json/
│   │   └── README.md
│   ├── after_test.ts
│   ├── ajv.spec.ts
│   ├── ajv.ts
│   ├── ajv2019.ts
│   ├── ajv2020.ts
│   ├── ajv_all_instances.ts
│   ├── ajv_async_instances.ts
│   ├── ajv_instances.ts
│   ├── ajv_jtd.ts
│   ├── ajv_options.ts
│   ├── ajv_standalone.ts
│   ├── async/
│   │   ├── boolean.json
│   │   ├── compound.json
│   │   ├── format.json
│   │   ├── items.json
│   │   ├── keyword.json
│   │   ├── no_async.json
│   │   └── properties.json
│   ├── async.spec.ts
│   ├── async_schemas.spec.ts
│   ├── async_validate.spec.ts
│   ├── boolean.spec.ts
│   ├── chai.ts
│   ├── chai_type.ts
│   ├── codegen.spec.ts
│   ├── coercion.spec.ts
│   ├── discriminator.spec.ts
│   ├── dynamic-ref.spec.ts
│   ├── errors.spec.ts
│   ├── extras/
│   │   ├── $data/
│   │   │   ├── absolute_ref.json
│   │   │   ├── const.json
│   │   │   ├── enum.json
│   │   │   ├── exclusiveMaximum.json
│   │   │   ├── exclusiveMinimum.json
│   │   │   ├── format.json
│   │   │   ├── maxItems.json
│   │   │   ├── maxLength.json
│   │   │   ├── maxProperties.json
│   │   │   ├── maximum.json
│   │   │   ├── minItems.json
│   │   │   ├── minLength.json
│   │   │   ├── minProperties.json
│   │   │   ├── minimum.json
│   │   │   ├── multipleOf.json
│   │   │   ├── pattern.json
│   │   │   ├── required.json
│   │   │   └── uniqueItems.json
│   │   ├── const.json
│   │   ├── contains.json
│   │   ├── exclusiveMaximum.json
│   │   └── exclusiveMinimum.json
│   ├── extras.spec.ts
│   ├── issues/
│   │   ├── 1001_addKeyword_and_schema_without_id.spec.ts
│   │   ├── 1344_non_root_recursive_ref_standalone.spec.ts
│   │   ├── 1414_base_uri_change.spec.ts
│   │   ├── 1501_jtd_many_properties.spec.ts
│   │   ├── 1515_evaluated_properties_nested_anyof.spec.ts
│   │   ├── 1539_add_keyword_name_to_validation_error.spec.ts
│   │   ├── 1625_evaluated_truthy_pattern_properties.spec.ts
│   │   ├── 1683_re2_engine.spec.ts
│   │   ├── 1819_mincontains.spec.ts
│   │   ├── 181_allErrors_custom_keyword_skipped.spec.ts
│   │   ├── 182_nan_validation.spec.ts
│   │   ├── 1935_integer_narrowing_subschema.spec.ts
│   │   ├── 1949_jtd_empty_values.spec.ts
│   │   ├── 1971_jtd_discriminator.spec.ts
│   │   ├── 2001_jtd_only_optional_properties.spec.ts
│   │   ├── 204_options_schemas_data_together.spec.ts
│   │   ├── 210_mutual_recur_frags.spec.ts
│   │   ├── 240_mutual_recur_frags_common_ref.spec.ts
│   │   ├── 259_validate_meta_against_itself.spec.ts
│   │   ├── 273_error_schemaPath_refd_schema.spec.ts
│   │   ├── 342_uniqueItems_non-json_objects.spec.ts
│   │   ├── 485_type_validation_priority.spec.ts
│   │   ├── 50_refs_with_definitions.spec.ts
│   │   ├── 521_wrong_warning_id_property.spec.ts
│   │   ├── 743_removeAdditional_to_remove_proto.spec.ts
│   │   ├── 768_passContext_recursive_ref.spec.ts
│   │   ├── 815_id_updates_ref_base.spec.ts
│   │   ├── 8_shared_refs.spec.ts
│   │   ├── 955_removeAdditional_custom_keywords.spec.ts
│   │   ├── cve_2025_69873_redos_attack.spec.ts
│   │   └── re2.ts
│   ├── javacript.spec.js
│   ├── json-schema.spec.ts
│   ├── json_parse_tests.json
│   ├── jtd-schema.spec.ts
│   ├── jtd-timestamps.spec.ts
│   ├── keyword.spec.ts
│   ├── options/
│   │   ├── comment.spec.ts
│   │   ├── int32range.spec.ts
│   │   ├── meta_validateSchema.spec.ts
│   │   ├── nullable.spec.ts
│   │   ├── options_add_schemas.spec.ts
│   │   ├── options_code.spec.ts
│   │   ├── options_refs.spec.ts
│   │   ├── options_reporting.spec.ts
│   │   ├── options_validation.spec.ts
│   │   ├── ownProperties.spec.ts
│   │   ├── removeAdditional.spec.ts
│   │   ├── schemaId.spec.ts
│   │   ├── strict.spec.ts
│   │   ├── strictDefaults.spec.ts
│   │   ├── strictKeywords.spec.ts
│   │   ├── strictNumbers.spec.ts
│   │   ├── unicodeRegExp.spec.ts
│   │   ├── unknownFormats.spec.ts
│   │   └── useDefaults.spec.ts
│   ├── remotes/
│   │   ├── bar.json
│   │   ├── buu.json
│   │   ├── first.json
│   │   ├── foo.json
│   │   ├── hyper-schema.json
│   │   ├── name.json
│   │   ├── node.json
│   │   ├── scope_change.json
│   │   ├── second.json
│   │   └── tree.json
│   ├── resolve.spec.ts
│   ├── schema-tests.spec.ts
│   ├── security/
│   │   ├── array.json
│   │   ├── object.json
│   │   └── string.json
│   ├── security.spec.ts
│   ├── standalone.spec.ts
│   ├── tests/
│   │   ├── issues/
│   │   │   ├── 12_restoring_root_after_resolve.json
│   │   │   ├── 13_root_ref_in_ref_in_remote_ref.json
│   │   │   ├── 14_ref_in_remote_ref_with_id.json
│   │   │   ├── 1668_not_with_other_keywords.json
│   │   │   ├── 170_ref_and_id_in_sibling.json
│   │   │   ├── 17_escaping_pattern_property.json
│   │   │   ├── 19_required_many_properties.json
│   │   │   ├── 1_ids_in_refs.json
│   │   │   ├── 20_failing_to_parse_schema.json
│   │   │   ├── 226_json_with_control_chars.json
│   │   │   ├── 27_1_recursive_raml_schema.json
│   │   │   ├── 27_recursive_reference.json
│   │   │   ├── 28_escaping_pattern_error.json
│   │   │   ├── 2_root_ref_in_ref.json
│   │   │   ├── 311_quotes_in_refs.json
│   │   │   ├── 33_json_schema_latest.json
│   │   │   ├── 413_dependencies_with_quote.json
│   │   │   ├── 490_integer_validation.json
│   │   │   ├── 502_contains_empty_array_with_ref_in_another_property.json
│   │   │   ├── 5_adding_dependency_after.json
│   │   │   ├── 5_recursive_references.json
│   │   │   ├── 62_resolution_scope_change.json
│   │   │   ├── 63_id_property_not_in_schema.json
│   │   │   ├── 70_1_recursive_hash_ref_in_remote_ref.json
│   │   │   ├── 70_swagger_schema.json
│   │   │   ├── 861_empty_propertynames.json
│   │   │   ├── 87_$_property.json
│   │   │   └── 94_dependencies_fail.json
│   │   ├── rules/
│   │   │   ├── allOf.json
│   │   │   ├── anyOf.json
│   │   │   ├── comment.json
│   │   │   ├── dependencies.json
│   │   │   ├── format.json
│   │   │   ├── if.json
│   │   │   ├── items.json
│   │   │   ├── oneOf.json
│   │   │   ├── required.json
│   │   │   ├── type.json
│   │   │   └── uniqueItems.json
│   │   └── schemas/
│   │       ├── advanced.json
│   │       ├── basic.json
│   │       ├── complex.json
│   │       ├── complex2.json
│   │       ├── complex3.json
│   │       ├── cosmicrealms.json
│   │       └── medium.json
│   ├── tsconfig.json
│   └── types/
│       ├── async-validate.spec.ts
│       ├── error-parameters.spec.ts
│       ├── json-schema.spec.ts
│       └── jtd-schema.spec.ts
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .eslintrc.js
================================================
const jsConfig = require("@ajv-validator/config/.eslintrc_js")
const tsConfig = require("@ajv-validator/config/.eslintrc")

module.exports = {
  env: {
    es6: true,
    node: true,
  },
  overrides: [
    jsConfig,
    {
      ...tsConfig,
      files: ["*.ts"],
      rules: {
        ...tsConfig.rules,
        complexity: ["error", 17],
        "@typescript-eslint/no-empty-function": "off",
        "@typescript-eslint/no-explicit-any": "off",
        "@typescript-eslint/no-floating-promises": "off",
        "@typescript-eslint/no-implied-eval": "off",
        "@typescript-eslint/no-invalid-this": "off",
        "@typescript-eslint/no-parameter-properties": "off",
        "@typescript-eslint/no-unnecessary-condition": "warn",
        "@typescript-eslint/no-unsafe-assignment": "off",
        "@typescript-eslint/no-unsafe-member-access": "off",
        "@typescript-eslint/restrict-template-expressions": "off",
      },
    },
  ],
}


================================================
FILE: .github/CODEOWNERS
================================================
@epoberezkin


================================================
FILE: .github/FUNDING.yml
================================================
github: epoberezkin
tidelift: "npm/ajv"
open_collective: "ajv"


================================================
FILE: .github/ISSUE_TEMPLATE/bug-or-error-report.md
================================================
---
name: Bug or error report
about: Please use for issues related to incorrect validation behaviour
title: ""
labels: "bug report"
assignees: ""
---

<!--
Frequently Asked Questions: https://ajv.js.org/faq.html
Please provide all info and reduce your schema and data to the smallest possible size.

This template is for bug or error reports.
For other issues please see https://ajv.js.org/contributing/
-->

**What version of Ajv are you using? Does the issue happen if you use the latest version?**

**Ajv options object**

<!-- See https://ajv.js.org/options.html -->

```javascript

```

**JSON Schema**

<!-- Please make it as small as possible to reproduce the issue -->

```json

```

**Sample data**

<!-- Please make it as small as possible to reproduce the issue -->

```json

```

**Your code**

<!--
Please:
- make it as small as possible to reproduce the issue
- use one of the usage patterns from https://ajv.js.org/guide/getting-started.html
- use `options`, `schema` and `data` as variables, do not repeat their values here
- post a working code sample in RunKit notebook cloned from https://runkit.com/esp/ajv-issue and include the link here.

It would make understanding your problem easier and the issue more useful to others.
Thank you!
-->

```javascript

```

**Validation result, data AFTER validation, error messages**

```

```

**What results did you expect?**

**Are you going to resolve the issue?**


================================================
FILE: .github/ISSUE_TEMPLATE/change.md
================================================
---
name: Feature or change proposal
about: For proposals of new features, options or some other improvements
title: ""
labels: "enhancement"
assignees: ""
---

<!--
Frequently Asked Questions: https://ajv.js.org/faq.html
Please provide all info and reduce your schema and data to the smallest possible size.

This template is for change proposals.
For other issues please see https://ajv.js.org/contributing/
-->

**What version of Ajv you are you using?**

**What problem do you want to solve?**

**What do you think is the correct solution to problem?**

**Will you be able to implement it?**


================================================
FILE: .github/ISSUE_TEMPLATE/compatibility.md
================================================
---
name: Browser and compatibility issue
about: For issues that only happen in a specific environment
title: ""
labels: "compatibility"
assignees: ""
---

<!--
Frequently Asked Questions: https://ajv.js.org/faq.html
Please provide all info and reduce your schema and data to the smallest possible size.

This template is for compatibility issues.
For other issues please see https://ajv.js.org/contributing/
-->

**The version of Ajv you are using**

**The environment you have the problem with**

**Your code (please make it as small as possible to reproduce the issue)**

**If your issue is in the browser, please list the other packages loaded in the page in the order they are loaded. Please check if the issue gets resolved (or results change) if you move Ajv bundle closer to the top**

**Results in node.js v8+**

**Results and error messages in your platform**


================================================
FILE: .github/ISSUE_TEMPLATE/installation.md
================================================
---
name: Installation and dependency issue
about: For issues that happen during installation
title: ""
labels: "installation"
assignees: ""
---

<!--
Frequently Asked Questions: https://ajv.js.org/faq.html
Please provide all info and reduce your schema and data to the smallest possible size.

This template is for installation and dependency issues.
For other issues please see https://ajv.js.org/contributing/

Before submitting the issue, please try the following:
- use the latest stable Node.js and npm
- use yarn instead of npm - the issue can be related to https://github.com/npm/npm/issues/19877
- remove node_modules and package-lock.json and run install again
-->

**The version of Ajv you are using**

**Operating system and node.js version**

**Package manager and its version**

**Link to (or contents of) package.json**

**Error messages**

**The output of `npm ls`**


================================================
FILE: .github/ISSUE_TEMPLATE/typescript.md
================================================
---
name: Missing or incorrect type definition
about: Please use for issues related to typescript types
title: ""
labels: "typescript"
assignees: ""
---

<!--
Frequently Asked Questions: https://ajv.js.org/faq.html

This template is for issues about missing or incorrect type definition and other typescript-related issues.
For other issues please see https://ajv.js.org/contributing/
-->

**What version of Ajv are you using? Does the issue happen if you use the latest version?**

**Your typescript code**

<!--
Please make it as small as possible to reproduce the issue
-->

```typescript

```

**Typescript compiler error messages**

```

```

**Describe the change that should be made to address the issue?**

**Are you going to resolve the issue?**


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--
Frequently Asked Questions: https://ajv.js.org/faq.html
Please provide all info and reduce your schema and data to the smallest possible size.

This template is for bug or error reports. For other issues please use:
- security vulnerability: https://tidelift.com/security)
- a new feature/improvement: https://ajv.js.org/contributing/#changes
- browser/compatibility issues: https://ajv.js.org/contributing/#compatibility
- JSON-Schema standard: https://ajv.js.org/contributing/#json-schema
- Ajv usage questions: https://gitter.im/ajv-validator/ajv
-->

**What version of Ajv are you using? Does the issue happen if you use the latest version?**

**Ajv options object**

<!-- See https://ajv.js.org/options.html -->

```javascript

```

**JSON Schema**

<!-- Please make it as small as possible to reproduce the issue -->

```json

```

**Sample data**

<!-- Please make it as small as possible to reproduce the issue -->

```json

```

**Your code**

<!--
Please:
- make it as small as possible to reproduce the issue
- use one of the usage patterns from https://ajv.js.org/guide/getting-started.html
- use `options`, `schema` and `data` as variables, do not repeat their values here
- post a working code sample in RunKit notebook cloned from https://runkit.com/esp/ajv-issue and include the link here.

It would make understanding your problem easier and the issue more useful to others.
Thank you!
-->

```javascript

```

**Validation result, data AFTER validation, error messages**

```


```

**What results did you expect?**

**Are you going to resolve the issue?**


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--
Thank you for submitting a pull request to Ajv.

Before continuing, please read the guidelines:
https://github.com/ajv-validator/ajv/blob/master/CONTRIBUTING.md#pull-requests

If the pull request contains code please make sure there is an issue that we agreed to resolve (if it is a documentation improvement there is no need for an issue).

Please answer the questions below.
-->

**What issue does this pull request resolve?**

**What changes did you make?**

**Is there anything that requires more attention while reviewing?**


================================================
FILE: .github/config.yml
================================================
# Please supply comments to be used for GitHub labels 
githubLabels:
  bug: >
    Bug confirmed - to be fixed. PR is welcome!

#  duplicate: >
#  enhancement: >    
#  good first issue: >    
#  help wanted: >
#  invalid: >
#  question: >    
#  wont fix: >
  
  bug report: >
    Thank you for the report! If you didn't post a code sample to RunKit yet,
    please clone this notebook https://runkit.com/esp/ajv-issue,
    post the code sample that demonstrates the bug and post the link here.
    It will speed up the investigation and fixing!

  json schema: >
    This question is about the usage of JSON Schema specification - it is not specific to Ajv.
    Please use JSON Schema reference materials or [submit the question to Stack Overflow](https://stackoverflow.com/questions/ask?tags=jsonschema,ajv).

    - [JSON Schema specification](http://json-schema.org/)

    - [Tutorial by Space Telescope Science Institute](http://json-schema.org/understanding-json-schema/)

    - [validation keywords](https://github.com/ajv-validator/ajv#validation-keywords) (in Ajv docs)

    - [combining schemas](https://github.com/ajv-validator/ajv#ref) (in Ajv docs)

    - [Tutorial by @epoberezkin](https://code.tutsplus.com/tutorials/validating-data-with-json-schema-part-1--cms-25343)


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: npm
  directory: "/"
  schedule:
    interval: daily
  open-pull-requests-limit: 10
  ignore:
  - dependency-name: "@types/node"
    versions:
    - 15.0.0
  - dependency-name: eslint-config-prettier
    versions:
    - 8.0.0
    - 8.1.0
    - 8.2.0
  - dependency-name: karma
    versions:
    - 6.0.3
    - 6.0.4
    - 6.1.0
    - 6.1.1
    - 6.1.2
    - 6.2.0
    - 6.3.0
    - 6.3.1


================================================
FILE: .github/workflows/build.yml
================================================
name: build

on:
  push:
    branches: [master]
  pull_request:
    branches: ["*"]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x, 21.x]

    steps:
      - uses: actions/checkout@v4
      - name: use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm install
      - run: git submodule update --init
      - name: update website
        if: ${{ github.event_name == 'push' && matrix.node-version == '18.x' }}
        run: ./scripts/publish-site
        env:
          GH_TOKEN_PUBLIC: ${{ secrets.GH_TOKEN_PUBLIC }}
          GIT_USER_EMAIL: ${{ secrets.GIT_USER_EMAIL }}
          GIT_USER_NAME: ${{ secrets.GIT_USER_NAME }}
      - run: npm run build
      - run: npm run test-ci
      - name: coveralls
        uses: coverallsapp/github-action@v2
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/publish.yml
================================================
name: publish

on:
  release:
    types: [published]

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 18
          registry-url: https://registry.npmjs.org/
      - run: npm install
      - run: git submodule update --init
      - run: npm run test-ci
      - name: Publish beta version to npm
        if: ${{ github.event.release.prerelease }}
        run: npm publish --tag beta
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - name: Publish to npm
        if: ${{ !github.event.release.prerelease }}
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - name: Commit bundles to ajv-dist
        run: ./scripts/publish-bundles
        env:
          GH_TOKEN_PUBLIC: ${{ secrets.GH_TOKEN_PUBLIC }}
          GIT_USER_EMAIL: ${{ secrets.GIT_USER_EMAIL }}
          GIT_USER_NAME: ${{ secrets.GIT_USER_NAME }}


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

.DS_Store

# Browserified tests
.browser

# compiled typescript
dist/

# browser bundles
bundle/

package-lock.json

spec/_json/*.js

# docs
docs/code_of_conduct.md
docs/contributing.md
docs/license.md
docs/.vuepress/components/Contributors/
docs/packages/*
!docs/packages/README.md


================================================
FILE: .gitmodules
================================================
[submodule "spec/JSON-Schema-Test-Suite"]
	path = spec/JSON-Schema-Test-Suite
	url = https://github.com/json-schema/JSON-Schema-Test-Suite.git
[submodule "spec/json-typedef-spec"]
	path = spec/json-typedef-spec
	url = https://github.com/jsontypedef/json-typedef-spec.git


================================================
FILE: .npmrc
================================================
package-lock=false


================================================
FILE: .prettierignore
================================================
spec/JSON-Schema-Test-Suite
spec/json-typedef-spec
.browser
coverage
dist
bundle
.nyc_output
spec/_json
docs/.vuepress/components/_contributors.js


================================================
FILE: .runkit_example.js
================================================
const Ajv = require("ajv")
const ajv = new Ajv({allErrors: true})

const schema = {
  type: "object",
  properties: {
    foo: {type: "string"},
    bar: {type: "number", maximum: 3},
  },
  required: ["foo", "bar"],
  additionalProperties: false,
}

const validate = ajv.compile(schema)

test({foo: "abc", bar: 2})
test({foo: 2, bar: 4})

function test(data) {
  const valid = validate(data)
  if (valid) console.log("Valid!")
  else console.log("Invalid: " + ajv.errorsText(validate.errors))
}


================================================
FILE: CODE_OF_CONDUCT.md
================================================
---
permalink: /code_of_conduct
---

# Contributor Covenant Code of Conduct

### Our Pledge

We commit to creating and maintaining an open and welcoming environment. We, as contributors and maintainers, commit to building a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

### Our Standards

**Behaviour that contributes to creating a positive environment include**:

- Using welcoming and inclusive language
  - Consider when identity words like race or ethnicity matter
  - Be conscious of language with discriminatory connotations (e.g. gendered, ableist, racialized phrases)
  - Be open to being corrected if you make a mistake - it’s okay to mess up, what matters is your follow up
- Gracefully accepting constructive criticism
- Showing empathy towards other community members
- Treat other community members and project team members with respect
- Report if you witness harassment or wrongdoing in our spaces

**Unacceptable behaviour by participants include**:

- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

### Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behaviour and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behaviour.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

### Scope

The goal of this Code of Conduct is to set standards and expectations around how we interact within this community. It’s scope applies to all project participants and covers all interactions within the community associated with this project including, but not limited to, email communication, issue trackers, source code repositories, forums, and social media.

Examples of representing a project or community include:

- Using an official project e-mail address
- Posting via an official social media account
- Acting as an appointed representative at an online or offline event

Representation of a project may be further defined and clarified by project maintainers.

### Enforcement

We will not tolerate abuse, harassment, or any other unacceptable behaviour made against community members, project maintainers, or members of our project team, either online or offline.

Violations of our Code of Conduct may be reported by contacting the project team at [ajv.validator@gmail.com](mailto:ajv.validator@gmail.com). The project team will review and investigate all complaints, to the best of our ability, and will respond in a way that it deems appropriate to the circumstances.

Reports of violations will be investigated in a respectful, professional manner as promptly and confidentially as possible. We will have zero tolerance for intimidation or retaliation against anyone who raises a concern, makes a report or cooperates in an investigation around a violation of our code of conduct. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions or removal as determined by other members of the project's leadership.

### Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)

For answers to common questions about this code of conduct, see
[https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq)


================================================
FILE: CONTRIBUTING.md
================================================
---
permalink: /contributing
---

# Contributing guide

Thank you for your help making Ajv better! Every contribution is appreciated. There are many areas where you can contribute.

More than 100 people contributed to Ajv, and we would love to have you join the development. We welcome implementing new features that will benefit many users and ideas to improve our documentation.

At Ajv, we are committed to creating more equitable and inclusive spaces for our community and team members to contribute to discussions that affect both this project and our ongoing work in the open source ecosystem.

We strive to create an environment of respect and healthy discourse by setting standards for our interactions and we expect it from all members of our community - from long term project member to first time visitor. For more information, review our [code of conduct](./CODE_OF_CONDUCT.md) and values.

::: tip Submit issue first
If you plan to implement a new feature or some other change please create an issue first, to make sure that your work is not lost.
:::

[[toc]]

## Documentation

Ajv has a lot of features and maintaining documentation takes time. If anything is unclear, or could be explained better, we appreciate the time you spend correcting or clarifying it.

There is a link in the bottom of each website page to quickly edit it.

## Issues

Before submitting the issue:

- Search the existing issues
- Review [Frequently Asked Questions](./docs/faq.md).
- Provide all the relevant information, reducing both your schema and data to the smallest possible size when they still have the issue.

We value simplicity - simplifying the example that shows the issue makes it more valuable for other users. This process helps us reduce situations where an error is occurring due to incorrect usage rather than a bug.

### Bug reports

Please make sure to include the following information in the issue:

1. What version of Ajv are you using?
2. Does the issue happen if you use the latest version?
3. Ajv [options object](./docs/options)
4. Schema and the data you are validating (please make it as small as possible to reproduce the issue).
5. Your code sample (please use `options`, `schema` and `data` as variables).
6. Validation result, data AFTER validation, error messages.
7. What results did you expect?

To speed up investigation and fixes, please include the link to the working code sample at runkit.com (please clone https://runkit.com/esp/ajv-issue).

[Create bug report](https://github.com/ajv-validator/ajv/issues/new?template=bug-or-error-report.md).

### Security vulnerabilities

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.

Please do NOT report security vulnerabilities via GitHub issues.

<a name="changes"></a>

### Change proposals

[Create a proposal](https://github.com/ajv-validator/ajv/issues/new?template=change.md) for a new feature, option or some other improvement.

Please include this information:

1. The version of Ajv you are using.
2. The problem you want to solve.
3. Your solution to the problem.
4. Would you like to implement it?

If you’re requesting a change, it would be helpful to include this as well:

1. What you did.
2. What happened.
3. What you would like to happen.

Please include as much details as possible - the more information, the better.

<a name="compatibility"></a>

### Browser and compatibility issues

[Create an issue](https://github.com/ajv-validator/ajv/issues/new?template=compatibility.md) to report a compatibility problem that only happens in a particular environment (when your code works correctly in the latest stable Node.js in linux systems but fails in some other environment).

Please include this information:

1. The version of Ajv you are using.
2. The environment you have the problem with.
3. Your code (please make it as small as possible to reproduce the issue).
4. If your issue is in the browser, please list the other packages loaded in the page in the order they are loaded. Please check if the issue gets resolved (or results change) if you move Ajv bundle closer to the top.
5. Results in the latest stable Node.js.
6. Results and error messages in your platform.

<a name="installation"></a>

### Installation and dependency issues

[Create an issue](https://github.com/ajv-validator/ajv/issues/new?template=installation.md) to report problems that happen during Ajv installation or when Ajv is missing some dependency.

Before submitting the issue, please try the following:

- use the latest stable Node.js and `npm`
- try using `yarn` instead of `npm` - the issue can be related to https://github.com/npm/npm/issues/19877
- remove `node_modules` and `package-lock.json` and run `npm install` again

If nothing helps, please submit:

1. The version of Ajv you are using
2. Operating system and Node.js version
3. Package manager and its version
4. Link to (or contents of) package.json and package-lock.json
5. Error messages
6. The output of `npm ls`

<a name="json-schema"></a>

### Using JSON Schema standard

Ajv implements JSON Schema standard draft-04 and draft-06/07.

If it is a general issue related to using the standard keywords included in JSON Schema specification or implementing some advanced validation logic please ask the question on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=jsonschema,ajv) (my account is [esp](https://stackoverflow.com/users/1816503/esp)) or submit the question to [json-schema.org](https://github.com/json-schema-org/json-schema-spec/issues/new). Please mention @epoberezkin.

<a name="usage"></a>

### Ajv usage questions

The best place to ask a question about using Ajv is [Gitter chat](https://gitter.im/ajv-validator/ajv).

If the question is advanced, it can be submitted to [Stack Overflow](http://stackoverflow.com/questions/ask?tags=jsonschema,ajv).

## Code

Thanks a lot for considering contributing to Ajv! Our users have created many great features, and we look forward to your contributions.

For help navigating the code, please review the [Code components](./docs/components.md) document.

### How we make decisions

We value conscious curation of our library size, and balancing performance and functionality. To that end, we cannot accept every suggestion. When evaluating pull requests we consider:

- Will this benefit many users or a niche use case?
- How will this impact the performance of Ajv?
- How will this expand our library size?

To help us evaluate and understand, when you submit an issue and pull request:

- Explain why this feature is important to the user base
- Include documentation
- Include test coverage with any new feature implementations

Please include documentation and test coverage with any new feature implementations.

### Development

Running tests:

```bash
npm install
git submodule update --init
npm test
```

`npm run build` - compiles typescript to dist folder.

`npm run watch` - automatically compiles typescript when files on lib folder changes.

### Pull requests

We want to iterate on the code efficiently. To speed up the process, please follow these steps:

1. Submit an [issue with the bug](https://github.com/ajv-validator/ajv/issues/new) or with the proposed change (unless the contribution is to fix the documentation typos and mistakes).
2. Describe the proposed api and implementation plan (unless the issue is a relatively simple bug and fixing it doesn't change any api).
3. Once agreed, please write as little code as possible to achieve the desired result. We are passionate about keeping our library size optimized.
4. Please add the tests both for the added feature and, if you are submitting an option, for the existing behaviour when this option is turned off or not passed.
5. Please avoid unnecessary changes, refactoring or changing coding styles as part of your change (unless the change was proposed as refactoring).
6. Follow the coding conventions even if they are not validated.
7. Please run the tests before committing your code.
8. If tests fail in CI build after you make a PR please investigate and fix the issue.

### Contributions license

When contributing the code you confirm that:

1. Your contribution is created by you.
2. You have the right to submit it under the MIT license.
3. You understand and agree that your contribution is public, will be stored indefinitely, can be redistributed as the part of Ajv or another related package under MIT license, modified or completely removed from Ajv.
4. You grant irrevocable MIT license to use your contribution as part of Ajv or any other package.
5. You waive all rights to your contribution.
6. Unless you request otherwise, you can be mentioned as the author of the contribution in the Ajv documentation and change log.


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015-2021 Evgeny Poberezkin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
<img align="right" alt="Ajv logo" width="160" src="https://ajv.js.org/img/ajv.svg">

&nbsp;

# Ajv JSON schema validator

The fastest JSON validator for Node.js and browser.

Supports JSON Schema draft-04/06/07/2019-09/2020-12 ([draft-04 support](https://ajv.js.org/json-schema.html#draft-04) requires ajv-draft-04 package) and JSON Type Definition [RFC8927](https://datatracker.ietf.org/doc/rfc8927/).

[![build](https://github.com/ajv-validator/ajv/actions/workflows/build.yml/badge.svg)](https://github.com/ajv-validator/ajv/actions?query=workflow%3Abuild)
[![npm](https://img.shields.io/npm/v/ajv.svg)](https://www.npmjs.com/package/ajv)
[![npm downloads](https://img.shields.io/npm/dm/ajv.svg)](https://www.npmjs.com/package/ajv)
[![Coverage Status](https://coveralls.io/repos/github/ajv-validator/ajv/badge.svg?branch=master)](https://coveralls.io/github/ajv-validator/ajv?branch=master)
[![SimpleX](https://img.shields.io/badge/chat-on%20SimpleX-70F0F9)](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2Fu2dS9sG8nMNURyZwqASV4yROM28Er0luVTx5X1CsMrU%3D%40smp4.simplex.im%2F8KvvURM6J38Gdq9dCuPswMOkMny0xCOJ%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAr8rPVRuMOXv6kwF2yUAap-eoVg-9ssOFCi1fIrxTUw0%253D%26srv%3Do5vmywmrnaxalvz6wi3zicyftgio6psuvyniis6gco6bp6ekl4cqj4id.onion&data=%7B%22type%22%3A%22group%22%2C%22groupLinkId%22%3A%224pwLRgWHU9tlroMWHz0uOg%3D%3D%22%7D)
[![Gitter](https://img.shields.io/gitter/room/ajv-validator/ajv.svg)](https://gitter.im/ajv-validator/ajv)
[![GitHub Sponsors](https://img.shields.io/badge/$-sponsors-brightgreen)](https://github.com/sponsors/epoberezkin)

## Ajv sponsors

[<img src="https://ajv.js.org/img/mozilla.svg" width="45%" alt="Mozilla">](https://www.mozilla.org)<img src="https://ajv.js.org/img/gap.svg" width="9%">[<img src="https://ajv.js.org/img/reserved.svg" width="45%">](https://opencollective.com/ajv)

[<img src="https://ajv.js.org/img/microsoft.png" width="31%" alt="Microsoft">](https://opensource.microsoft.com)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="31%">](https://opencollective.com/ajv)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="31%">](https://opencollective.com/ajv)

[<img src="https://ajv.js.org/img/retool.svg" width="22.5%" alt="Retool">](https://retool.com/?utm_source=sponsor&utm_campaign=ajv)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/tidelift.svg" width="22.5%" alt="Tidelift">](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=enterprise)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/simplex.svg" width="22.5%" alt="SimpleX">](https://github.com/simplex-chat/simplex-chat)<img src="https://ajv.js.org/img/gap.svg" width="3%">[<img src="https://ajv.js.org/img/reserved.svg" width="22.5%">](https://opencollective.com/ajv)

## Contributing

More than 100 people contributed to Ajv, and we would love to have you join the development. We welcome implementing new features that will benefit many users and ideas to improve our documentation.

Please review [Contributing guidelines](./CONTRIBUTING.md) and [Code components](https://ajv.js.org/components.html).

## Documentation

All documentation is available on the [Ajv website](https://ajv.js.org).

Some useful site links:

- [Getting started](https://ajv.js.org/guide/getting-started.html)
- [JSON Schema vs JSON Type Definition](https://ajv.js.org/guide/schema-language.html)
- [API reference](https://ajv.js.org/api.html)
- [Strict mode](https://ajv.js.org/strict-mode.html)
- [Standalone validation code](https://ajv.js.org/standalone.html)
- [Security considerations](https://ajv.js.org/security.html)
- [Command line interface](https://ajv.js.org/packages/ajv-cli.html)
- [Frequently Asked Questions](https://ajv.js.org/faq.html)

## <a name="sponsors"></a>Please [sponsor Ajv development](https://github.com/sponsors/epoberezkin)

Since I asked to support Ajv development 40 people and 6 organizations contributed via GitHub and OpenCollective - this support helped receiving the MOSS grant!

Your continuing support is very important - the funds will be used to develop and maintain Ajv once the next major version is released.

Please sponsor Ajv via:

- [GitHub sponsors page](https://github.com/sponsors/epoberezkin) (GitHub will match it)
- [Ajv Open Collective](https://opencollective.com/ajv)

Thank you.

#### Open Collective sponsors

<a href="https://opencollective.com/ajv"><img src="https://opencollective.com/ajv/individuals.svg?width=890"></a>

<a href="https://opencollective.com/ajv/organization/0/website"><img src="https://opencollective.com/ajv/organization/0/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/1/website"><img src="https://opencollective.com/ajv/organization/1/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/2/website"><img src="https://opencollective.com/ajv/organization/2/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/3/website"><img src="https://opencollective.com/ajv/organization/3/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/4/website"><img src="https://opencollective.com/ajv/organization/4/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/5/website"><img src="https://opencollective.com/ajv/organization/5/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/6/website"><img src="https://opencollective.com/ajv/organization/6/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/7/website"><img src="https://opencollective.com/ajv/organization/7/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/8/website"><img src="https://opencollective.com/ajv/organization/8/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/9/website"><img src="https://opencollective.com/ajv/organization/9/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/10/website"><img src="https://opencollective.com/ajv/organization/10/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/11/website"><img src="https://opencollective.com/ajv/organization/11/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/12/website"><img src="https://opencollective.com/ajv/organization/12/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/13/website"><img src="https://opencollective.com/ajv/organization/13/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/14/website"><img src="https://opencollective.com/ajv/organization/14/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/15/website"><img src="https://opencollective.com/ajv/organization/15/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/16/website"><img src="https://opencollective.com/ajv/organization/16/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/17/website"><img src="https://opencollective.com/ajv/organization/17/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/18/website"><img src="https://opencollective.com/ajv/organization/18/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/19/website"><img src="https://opencollective.com/ajv/organization/19/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/20/website"><img src="https://opencollective.com/ajv/organization/20/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/21/website"><img src="https://opencollective.com/ajv/organization/21/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/22/website"><img src="https://opencollective.com/ajv/organization/22/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/23/website"><img src="https://opencollective.com/ajv/organization/23/avatar.svg"></a>
<a href="https://opencollective.com/ajv/organization/24/website"><img src="https://opencollective.com/ajv/organization/24/avatar.svg"></a>

## Performance

Ajv generates code to turn JSON Schemas into super-fast validation functions that are efficient for v8 optimization.

Currently Ajv is the fastest and the most standard compliant validator according to these benchmarks:

- [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark) - 50% faster than the second place
- [jsck benchmark](https://github.com/pandastrike/jsck#benchmarks) - 20-190% faster
- [z-schema benchmark](https://rawgit.com/zaggino/z-schema/master/benchmark/results.html)
- [themis benchmark](https://cdn.rawgit.com/playlyfe/themis/master/benchmark/results.html)

Performance of different validators by [json-schema-benchmark](https://github.com/ebdrup/json-schema-benchmark):

[![performance](https://chart.googleapis.com/chart?chxt=x,y&cht=bhs&chco=76A4FB&chls=2.0&chbh=62,4,1&chs=600x416&chxl=-1:|ajv|@exodus/schemasafe|is-my-json-valid|djv|@cfworker/json-schema|jsonschema/=t:100,69.2,51.5,13.1,5.1,1.2)](https://github.com/ebdrup/json-schema-benchmark/blob/master/README.md#performance)

## Features

- Ajv implements JSON Schema [draft-06/07/2019-09/2020-12](http://json-schema.org/) standards (draft-04 is supported in v6):
  - all validation keywords (see [JSON Schema validation keywords](https://ajv.js.org/json-schema.html))
  - [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md) extensions:
    - NEW: keyword [discriminator](https://ajv.js.org/json-schema.html#discriminator).
    - keyword [nullable](https://ajv.js.org/json-schema.html#nullable).
  - full support of remote references (remote schemas have to be added with `addSchema` or compiled to be available)
  - support of recursive references between schemas
  - correct string lengths for strings with unicode pairs
  - JSON Schema [formats](https://ajv.js.org/guide/formats.html) (with [ajv-formats](https://github.com/ajv-validator/ajv-formats) plugin).
  - [validates schemas against meta-schema](https://ajv.js.org/api.html#api-validateschema)
- NEW: supports [JSON Type Definition](https://datatracker.ietf.org/doc/rfc8927/):
  - all keywords (see [JSON Type Definition schema forms](https://ajv.js.org/json-type-definition.html))
  - meta-schema for JTD schemas
  - "union" keyword and user-defined keywords (can be used inside "metadata" member of the schema)
- supports [browsers](https://ajv.js.org/guide/environments.html#browsers) and Node.js 10.x - current
- [asynchronous loading](https://ajv.js.org/guide/managing-schemas.html#asynchronous-schema-loading) of referenced schemas during compilation
- "All errors" validation mode with [option allErrors](https://ajv.js.org/options.html#allerrors)
- [error messages with parameters](https://ajv.js.org/api.html#validation-errors) describing error reasons to allow error message generation
- i18n error messages support with [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) package
- [removing-additional-properties](https://ajv.js.org/guide/modifying-data.html#removing-additional-properties)
- [assigning defaults](https://ajv.js.org/guide/modifying-data.html#assigning-defaults) to missing properties and items
- [coercing data](https://ajv.js.org/guide/modifying-data.html#coercing-data-types) to the types specified in `type` keywords
- [user-defined keywords](https://ajv.js.org/guide/user-keywords.html)
- additional extension keywords with [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package
- [\$data reference](https://ajv.js.org/guide/combining-schemas.html#data-reference) to use values from the validated data as values for the schema keywords
- [asynchronous validation](https://ajv.js.org/guide/async-validation.html) of user-defined formats and keywords

## Install

To install version 8:

```
npm install ajv
```

## <a name="usage"></a>Getting started

Try it in the Node.js REPL: https://runkit.com/npm/ajv

In JavaScript:

```javascript
// or ESM/TypeScript import
import Ajv from "ajv"
// Node.js require:
const Ajv = require("ajv")

const ajv = new Ajv() // options can be passed, e.g. {allErrors: true}

const schema = {
  type: "object",
  properties: {
    foo: {type: "integer"},
    bar: {type: "string"},
  },
  required: ["foo"],
  additionalProperties: false,
}

const data = {
  foo: 1,
  bar: "abc",
}

const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) console.log(validate.errors)
```

Learn how to use Ajv and see more examples in the [Guide: getting started](https://ajv.js.org/guide/getting-started.html)

## Changes history

See [https://github.com/ajv-validator/ajv/releases](https://github.com/ajv-validator/ajv/releases)

**Please note**: [Changes in version 8.0.0](https://github.com/ajv-validator/ajv/releases/tag/v8.0.0)

[Version 7.0.0](https://github.com/ajv-validator/ajv/releases/tag/v7.0.0)

[Version 6.0.0](https://github.com/ajv-validator/ajv/releases/tag/v6.0.0).

## Code of conduct

Please review and follow the [Code of conduct](./CODE_OF_CONDUCT.md).

Please report any unacceptable behaviour to ajv.validator@gmail.com - it will be reviewed by the project team.

## Security contact

To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure. Please do NOT report security vulnerabilities via GitHub issues.

## Open-source software support

Ajv is a part of [Tidelift subscription](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=readme) - it provides a centralised support to open-source software users, in addition to the support provided by software maintainers.

## License

[MIT](./LICENSE)


================================================
FILE: benchmark/jtd.js
================================================
/* eslint-disable no-empty */
/* eslint-disable no-console */
const Ajv = require("ajv/dist/jtd")
const Benchmark = require("benchmark")
const jtdValidationTests = require("../spec/json-typedef-spec/tests/validation.json")

const ajv = new Ajv()
const suite = new Benchmark.Suite()
const tests = []

for (const testName in jtdValidationTests) {
  const {schema, instance, errors} = jtdValidationTests[testName]
  const valid = errors.length === 0
  if (!valid) continue
  tests.push({
    validate: ajv.compile(schema),
    serialize: ajv.compileSerializer(schema),
    parse: ajv.compileParser(schema),
    data: instance,
    json: JSON.stringify(instance),
  })
}

// suite.add("JTD test suite: compiled JTD serializers", () => {
//   for (const test of tests) {
//     test.serialize(test.data)
//   }
// })

// suite.add("JTD test suite: JSON.stringify", () => {
//   for (const test of tests) {
//     JSON.stringify(test.data)
//   }
// })

const testSchema = {
  definitions: {
    obj: {
      properties: {
        foo: {type: "string"},
        bar: {type: "int8"},
      },
    },
  },
  properties: {
    a: {ref: "obj"},
  },
  optionalProperties: {
    b: {ref: "obj"},
  },
}

const testData = {
  a: {
    foo: "foo1",
    bar: 1,
  },
  b: {
    foo: "foo2",
    bar: 2,
  },
}

// const serializer = ajv.compileSerializer(testSchema)

// suite.add("test data: compiled JTD serializer", () => serializer(testData))
// suite.add("test data: JSON.stringify", () => JSON.stringify(testData))

suite.add("JTD test suite: compiled JTD parsers", () => {
  for (const test of tests) {
    test.parse(test.json)
  }
})

suite.add("JTD test suite: JSON.parse", () => {
  for (const test of tests) {
    JSON.parse(test.json)
  }
})

suite.add("JTD test suite: JSON.parse + validate", () => {
  for (const test of tests) {
    JSON.parse(test.json)
  }
})

const validTestData = JSON.stringify(testData)

const invalidTestData = JSON.stringify({
  a: {
    foo: "foo1",
    bar: "1",
  },
  b: {
    foo: "foo2",
    bar: 2,
  },
})

const parse = ajv.compileParser(testSchema)
const validate = ajv.compile(testSchema)

suite.add("valid test data: compiled JTD parser", () => parse(validTestData))
suite.add("valid test data: JSON.parse", () => JSON.parse(validTestData))
suite.add("valid test data: JSON.parse + validate", () => validate(JSON.parse(validTestData)))
suite.add("invalid test data: compiled JTD parser", () => parse(invalidTestData))
suite.add("invalid test data: JSON.parse", () => JSON.parse(invalidTestData))
suite.add("invalid test data: JSON.parse + validate", () => validate(JSON.parse(invalidTestData)))

console.log()

suite
  .on("cycle", (event) => console.log(String(event.target)))
  .on("complete", function () {
    // eslint-disable-next-line no-invalid-this
    console.log('The fastest is "' + this.filter("fastest").map("name") + '"')
  })
  .run({async: true})


================================================
FILE: benchmark/package.json
================================================
{
  "private": true,
  "devDependencies": {
    "benchmark": "^2.1.4"
  }
}


================================================
FILE: bower.json
================================================
{
  "name": "ajv",
  "description": "Another JSON Schema Validator",
  "main": "bundle/ajv.min.js",
  "authors": ["Evgeny Poberezkin"],
  "license": "MIT",
  "keywords": ["JSON", "schema", "validator"],
  "homepage": "https://github.com/ajv-validator/ajv",
  "moduleType": ["amd", "globals", "node"],
  "ignore": ["node_modules", "bower_components", "spec"]
}


================================================
FILE: docs/.vuepress/components/Button.vue
================================================
<template>
  <a :href="link" :class="cssClass" class="button"><slot /></a>
</template>

<script>
export default {
  props: {
    link: {
      type: String,
    },
    cssClass: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
a.button
  display block
  width 114px
  height 38px
  line-height 38px
  background-color $ajvGreenColor
  border-radius 6px
  color white
  text-align center
  font-weight 600
</style>


================================================
FILE: docs/.vuepress/components/Column.vue
================================================
<template>
  <div :class="side" class="column">
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    side: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
.column
  margin-bottom 22px

  @media only screen and (min-width: $MQMobile)
    &.left
      width 33%
      margin-right 5%

    &.right
      width 62%
</style>


================================================
FILE: docs/.vuepress/components/Columns.vue
================================================
<template>
  <div class="columns">
    <slot />
  </div>
</template>

<style lang="stylus" scoped>
@media only screen and (min-width: $MQMobile)
  .columns
    display flex
</style>


================================================
FILE: docs/.vuepress/components/Contributors.vue
================================================
<template>
  <div>
    <a
      v-for="(contributor, i) in contributors"
      class="contributor"
      :style="'background-position: ' + (100 * i) / (contributors.length - 1) + '% 0'"
      :href="'https://github.com/' + contributor"
    >
      {{ contributor }}
    </a>
  </div>
</template>

<script>
import contributors from "./Contributors/_contributors.js"
export default {
  data() {
    return {
      contributors: contributors,
    }
  },
}
</script>

<style lang="stylus" scoped>
.contributor
  width 3.26em
  height 3.26em
  border-radius 50%
  text-indent -9999px
  display inline-block
  background no-repeat url('./Contributors/contributors.jpg')
  background-size auto 102%
  margin 0 0.67em 0.67em 0
  border 2px solid var(--second)
  @media only screen and (min-width: $MQMobileSmall)
    width 3.625em
    height 3.625em
    margin 0 0.8em 0.8em 0
</style>


================================================
FILE: docs/.vuepress/components/Feature.vue
================================================
<template>
  <div :class="type">
    <slot />
    <a class="read-more" :href="link">
      <img src="./Feature/arrow.svg" />
    </a>
  </div>
</template>

<script>
export default {
  props: {
    type: {
      type: String,
    },
    link: {
      type: String,
    },
  },
}
</script>


<style lang="stylus" scoped>
div
  height 200px
  box-sizing border-box
  padding 28px
  border-radius 8px
  position relative
  color #fff
  margin-bottom 25px

  @media only screen and (min-width: $MQMobileNarrow)
    height 160px

  @media only screen and (min-width: $MQMobile)
    width 31.25%
    height 225px
    margin-right 3%
    margin-bottom 0

  h3
    margin 0 0
    @media only screen and (min-width: $MQNarrow)
      font-size 1.75em

    .header-anchor
      display none

  p
    @media only screen and (min-width: $MQNarrow)
      font-size 1.25em

  &.less-code
    background-color $ajvGreenColor

  &.fast-secure
    background-color $ajvBlueColor

  &.multi-spec
    background-color $ajvRedColor

@media only screen and (min-width: $MQMobile)
  div:last-child
    margin-right 0

a
  position absolute
  bottom 24px
  right 24px
  color #fff
</style>


================================================
FILE: docs/.vuepress/components/Features.vue
================================================
<template>
  <div class="features">
    <slot />
  </div>
</template>

<style lang="stylus" scoped>
.features
  padding 60px 0

  @media only screen and (min-width: $MQMobile)
    display flex
</style>


================================================
FILE: docs/.vuepress/components/FooterColumn.vue
================================================
<template>
  <div :class="type" class="column">
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    type: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
div
  @media only screen and (min-width: $MQMobile)
    width 25%

p
  a
    color $textColor
    font-weight normal
    &:hover
      text-decoration underline

  @media only screen and (max-width: $MQMobile)
    margin 0
    line-height 30px

.column
  img
    display block
    margin 0 auto

  &.ajv
    img
      margin 0 0
      width 100px      
      @media only screen and (max-width: $MQMobile)
        margin-bottom 34px


  &.links a
    color $textColor
    font-weight normal

  &.sponsors
    @media only screen and (max-width: $MQMobile)
      a:first-child
        display block
        margin-top 80px

    img
      width 140px
      padding 0 20px 15px
</style>


================================================
FILE: docs/.vuepress/components/FooterColumns.vue
================================================
<template>
  <div class="footer-columns">
    <slot />
  </div>
</template>

<style lang="stylus" scoped>
.footer-columns
  padding 20px 0 60px
  border-bottom 1px solid #C4C4C4

  @media only screen and (min-width: $MQMobile)
    display flex
</style>


================================================
FILE: docs/.vuepress/components/GitHub.vue
================================================
<template>
  <ClientOnly>
    <span>
      <a
        class="github-button"
        href="https://github.com/ajv-validator/ajv"
        data-show-count="true"
        data-size="large"
        aria-label="Star ajv-validator/ajv on GitHub"
      >
        Star
      </a>
    </span>
  </ClientOnly>
</template>

<script>
export default {
  mounted() {
    let githubScript = document.createElement("script")
    githubScript.setAttribute("src", "https://buttons.github.io/buttons.js")
    document.head.appendChild(githubScript)
  },
}
</script>

<style lang="stylus" scoped>
span
  vertical-align -8px
  padding-left 20px
  @media only screen and (max-width: $MQMobile)
    vertical-align -21px
</style>


================================================
FILE: docs/.vuepress/components/HeroSection.vue
================================================
<template>
  <div class="hero-section">
    <div class="section-content">
      <img src="./HeroSection/hero-image.svg" class="hero-image" />
      <div class="section-content-wrapper">
        <slot />
      </div>
    </div>
  </div>
</template>

<style lang="stylus" scoped>
.hero-section
  width 100%
  padding 50px 0
  padding-top $navbarHeight
  overflow hidden

  .section-content
    position relative
    max-width 1000px
    padding 0 50px
    margin 0 auto
    @media only screen and (max-width: $MQMobile)
      padding 0 40px
    @media only screen and (max-width: $MQMobileNarrow)
      padding 0 30px

    .section-content-wrapper
      position relative
      z-index 2

  .hero-image
    position absolute
    z-index 1
    width 658px
    top -400px
    left -25px

    @media only screen and (min-width: $MQMobileNarrow)
      width 823px
      top -500px
      left 50px

    @media only screen and (min-width: $MQMobile)
      top -430px
      left 330px

    @media only screen and (min-width: $MQNarrow)
      width 1097px
      top -575px
      left 425px

  background linear-gradient(304.33deg, rgba(237, 237, 237, 0.31) -7.48%, #C6E1FF 30.07%, rgba(237, 237, 237, 0.26) 82.76%)

  .header-anchor
    display none

  h1
    font-size 2em
    margin-top 200px
  h2
    border-bottom none

  @media only screen and (min-width: $MQMobileNarrow)
    h1
      font-size 3em
    h2
      font-size 1.75em

  @media only screen and (min-width: $MQMobile)
    h1, h2
      margin-left 48px

  @media only screen and (min-width: $MQNarrow)
    h1
      font-size 4em
    h2
      font-size 2.25em
    h1, h2
      margin-left 64px
</style>

================================================
FILE: docs/.vuepress/components/HomePage.vue
================================================
<template>
  <main class="homepage">
    <slot name="top" />

    <Content />

    <slot name="bottom" />
  </main>
</template>

<style lang="stylus" scoped>
@require '../theme/styles/wrapper.styl'

.homepage
  padding 0 0 0 0
  box-sizing content-box
</style>


================================================
FILE: docs/.vuepress/components/HomeSection.vue
================================================
<template>
  <div class="home-section" :class="section">
    <div class="section-content">
      <slot />
    </div>
  </div>
</template>

<script>
export default {
  props: {
    section: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
.home-section
  width 100%
  padding 50px 0
  padding-top $navbarHeight

  .section-content
    max-width 1000px
    padding 0 50px
    margin 0 auto
    @media only screen and (max-width: $MQMobile)
      padding 0 40px
    @media only screen and (max-width: $MQMobileNarrow)
      padding 0 30px

  & >>> .theme-code-group
    button
      position relative
      outline none
      z-index 1

  &.testimonials
    background linear-gradient(295.26deg, rgba(232, 232, 232, 0.8) 26.65%, rgba(255, 255, 255, 0.04) 83.48%)

  &.contributors
    background linear-gradient(295.26deg, rgba(232, 232, 232, 0.8) 26.65%, rgba(255, 255, 255, 0.04) 83.48%)

  &.footer
    background linear-gradient(295.26deg, rgba(232, 232, 232, 0.8) 26.65%, rgba(255, 255, 255, 0.04) 83.48%)

    p
      padding 20px 0 0
      text-align center
      color #292828

      a
        color $textColor
        font-weight normal
        &:hover
          text-decoration underline
</style>

================================================
FILE: docs/.vuepress/components/NewsHome.vue
================================================
<template>
  <div>
    <div v-for="(post, i) in posts" class="post">
      <Columns>
        <Column side="left">
          <h3>{{ post.frontmatter.title }}</h3>
          <NewsPostMeta :date="post.frontmatter.date" />
        </Column>

        <Column side="right">
          <div v-html="post.excerpt"></div>
          <Button :link="post.path" cssClass="read-more" v-if="post.frontmatter.more !== false">Read more</Button>
        </Column>
      </Columns>
    </div>
    <p class="subscribe">
      <Subscribe />
      <a href="/news/" class="all-news">All news</a>
    </p>
  </div>
</template>

<script>
export default {
  computed: {
    posts() {
      return this.$site.pages
        .filter((x) => x.path.startsWith("/news/") && !x.frontmatter.newsIndex)
        .sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date))
        .slice(0, 3)
    },
  },
}
</script>

<style lang="stylus" scoped>
.post
  display flex
  border-bottom 1px solid #eaecef

  &:last-child
    border-bottom none

  a.read-more
    float right
    margin 28px 0

p.subscribe
  margin-top 2em

  a.all-news
    display block
    margin-top 1rem

    @media only screen and (min-width: $MQMobileNarrow)
      display inline-block
      float right
      margin-top 0
</style>


================================================
FILE: docs/.vuepress/components/NewsIndex.vue
================================================
<template>
  <div>
    <div v-for="post in posts">
      <h2>{{ post.frontmatter.title }}</h2>

      <router-link :to="post.path">
        <NewsPostMeta :date="post.frontmatter.date" />
      </router-link>

      <div v-html="post.excerpt"></div>

      <p v-if="post.frontmatter.more !== false">
        <router-link :to="post.path">Read more</router-link>
      </p>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    posts() {
      return this.$site.pages
        .filter((x) => x.path.startsWith("/news/") && !x.frontmatter.newsIndex)
        .sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date))
    },
  },
}
</script>


================================================
FILE: docs/.vuepress/components/NewsPost.vue
================================================
<template>
  <main class="page">
    <slot name="top" />

    <div class="theme-default-content" style="padding-bottom: 0px">
      <h1>{{ $page.frontmatter.title }}</h1>
      <NewsPostMeta :date="$page.frontmatter.date" />
    </div>

    <Content class="theme-default-content" style="padding-top: 0px" />
    <PageEdit />

    <slot name="bottom" />
  </main>
</template>

<script>
import PageEdit from "@theme/components/PageEdit.vue"

export default {
  components: {PageEdit},
}
</script>

<style lang="stylus" scoped>
@require '../theme/styles/wrapper.styl'

.page
  padding-bottom 2rem
  display block
</style>


================================================
FILE: docs/.vuepress/components/NewsPostMeta.vue
================================================
<template>
  <div class="post-meta">
    <time class="pub-date" pubdate itemprop="datePublished" :datetime="date">
      {{ resolvedDate }}
    </time>
  </div>
</template>

<script>
import dayjs from "dayjs"
import dayjsPluginUTC from "dayjs/plugin/utc"

dayjs.extend(dayjsPluginUTC)

export default {
  props: {
    date: {
      type: String,
    },
  },
  computed: {
    resolvedDate() {
      return dayjs.utc(this.date).format("MMMM D, YYYY")
    },
  },
}
</script>

<style lang="stylus" scoped>
.post-meta > div
  display inline-flex

.pub-date
  color #808080
</style>


================================================
FILE: docs/.vuepress/components/Projects.vue
================================================
<template>
  <div class="projects">
    <slot />
  </div>
</template>

<style lang="stylus" scoped>
.projects
  p
    max-width 1100px
    padding 0

  img
    display inline-block
    max-width 240px
    height 40px
    line-height 40px
    vertical-align middle
    @media only screen and (max-width: $MQMobile)
      max-width 160px
      height 30px
      line-height 30px

  a
    display inline-block
    height 40px
    line-height 40px
    vertical-align middle
    margin 0 36px 30px 0
    font-size 28px
    font-weight 500
    color $textColor
    @media only screen and (max-width: $MQMobile)
      margin 0 24px 20px 0
      height 30px
      line-height 30px
      font-size 20px

    &:hover
      text-decoration none

    span
      display none
</style>


================================================
FILE: docs/.vuepress/components/Sponsors.vue
================================================
<template>
  <div class="sponsors" :class="level">
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    level: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
.sponsors
  max-width 800px
  margin 0 auto

  h2
    margin-left 0
    text-decoration none

    a.header-anchor
      width auto
      margin-right 0
  p
    font-size 24px

  &.platinum, &.gold, &.bronze
    img
      width 100%
    a
      margin-bottom 10px
      display inline-block
      @media only screen and (min-width: $MQMobileNarrow)
        margin-bottom 0
    a:last-child
      margin-right 0

  &.platinum
    a
      width 100%
      display block
      @media only screen and (min-width: $MQMobileNarrow)
        display inline-block
        width 45%
        margin-right 8%

  &.gold
    a
      width 45%
      margin-right 4%
      @media only screen and (min-width: $MQMobileNarrow)
        width 31%
        margin-right 2%

  &.bronze
    a
      width 45%
      margin-right 4%
      @media only screen and (min-width: $MQMobileNarrow)
        width 22%
        margin-right 3%

</style>


================================================
FILE: docs/.vuepress/components/Subscribe.vue
================================================
<template>
  <form
    action="https://ajv.us1.list-manage.com/subscribe/post?u=4343a2a251fa30892c2360003&amp;id=304f51cbc3"
    method="post"
    target="_blank"
    novalidate
  >
    <label for="subscription-email">Subscribe to Ajv news</label>
    <input id="subscription-email" name="EMAIL" placeholder="Your email" />
    <div style="position: absolute; left: -5000px;" aria-hidden="true">
      <input type="text" name="b_4343a2a251fa30892c2360003_304f51cbc3" tabindex="-1" value="">
    </div>
    <button type="submit">Submit</button>
  </form>
</template>

<style lang="stylus" scoped>
form
  display inline-block

label
  display block
  margin-bottom 1rem
  @media only screen and (min-width: $MQMobile)
    display inline-block
    margin-bottom 0

input, button
  font-family Raleway
  font-size 16px
  border 0px solid
  outline none

input
  border 1px solid #cfd4db
  height 2rem
  width 180px
  border-radius 2rem
  padding 0 0.5rem
  margin 0 0.5rem 0 0
  &:focus
    border-color: $accentColor
  @media only screen and (min-width: $MQMobile)
    width 200px
    margin 0 1rem


button
  width 114px
  height 36px
  line-height 36px
  padding-top 0
  background-color $ajvGreenColor
  border-radius 6px
  color white
  text-align center
  font-weight 600
  display block
  margin-top 1em
  @media only screen and (min-width: $MQMobileSmall)
    display inline-block
    margin-top 0
</style>


================================================
FILE: docs/.vuepress/components/Testimonial.vue
================================================
<template>
  <div class="testimonial-content" :class="color">
    <slot />
  </div>
</template>

<script>
export default {
  props: {
    color: {
      type: String,
    },
  },
}
</script>

<style lang="stylus" scoped>
div.testimonial-content
  background-position center
  overflow hidden
  width 280px
  background-repeat no-repeat
  &.blue
    background-image url(./Testimonial/testimonials-blue.svg)
  &.green
    background-image url(./Testimonial/testimonials-green.svg)
  p
    margin 0.9em 0
    font-size 15px

  @media only screen and (max-width 374px)
    &.blue, &.green
      background-image none
      padding 0 0
      p
        font-size 15px

  @media only screen and (max-width 500px)
    width 100%
    background-size 350px 156px
    padding 0 calc(50% - 100px)
    box-sizing border-box
    p
      font-size 12px

  @media only screen and (min-width 500px)
    height 212px
    padding 0 75px
    margin 40px auto 0

  @media only screen and (min-width $MQNarrow)
    padding 0 calc(25% - 140px)

.header-anchor
  display none
</style>


================================================
FILE: docs/.vuepress/components/Testimonials.vue
================================================
<template>
  <div class="testimonials">
    <slot />
  </div>
</template>

<style lang="stylus" scoped>
.testimonials
  padding 20px 0
  @media only screen and (min-width $MQNarrow)
    display flex
</style>


================================================
FILE: docs/.vuepress/config.js
================================================
const {slugify} = require("@vuepress/shared-utils")

const title = "Ajv JSON schema validator"
const description =
  "The fastest JSON schema Validator. Supports JSON Schema draft-04/06/07/2019-09/2020-12 and JSON Type Definition (RFC8927)"

module.exports = {
  title,
  description,
  head: [
    ["link", {rel: "icon", href: `/favicon.ico`}],
    ["meta", {charset: "utf-8"}],
    ["meta", {property: "og:title", content: title}],
    ["meta", {property: "og:description", content: description}],
    ["meta", {property: "og:image", content: "https://ajv.js.org/img/ajv.png"}],
    ["meta", {itemprop: "image", content: "https://ajv.js.org/img/ajv.png"}],
    ["meta", {name: "twitter:card", content: "summary"}],
    ["meta", {name: "twitter:title", content: title}],
    ["meta", {name: "twitter:image:src", content: "https://ajv.js.org/img/ajv.png"}],
    ["meta", {name: "apple-mobile-web-app-capable", content: "yes"}],
    ["link", {rel: "apple-touch-icon", href: `/img/apple-touch-icon.png`}],
  ],
  markdown: {
    slugify: (str) => slugify(str.replace(/<Badge[^>]*\/>/, "")),
    toc: {includeLevel: [2, 3, 4]},
  },
  heroText: "hello there",
  themeConfig: {
    logo: "/img/ajv.svg",
    nav: [
      {text: "Home", link: "/"},
      {
        text: "Guide",
        items: [
          {link: "/guide/why-ajv", text: "Why use Ajv"},
          {link: "/guide/getting-started", text: "Getting started"},
          {link: "/guide/typescript", text: "Using with TypeScript"},
          {link: "/guide/schema-language", text: "Choosing schema language"},
          {link: "/guide/managing-schemas", text: "Managing schemas"},
          {link: "/guide/combining-schemas", text: "Combining schemas"},
          {link: "/guide/formats", text: "Format validation"},
          {link: "/guide/modifying-data", text: "Modifying data"},
          {link: "/guide/user-keywords", text: "User-defined keywords"},
          {link: "/guide/async-validation", text: "Asynchronous validation"},
          {link: "/guide/environments", text: "Execution environments"},
        ],
      },
      {
        text: "Reference",
        items: [
          {link: "/api", text: "API Reference"},
          {link: "/options", text: "Ajv options"},
          {link: "/json-schema", text: "JSON Schema"},
          {link: "/json-type-definition", text: "JSON Type Definition"},
          {link: "/strict-mode", text: "Strict mode"},
          {link: "/standalone", text: "Standalone validation code"},
          {link: "/keywords", text: "User defined keywords"},
          {link: "/coercion", text: "Type coercion rules"},
        ],
      },
      {
        text: "Learn more",
        items: [
          {
            text: "Extending Ajv",
            items: [
              {link: "/packages/", text: "Extending Ajv"},
              {link: "/packages/ajv-cli", text: "ajv-cli"},
              {link: "/packages/ajv-errors", text: "ajv-errors"},
              {link: "/packages/ajv-formats", text: "ajv-formats"},
              {link: "/packages/ajv-i18n", text: "ajv-i18n"},
              {link: "/packages/ajv-keywords", text: "ajv-keywords"},
            ],
          },
          {
            text: "Contributors",
            items: [
              {link: "/contributing", text: "Contributing guide"},
              {link: "/codegen", text: "Code generation design"},
              {link: "/components", text: "Code components"},
              {link: "/code_of_conduct", text: "Code of Conduct"},
            ],
          },
          {
            text: "Information",
            items: [
              {link: "/news/", text: "News"},
              {link: "/faq", text: "FAQ"},
              {link: "/security", text: "Security"},
              {link: "/v6-to-v8-migration", text: "Migrate from v6"},
              {link: "/testimonials", text: "What users say"},
              {link: "/license", text: "License"},
            ],
          },
        ],
      },
    ],
    sidebar: [
      {
        title: "Guide",
        children: [
          "/guide/why-ajv",
          "/guide/getting-started",
          "/guide/typescript",
          "/guide/schema-language",
          "/guide/managing-schemas",
          "/guide/combining-schemas",
          "/guide/formats",
          "/guide/modifying-data",
          "/guide/user-keywords",
          "/guide/async-validation",
          "/guide/environments",
        ],
      },
      {
        title: "Reference",
        children: [
          "/api",
          "/options",
          "/json-schema",
          "/json-type-definition",
          "/strict-mode",
          "/standalone",
          "/keywords",
          "/coercion",
        ],
      },
      {
        title: "Extending Ajv",
        children: [
          ["/packages/", "Extending Ajv"],
          ["/packages/ajv-formats", "ajv-formats"],
          ["/packages/ajv-keywords", "ajv-keywords"],
          ["/packages/ajv-errors", "ajv-errors"],
          ["/packages/ajv-i18n", "ajv-i18n"],
          ["/packages/ajv-cli", "ajv-cli"],
        ],
      },
      {
        title: "Contributors",
        children: [
          "/contributing",
          "/codegen",
          "/components",
          ["/code_of_conduct", "Code of conduct"],
        ],
      },
      {
        title: "Information",
        children: [
          "/news/",
          "/faq",
          "/security",
          ["/v6-to-v8-migration", "Migrate from v6 to v8"],
          "/testimonials",
          ["/license", "License"],
        ],
      },
    ],
    repo: "ajv-validator/ajv",
    docsDir: "docs",
    editLinks: true,
    activeHeaderLinks: false,
  },
}


================================================
FILE: docs/.vuepress/styles/index.styl
================================================
img + span > .icon.outbound {
  display: none;
}

body {
  font-family: 'Raleway';
  font-weight: normal;
}

strong {
  font-weight: 550;
}

h1, h2, h3, h4, h5, h6 {
  font-family: 'IstokWeb';
  font-weight: normal;
}

.custom-block.tip {
  border-color: $tipColor;
  background-color: $attentionBoxColor;
  color: $textColor;

  .custom-block-title {
    color: $textColor;
  }
}

.custom-block.warning {
  border-color: $warningColor;
  background-color: $attentionBoxColor;
  color: $textColor;

  .custom-block-title {
    color: $textColor;
  }
}

.custom-block.danger {
  border-color: $dangerColor;
  background-color: $attentionBoxColor;
  color: $textColor;

  .custom-block-title {
    color: $textColor;
  }
}

.sidebar nav.nav-links div.nav-item {
  display: none;
}

span.badge {
  font-family: 'Raleway';
  font-weight: 500;
}

.theme-code-group .token.string {
  color: $accentCode;
}

.theme-code-group button.theme-code-group__nav-tab.theme-code-group__nav-tab-active {
  border-color: $accentCode;
}

.navbar span.site-name {
  font-family: IstokWeb;
  font-weight: 500;
  font-size: 1.6em;
}

p.sidebar-heading {
  font-weight: 500;
  font-size: 1em;
}

a.sidebar-link.active {
  font-weight: 500!important;
}

@font-face {
  font-family: 'Raleway';
  src: url(/fonts/Raleway-VariableFont_wght.ttf);
}

@font-face {
  font-family: 'IstokWeb';
  src: url(/fonts/IstokWeb-Regular.ttf);
  font-weight: normal;
}


================================================
FILE: docs/.vuepress/styles/palette.styl
================================================
$ajvBlueColor = #409cff
$ajvGreenColor = #23c8d2 // #1fdca3
$ajvRedColor = #f5775b

$tipColor = $ajvGreenColor
$warningColor = #f1f440
$dangerColor = $ajvRedColor
$attentionBoxColor = #f7f7f3

$accentColor = #07aab4 // darken($ajvGreenColor, 15%)
$accentCode = #7ec699
$textColor = #292828
$borderColor = #eaecef
$codeBgColor = #282c34
$arrowBgColor = #ccc
$badgeTipColor = $ajvGreenColor
$badgeWarningColor = #e9c400
$badgeErrorColor = $ajvRedColor

$MQMobileNarrow = 480px
$MQMobileSmall = 414px


================================================
FILE: docs/.vuepress/theme/LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2018-present, Yuxi (Evan) You

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: docs/.vuepress/theme/components/AlgoliaSearchBox.vue
================================================
<template>
  <form
    id="search-form"
    class="algolia-search-wrapper search-box"
    role="search"
  >
    <input
      id="algolia-search-input"
      class="search-query"
      :placeholder="placeholder"
    >
  </form>
</template>

<script>
export default {
  name: 'AlgoliaSearchBox',

  props: ['options'],

  data () {
    return {
      placeholder: undefined
    }
  },

  watch: {
    $lang (newValue) {
      this.update(this.options, newValue)
    },

    options (newValue) {
      this.update(newValue, this.$lang)
    }
  },

  mounted () {
    this.initialize(this.options, this.$lang)
    this.placeholder = this.$site.themeConfig.searchPlaceholder || ''
  },

  methods: {
    initialize (userOptions, lang) {
      Promise.all([
        import(/* webpackChunkName: "docsearch" */ 'docsearch.js/dist/cdn/docsearch.min.js'),
        import(/* webpackChunkName: "docsearch" */ 'docsearch.js/dist/cdn/docsearch.min.css')
      ]).then(([docsearch]) => {
        docsearch = docsearch.default
        const { algoliaOptions = {}} = userOptions
        docsearch(Object.assign(
          {},
          userOptions,
          {
            inputSelector: '#algolia-search-input',
            // #697 Make docsearch work well at i18n mode.
            algoliaOptions: {
              ...algoliaOptions,
              facetFilters: [`lang:${lang}`].concat(algoliaOptions.facetFilters || [])
            },
            handleSelected: (input, event, suggestion) => {
              const { pathname, hash } = new URL(suggestion.url)
              const routepath = pathname.replace(this.$site.base, '/')
              const _hash = decodeURIComponent(hash)
              this.$router.push(`${routepath}${_hash}`)
            }
          }
        ))
      })
    },

    update (options, lang) {
      this.$el.innerHTML = '<input id="algolia-search-input" class="search-query">'
      this.initialize(options, lang)
    }
  }
}
</script>

<style lang="stylus">
.algolia-search-wrapper
  & > span
    vertical-align middle
  .algolia-autocomplete
    line-height normal
    .ds-dropdown-menu
      background-color #fff
      border 1px solid #999
      border-radius 4px
      font-size 16px
      margin 6px 0 0
      padding 4px
      text-align left
      &:before
        border-color #999
      [class*=ds-dataset-]
        border none
        padding 0
      .ds-suggestions
        margin-top 0
      .ds-suggestion
        border-bottom 1px solid $borderColor
    .algolia-docsearch-suggestion--highlight
      color #2c815b
    .algolia-docsearch-suggestion
      border-color $borderColor
      padding 0
      .algolia-docsearch-suggestion--category-header
        padding 5px 10px
        margin-top 0
        background $accentColor
        color #fff
        font-weight 600
        .algolia-docsearch-suggestion--highlight
          background rgba(255, 255, 255, 0.6)
      .algolia-docsearch-suggestion--wrapper
        padding 0
      .algolia-docsearch-suggestion--title
        font-weight 600
        margin-bottom 0
        color $textColor
      .algolia-docsearch-suggestion--subcategory-column
        vertical-align top
        padding 5px 7px 5px 5px
        border-color $borderColor
        background #f1f3f5
        &:after
          display none
      .algolia-docsearch-suggestion--subcategory-column-text
        color #555
    .algolia-docsearch-footer
      border-color $borderColor
    .ds-cursor .algolia-docsearch-suggestion--content
      background-color #e7edf3 !important
      color $textColor

@media (min-width: $MQMobile)
  .algolia-search-wrapper
    .algolia-autocomplete
      .algolia-docsearch-suggestion
        .algolia-docsearch-suggestion--subcategory-column
          float none
          width 150px
          min-width 150px
          display table-cell
        .algolia-docsearch-suggestion--content
          float none
          display table-cell
          width 100%
          vertical-align top
        .ds-dropdown-menu
          min-width 515px !important

@media (max-width: $MQMobile)
  .algolia-search-wrapper
    .ds-dropdown-menu
      min-width calc(100vw - 4rem) !important
      max-width calc(100vw - 4rem) !important
    .algolia-docsearch-suggestion--wrapper
      padding 5px 7px 5px 5px !important
    .algolia-docsearch-suggestion--subcategory-column
      padding 0 !important
      background white !important
    .algolia-docsearch-suggestion--subcategory-column-text:after
      content " > "
      font-size 10px
      line-height 14.4px
      display inline-block
      width 5px
      margin -3px 3px 0
      vertical-align middle

</style>


================================================
FILE: docs/.vuepress/theme/components/DropdownLink.vue
================================================
<template>
  <div
    class="dropdown-wrapper"
    :class="{ open }"
  >
    <button
      class="dropdown-title"
      type="button"
      :aria-label="dropdownAriaLabel"
      @click="handleDropdown"
    >
      <span class="title">{{ item.text }}</span>
      <span
        class="arrow down"
      />
    </button>
    <button
      class="mobile-dropdown-title"
      type="button"
      :aria-label="dropdownAriaLabel"
      @click="setOpen(!open)"
    >
      <span class="title">{{ item.text }}</span>
      <span
        class="arrow"
        :class="open ? 'down' : 'right'"
      />
    </button>

    <DropdownTransition>
      <ul
        v-show="open"
        class="nav-dropdown"
      >
        <li
          v-for="(subItem, index) in item.items"
          :key="subItem.link || index"
          class="dropdown-item"
        >
          <h4 v-if="subItem.type === 'links'">
            {{ subItem.text }}
          </h4>

          <ul
            v-if="subItem.type === 'links'"
            class="dropdown-subitem-wrapper"
          >
            <li
              v-for="childSubItem in subItem.items"
              :key="childSubItem.link"
              class="dropdown-subitem"
            >
              <NavLink
                :item="childSubItem"
                @focusout="
                  isLastItemOfArray(childSubItem, subItem.items) &&
                    isLastItemOfArray(subItem, item.items) &&
                    setOpen(false)
                "
              />
            </li>
          </ul>

          <NavLink
            v-else
            :item="subItem"
            @focusout="isLastItemOfArray(subItem, item.items) && setOpen(false)"
          />
        </li>
      </ul>
    </DropdownTransition>
  </div>
</template>

<script>
import NavLink from '@theme/components/NavLink.vue'
import DropdownTransition from '@theme/components/DropdownTransition.vue'
import last from 'lodash/last'

export default {
  name: 'DropdownLink',

  components: {
    NavLink,
    DropdownTransition
  },

  props: {
    item: {
      required: true
    }
  },

  data () {
    return {
      open: false
    }
  },

  computed: {
    dropdownAriaLabel () {
      return this.item.ariaLabel || this.item.text
    }
  },

  watch: {
    $route () {
      this.open = false
    }
  },

  methods: {
    setOpen (value) {
      this.open = value
    },

    isLastItemOfArray (item, array) {
      return last(array) === item
    },

    /**
     * Open the dropdown when user tab and click from keyboard.
     *
     * Use event.detail to detect tab and click from keyboard. Ref: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
     * The Tab + Click is UIEvent > KeyboardEvent, so the detail is 0.
     */
    handleDropdown () {
      const isTriggerByTab = event.detail === 0
      if (isTriggerByTab) this.setOpen(!this.open)
    }
  }
}
</script>

<style lang="stylus">
.dropdown-wrapper
  cursor pointer
  .dropdown-title
    display block
    font-size 0.9rem
    font-family inherit
    cursor inherit
    padding inherit
    line-height 1.4rem
    background transparent
    border none
    font-weight 500
    color $textColor
    &:hover
      border-color transparent
    .arrow
      vertical-align middle
      margin-top -1px
      margin-left 0.4rem
  .mobile-dropdown-title
    @extends .dropdown-title
    display none
    font-weight 600
    font-size inherit
      &:hover
        color $accentColor
  .nav-dropdown
    .dropdown-item
      color inherit
      line-height 1.7rem
      h4
        margin 0.45rem 0 0
        border-top 1px solid #eee
        padding 1rem 1.5rem 0.45rem 1.25rem
      .dropdown-subitem-wrapper
        padding 0
        list-style none
        .dropdown-subitem
          font-size 0.9em
      a
        display block
        line-height 1.7rem
        position relative
        border-bottom none
        font-weight 400
        margin-bottom 0
        padding 0 1.5rem 0 1.25rem
        &:hover
          color $accentColor
        &.router-link-active
          color $accentColor
          &::after
            content ""
            width 0
            height 0
            border-left 5px solid $accentColor
            border-top 3px solid transparent
            border-bottom 3px solid transparent
            position absolute
            top calc(50% - 2px)
            left 9px
      &:first-child h4
        margin-top 0
        padding-top 0
        border-top 0

@media (max-width: $MQMobile)
  .dropdown-wrapper
    &.open .dropdown-title
      margin-bottom 0.5rem
    .dropdown-title
      display: none
    .mobile-dropdown-title
      display: block
    .nav-dropdown
      transition height .1s ease-out
      overflow hidden
      .dropdown-item
        h4
          border-top 0
          margin-top 0
          padding-top 0
        h4, & > a
          font-size 15px
          line-height 2rem
        .dropdown-subitem
          font-size 14px
          padding-left 1rem

@media (min-width: $MQMobile)
  .dropdown-wrapper
    height 1.8rem
    &:hover .nav-dropdown,
    &.open .nav-dropdown
      // override the inline style.
      display block !important
    &.open:blur
      display none
    .nav-dropdown
      display none
      // Avoid height shaked by clicking
      height auto !important
      box-sizing border-box;
      max-height calc(100vh - 2.7rem)
      overflow-y auto
      position absolute
      top 100%
      right 0
      background-color #fff
      padding 0.6rem 0
      border 1px solid #ddd
      border-bottom-color #ccc
      text-align left
      border-radius 0.25rem
      white-space nowrap
      margin 0
</style>


================================================
FILE: docs/.vuepress/theme/components/DropdownTransition.vue
================================================
<template>
  <transition
    name="dropdown"
    @enter="setHeight"
    @after-enter="unsetHeight"
    @before-leave="setHeight"
  >
    <slot />
  </transition>
</template>

<script>
export default {
  name: 'DropdownTransition',

  methods: {
    setHeight (items) {
      // explicitly set height so that it can be transitioned
      items.style.height = items.scrollHeight + 'px'
    },

    unsetHeight (items) {
      items.style.height = ''
    }
  }
}
</script>

<style lang="stylus">
.dropdown-enter, .dropdown-leave-to
  height 0 !important

</style>


================================================
FILE: docs/.vuepress/theme/components/Home.vue
================================================
<template>
  <main
    class="home"
    :aria-labelledby="data.heroText !== null ? 'main-title' : null"
  >
    <header class="hero">
      <img
        v-if="data.heroImage"
        :src="$withBase(data.heroImage)"
        :alt="data.heroAlt || 'hero'"
      >

      <h1
        v-if="data.heroText !== null"
        id="main-title"
      >
        {{ data.heroText || $title || 'Hello' }}
      </h1>

      <p
        v-if="data.tagline !== null"
        class="description"
      >
        {{ data.tagline || $description || 'Welcome to your VuePress site' }}
      </p>

      <p
        v-if="data.actionText && data.actionLink"
        class="action"
      >
        <NavLink
          class="action-button"
          :item="actionLink"
        />
      </p>
    </header>

    <div
      v-if="data.features && data.features.length"
      class="features"
    >
      <div
        v-for="(feature, index) in data.features"
        :key="index"
        class="feature"
      >
        <h2>{{ feature.title }}</h2>
        <p>{{ feature.details }}</p>
      </div>
    </div>

    <Content class="theme-default-content custom" />

    <div
      v-if="data.footer"
      class="footer"
    >
      {{ data.footer }}
    </div>
  </main>
</template>

<script>
import NavLink from '@theme/components/NavLink.vue'

export default {
  name: 'Home',

  components: { NavLink },

  computed: {
    data () {
      return this.$page.frontmatter
    },

    actionLink () {
      return {
        link: this.data.actionLink,
        text: this.data.actionText
      }
    }
  }
}
</script>

<style lang="stylus">
.home
  padding $navbarHeight 2rem 0
  max-width $homePageWidth
  margin 0px auto
  display block
  .hero
    text-align center
    img
      max-width: 100%
      max-height 280px
      display block
      margin 3rem auto 1.5rem
    h1
      font-size 3rem
    h1, .description, .action
      margin 1.8rem auto
    .description
      max-width 35rem
      font-size 1.6rem
      line-height 1.3
      color lighten($textColor, 40%)
    .action-button
      display inline-block
      font-size 1.2rem
      color #fff
      background-color $accentColor
      padding 0.8rem 1.6rem
      border-radius 4px
      transition background-color .1s ease
      box-sizing border-box
      border-bottom 1px solid darken($accentColor, 10%)
      &:hover
        background-color lighten($accentColor, 10%)
  .features
    border-top 1px solid $borderColor
    padding 1.2rem 0
    margin-top 2.5rem
    display flex
    flex-wrap wrap
    align-items flex-start
    align-content stretch
    justify-content space-between
  .feature
    flex-grow 1
    flex-basis 30%
    max-width 30%
    h2
      font-size 1.4rem
      font-weight 500
      border-bottom none
      padding-bottom 0
      color lighten($textColor, 10%)
    p
      color lighten($textColor, 25%)
  .footer
    padding 2.5rem
    border-top 1px solid $borderColor
    text-align center
    color lighten($textColor, 25%)

@media (max-width: $MQMobile)
  .home
    .features
      flex-direction column
    .feature
      max-width 100%
      padding 0 2.5rem

@media (max-width: $MQMobileNarrow)
  .home
    padding-left 1.5rem
    padding-right 1.5rem
    .hero
      img
        max-height 210px
        margin 2rem auto 1.2rem
      h1
        font-size 2rem
      h1, .description, .action
        margin 1.2rem auto
      .description
        font-size 1.2rem
      .action-button
        font-size 1rem
        padding 0.6rem 1.2rem
    .feature
      h2
        font-size 1.25rem
</style>


================================================
FILE: docs/.vuepress/theme/components/NavLink.vue
================================================
<template>
  <RouterLink
    v-if="isInternal"
    class="nav-link"
    :to="link"
    :exact="exact"
    @focusout.native="focusoutAction"
  >
    {{ item.text }}
  </RouterLink>
  <a
    v-else
    :href="link"
    class="nav-link external"
    :target="target"
    :rel="rel"
    @focusout="focusoutAction"
  >
    {{ item.text }}
    <OutboundLink v-if="isBlankTarget" />
  </a>
</template>

<script>
import { isExternal, isMailto, isTel, ensureExt } from '../util'

export default {
  name: 'NavLink',

  props: {
    item: {
      required: true
    }
  },

  computed: {
    link () {
      return ensureExt(this.item.link)
    },

    exact () {
      if (this.$site.locales) {
        return Object.keys(this.$site.locales).some(rootLink => rootLink === this.link)
      }
      return this.link === '/'
    },

    isNonHttpURI () {
      return isMailto(this.link) || isTel(this.link)
    },

    isBlankTarget () {
      return this.target === '_blank'
    },

    isInternal () {
      return !isExternal(this.link) && !this.isBlankTarget
    },

    target () {
      if (this.isNonHttpURI) {
        return null
      }
      if (this.item.target) {
        return this.item.target
      }
      return isExternal(this.link) ? '_blank' : ''
    },

    rel () {
      if (this.isNonHttpURI) {
        return null
      }
      if (this.item.rel === false) {
        return null
      }
      if (this.item.rel) {
        return this.item.rel
      }
      return this.isBlankTarget ? 'noopener noreferrer' : null
    }
  },

  methods: {
    focusoutAction () {
      this.$emit('focusout')
    }
  }
}
</script>


================================================
FILE: docs/.vuepress/theme/components/NavLinks.vue
================================================
<template>
  <nav
    v-if="userLinks.length || repoLink"
    class="nav-links"
  >
    <!-- user links -->
    <div
      v-for="item in userLinks"
      :key="item.link"
      class="nav-item"
    >
      <DropdownLink
        v-if="item.type === 'links'"
        :item="item"
      />
      <NavLink
        v-else
        :item="item"
      />
    </div>

    <GitHub/>
    </a>
  </nav>
</template>

<script>
import DropdownLink from '@theme/components/DropdownLink.vue'
import { resolveNavLinkItem } from '../util'
import NavLink from '@theme/components/NavLink.vue'

export default {
  name: 'NavLinks',

  components: {
    NavLink,
    DropdownLink
  },

  computed: {
    userNav () {
      return this.$themeLocaleConfig.nav || this.$site.themeConfig.nav || []
    },

    nav () {
      const { locales } = this.$site
      if (locales && Object.keys(locales).length > 1) {
        const currentLink = this.$page.path
        const routes = this.$router.options.routes
        const themeLocales = this.$site.themeConfig.locales || {}
        const languageDropdown = {
          text: this.$themeLocaleConfig.selectText || 'Languages',
          ariaLabel: this.$themeLocaleConfig.ariaLabel || 'Select language',
          items: Object.keys(locales).map(path => {
            const locale = locales[path]
            const text = themeLocales[path] && themeLocales[path].label || locale.lang
            let link
            // Stay on the current page
            if (locale.lang === this.$lang) {
              link = currentLink
            } else {
              // Try to stay on the same page
              link = currentLink.replace(this.$localeConfig.path, path)
              // fallback to homepage
              if (!routes.some(route => route.path === link)) {
                link = path
              }
            }
            return { text, link }
          })
        }
        return [...this.userNav, languageDropdown]
      }
      return this.userNav
    },

    userLinks () {
      return (this.nav || []).map(link => {
        return Object.assign(resolveNavLinkItem(link), {
          items: (link.items || []).map(resolveNavLinkItem)
        })
      })
    },

    repoLink () {
      const { repo } = this.$site.themeConfig
      if (repo) {
        return /^https?:/.test(repo)
          ? repo
          : `https://github.com/${repo}`
      }
      return null
    },

    repoLabel () {
      if (!this.repoLink) return
      if (this.$site.themeConfig.repoLabel) {
        return this.$site.themeConfig.repoLabel
      }

      const repoHost = this.repoLink.match(/^https?:\/\/[^/]+/)[0]
      const platforms = ['GitHub', 'GitLab', 'Bitbucket']
      for (let i = 0; i < platforms.length; i++) {
        const platform = platforms[i]
        if (new RegExp(platform, 'i').test(repoHost)) {
          return platform
        }
      }

      return 'Source'
    }
  }
}
</script>

<style lang="stylus">
.nav-links
  display inline-block
  a
    line-height 1.4rem
    color inherit
    &:hover, &.router-link-active
      color $accentColor
  .nav-item
    position relative
    display inline-block
    margin-left 1.5rem
    line-height 2rem
    &:first-child
      margin-left 0
  .repo-link
    margin-left 1.5rem

@media (max-width: $MQMobile)
  .nav-links
    .nav-item, .repo-link
      margin-left 0

@media (min-width: $MQMobile)
  .nav-links a
    &:hover, &.router-link-active
      color $textColor
  .nav-item > a:not(.external)
    &:hover, &.router-link-active
      margin-bottom -2px
      border-bottom 2px solid lighten($accentColor, 8%)
</style>


================================================
FILE: docs/.vuepress/theme/components/Navbar.vue
================================================
<template>
  <header class="navbar">
    <SidebarButton @toggle-sidebar="$emit('toggle-sidebar')" />

    <RouterLink
      :to="$localePath"
      class="home-link"
    >
      <img
        v-if="$site.themeConfig.logo"
        class="logo"
        :src="$withBase($site.themeConfig.logo)"
        :alt="$siteTitle"
      >
      <span
        v-if="$siteTitle"
        ref="siteName"
        class="site-name"
        :class="{ 'can-hide': $site.themeConfig.logo }"
      >{{ $siteTitle }}</span>
    </RouterLink>

    <div
      class="links"
      :style="linksWrapMaxWidth ? {
        'max-width': linksWrapMaxWidth + 'px'
      } : {}"
    >
      <AlgoliaSearchBox
        v-if="isAlgoliaSearch"
        :options="algolia"
      />
      <SearchBox v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false" />
      <NavLinks class="can-hide" />
    </div>
  </header>
</template>

<script>
import AlgoliaSearchBox from '@AlgoliaSearchBox'
import SearchBox from '@SearchBox'
import SidebarButton from '@theme/components/SidebarButton.vue'
import NavLinks from '@theme/components/NavLinks.vue'

export default {
  name: 'Navbar',

  components: {
    SidebarButton,
    NavLinks,
    SearchBox,
    AlgoliaSearchBox
  },

  data () {
    return {
      linksWrapMaxWidth: null
    }
  },

  computed: {
    algolia () {
      return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
    },

    isAlgoliaSearch () {
      return this.algolia && this.algolia.apiKey && this.algolia.indexName
    }
  },

  mounted () {
    const MOBILE_DESKTOP_BREAKPOINT = 719 // refer to config.styl
    const NAVBAR_VERTICAL_PADDING = parseInt(css(this.$el, 'paddingLeft')) + parseInt(css(this.$el, 'paddingRight'))
    const handleLinksWrapWidth = () => {
      if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
        this.linksWrapMaxWidth = null
      } else {
        this.linksWrapMaxWidth = this.$el.offsetWidth - NAVBAR_VERTICAL_PADDING
          - (this.$refs.siteName && this.$refs.siteName.offsetWidth || 0)
      }
    }
    handleLinksWrapWidth()
    window.addEventListener('resize', handleLinksWrapWidth, false)
  }
}

function css (el, property) {
  // NOTE: Known bug, will return 'auto' if style value is 'auto'
  const win = el.ownerDocument.defaultView
  // null means not to return pseudo styles
  return win.getComputedStyle(el, null)[property]
}
</script>

<style lang="stylus">
$navbar-vertical-padding = 0.7rem
$navbar-horizontal-padding = 1.5rem

.navbar
  padding $navbar-vertical-padding $navbar-horizontal-padding
  line-height $navbarHeight - 1.4rem
  a, span, img
    display inline-block
  .logo
    height $navbarHeight - 1.4rem
    min-width $navbarHeight - 1.4rem
    margin-right 0.8rem
    vertical-align top
  .site-name
    font-size 1.3rem
    font-weight 600
    color $textColor
    position relative
  .links
    padding-left 1.5rem
    box-sizing border-box
    background-color white
    white-space nowrap
    font-size 0.9rem
    position absolute
    right $navbar-horizontal-padding
    top $navbar-vertical-padding
    display flex
    .search-box
      flex: 0 0 auto
      vertical-align top

@media (max-width: $MQMobile)
  .navbar
    padding-left 4rem
    .can-hide
      display none
    .links
      padding-left 1.5rem
    .site-name
      width calc(100vw - 9.4rem)
      overflow hidden
      white-space nowrap
      text-overflow ellipsis
</style>


================================================
FILE: docs/.vuepress/theme/components/Page.vue
================================================
<template>
  <main class="page">
    <slot name="top" />

    <Content class="theme-default-content" />
    <PageEdit />

    <PageNav v-bind="{ sidebarItems }" />

    <slot name="bottom" />
  </main>
</template>

<script>
import PageEdit from '@theme/components/PageEdit.vue'
import PageNav from '@theme/components/PageNav.vue'

export default {
  components: { PageEdit, PageNav },
  props: ['sidebarItems']
}
</script>

<style lang="stylus">
@require '../styles/wrapper.styl'

.page
  padding-bottom 2rem
  display block

</style>


================================================
FILE: docs/.vuepress/theme/components/PageEdit.vue
================================================
<template>
  <footer class="page-edit">
    <div
      v-if="editLink"
      class="edit-link"
    >
      <a
        :href="editLink"
        target="_blank"
        rel="noopener noreferrer"
      >{{ editLinkText }}</a>
      <OutboundLink />
    </div>

    <div
      v-if="lastUpdated"
      class="last-updated"
    >
      <span class="prefix">{{ lastUpdatedText }}:</span>
      <span class="time">{{ lastUpdated }}</span>
    </div>
  </footer>
</template>

<script>
import isNil from 'lodash/isNil'
import { endingSlashRE, outboundRE } from '../util'

export default {
  name: 'PageEdit',

  computed: {
    lastUpdated () {
      return this.$page.lastUpdated
    },

    lastUpdatedText () {
      if (typeof this.$themeLocaleConfig.lastUpdated === 'string') {
        return this.$themeLocaleConfig.lastUpdated
      }
      if (typeof this.$site.themeConfig.lastUpdated === 'string') {
        return this.$site.themeConfig.lastUpdated
      }
      return 'Last Updated'
    },

    editLink () {
      const showEditLink = isNil(this.$page.frontmatter.editLink)
        ? this.$site.themeConfig.editLinks
        : this.$page.frontmatter.editLink

      const {
        repo,
        docsDir = '',
        docsBranch = 'master',
        docsRepo = repo
      } = this.$site.themeConfig

      if (typeof showEditLink == "string") return showEditLink

      if (showEditLink && docsRepo && this.$page.relativePath) {
        return this.createEditLink(
          repo,
          docsRepo,
          docsDir,
          docsBranch,
          this.$page.relativePath
        )
      }
      return null
    },

    editLinkText () {
      return (
        this.$themeLocaleConfig.editLinkText
        || this.$site.themeConfig.editLinkText
        || `Edit this page`
      )
    }
  },

  methods: {
    createEditLink (repo, docsRepo, docsDir, docsBranch, path) {
      const bitbucket = /bitbucket.org/
      if (bitbucket.test(docsRepo)) {
        const base = docsRepo
        return (
          base.replace(endingSlashRE, '')
          + `/src`
          + `/${docsBranch}/`
          + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '')
          + path
          + `?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
        )
      }

      const gitlab = /gitlab.com/
      if (gitlab.test(docsRepo)) {
        const base = docsRepo
        return (
          base.replace(endingSlashRE, '')
          + `/-/edit`
          + `/${docsBranch}/`
          + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '')
          + path
        )
      }

      const base = outboundRE.test(docsRepo)
        ? docsRepo
        : `https://github.com/${docsRepo}`
      return (
        base.replace(endingSlashRE, '')
        + '/edit'
        + `/${docsBranch}/`
        + (docsDir ? docsDir.replace(endingSlashRE, '') + '/' : '')
        + path
      )
    }
  }
}
</script>

<style lang="stylus">
@require '../styles/wrapper.styl'

.page-edit
  @extend $wrapper
  padding-top 1rem
  padding-bottom 1rem
  overflow auto

  .edit-link
    display inline-block
    a
      color lighten($textColor, 25%)
      margin-right 0.25rem
  .last-updated
    float right
    font-size 0.9em
    .prefix
      font-weight 500
      color lighten($textColor, 25%)
    .time
      font-weight 400
      color #767676

@media (max-width: $MQMobile)
  .page-edit
    .edit-link
      margin-bottom 0.5rem
    .last-updated
      font-size 0.8em
      float none
      text-align left

</style>


================================================
FILE: docs/.vuepress/theme/components/PageNav.vue
================================================
<template>
  <div
    v-if="prev || next"
    class="page-nav"
  >
    <p class="inner">
      <span
        v-if="prev"
        class="prev"
      >
        ←
        <a
          v-if="prev.type === 'external'"
          class="prev"
          :href="prev.path"
          target="_blank"
          rel="noopener noreferrer"
        >
          {{ prev.title || prev.path }}

          <OutboundLink />
        </a>

        <RouterLink
          v-else
          class="prev"
          :to="prev.path"
        >
          {{ prev.title || prev.path }}
        </RouterLink>
      </span>

      <span
        v-if="next"
        class="next"
      >
        <a
          v-if="next.type === 'external'"
          :href="next.path"
          target="_blank"
          rel="noopener noreferrer"
        >
          {{ next.title || next.path }}

          <OutboundLink />
        </a>

        <RouterLink
          v-else
          :to="next.path"
        >
          {{ next.title || next.path }}
        </RouterLink>
        →
      </span>
    </p>
  </div>
</template>

<script>
import { resolvePage } from '../util'
import isString from 'lodash/isString'
import isNil from 'lodash/isNil'

export default {
  name: 'PageNav',

  props: ['sidebarItems'],

  computed: {
    prev () {
      return resolvePageLink(LINK_TYPES.PREV, this)
    },

    next () {
      return resolvePageLink(LINK_TYPES.NEXT, this)
    }
  }
}

function resolvePrev (page, items) {
  return find(page, items, -1)
}

function resolveNext (page, items) {
  return find(page, items, 1)
}

const LINK_TYPES = {
  NEXT: {
    resolveLink: resolveNext,
    getThemeLinkConfig: ({ nextLinks }) => nextLinks,
    getPageLinkConfig: ({ frontmatter }) => frontmatter.next
  },
  PREV: {
    resolveLink: resolvePrev,
    getThemeLinkConfig: ({ prevLinks }) => prevLinks,
    getPageLinkConfig: ({ frontmatter }) => frontmatter.prev
  }
}

function resolvePageLink (
  linkType,
  { $themeConfig, $page, $route, $site, sidebarItems }
) {
  const { resolveLink, getThemeLinkConfig, getPageLinkConfig } = linkType

  // Get link config from theme
  const themeLinkConfig = getThemeLinkConfig($themeConfig)

  // Get link config from current page
  const pageLinkConfig = getPageLinkConfig($page)

  // Page link config will overwrite global theme link config if defined
  const link = isNil(pageLinkConfig) ? themeLinkConfig : pageLinkConfig

  if (link === false) {
    return
  } else if (isString(link)) {
    return resolvePage($site.pages, link, $route.path)
  } else {
    return resolveLink($page, sidebarItems)
  }
}

function find (page, items, offset) {
  const res = []
  flatten(items, res)
  for (let i = 0; i < res.length; i++) {
    const cur = res[i]
    if (cur.type === 'page' && cur.path === decodeURIComponent(page.path)) {
      return res[i + offset]
    }
  }
}

function flatten (items, res) {
  for (let i = 0, l = items.length; i < l; i++) {
    if (items[i].type === 'group') {
      flatten(items[i].children || [], res)
    } else {
      res.push(items[i])
    }
  }
}
</script>

<style lang="stylus">
@require '../styles/wrapper.styl'

.page-nav
  @extend $wrapper
  padding-top 1rem
  padding-bottom 0
  .inner
    min-height 2rem
    margin-top 0
    border-top 1px solid $borderColor
    padding-top 1rem
    overflow auto // clear float
  .next
    float right
</style>


================================================
FILE: docs/.vuepress/theme/components/Sidebar.vue
================================================
<template>
  <aside class="sidebar">
    <NavLinks />

    <slot name="top" />

    <SidebarLinks
      :depth="0"
      :items="items"
    />
    <slot name="bottom" />
  </aside>
</template>

<script>
import SidebarLinks from '@theme/components/SidebarLinks.vue'
import NavLinks from '@theme/components/NavLinks.vue'

export default {
  name: 'Sidebar',

  components: { SidebarLinks, NavLinks },

  props: ['items']
}
</script>

<style lang="stylus">
.sidebar
  ul
    padding 0
    margin 0
    list-style-type none
  a
    display inline-block
  .nav-links
    display none
    border-bottom 1px solid $borderColor
    padding 0.5rem 0 0.75rem 0
    a
      font-weight 600
    .nav-item, .repo-link
      display block
      line-height 1.25rem
      font-size 1.1em
      padding 0.5rem 0 0.5rem 1.5rem
  & > .sidebar-links
    padding 1.5rem 0
    & > li > a.sidebar-link
      font-size 1.1em
      line-height 1.7
      font-weight bold
    & > li:not(:first-child)
      margin-top .75rem

@media (max-width: $MQMobile)
  .sidebar
    .nav-links
      display block
      .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after
        top calc(1rem - 2px)
    & > .sidebar-links
      padding 1rem 0
</style>


================================================
FILE: docs/.vuepress/theme/components/SidebarButton.vue
================================================
<template>
  <div
    class="sidebar-button"
    @click="$emit('toggle-sidebar')"
  >
    <svg
      class="icon"
      xmlns="http://www.w3.org/2000/svg"
      aria-hidden="true"
      role="img"
      viewBox="0 0 448 512"
    >
      <path
        fill="currentColor"
        d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
        class=""
      />
    </svg>
  </div>
</template>

<style lang="stylus">
.sidebar-button
  cursor pointer
  display none
  width 1.25rem
  height 1.25rem
  position absolute
  padding 0.6rem
  top 0.6rem
  left 1rem
  .icon
    display block
    width 1.25rem
    height 1.25rem

@media (max-width: $MQMobile)
  .sidebar-button
    display block
</style>


================================================
FILE: docs/.vuepress/theme/components/SidebarGroup.vue
================================================
<template>
  <section
    class="sidebar-group"
    :class="[
      {
        collapsable,
        'is-sub-group': depth !== 0
      },
      `depth-${depth}`
    ]"
  >
    <RouterLink
      v-if="item.path"
      class="sidebar-heading clickable"
      :class="{
        open,
        'active': isActive($route, item.path)
      }"
      :to="item.path"
      @click.native="$emit('toggle')"
    >
      <span>{{ item.title }}</span>
      <span
        v-if="collapsable"
        class="arrow"
        :class="open ? 'down' : 'right'"
      />
    </RouterLink>

    <p
      v-else
      class="sidebar-heading"
      :class="{ open }"
      @click="$emit('toggle')"
    >
      <span>{{ item.title }}</span>
      <span
        v-if="collapsable"
        class="arrow"
        :class="open ? 'down' : 'right'"
      />
    </p>

    <DropdownTransition>
      <SidebarLinks
        v-if="open || !collapsable"
        class="sidebar-group-items"
        :items="item.children"
        :sidebar-depth="item.sidebarDepth"
        :initial-open-group-index="item.initialOpenGroupIndex"
        :depth="depth + 1"
      />
    </DropdownTransition>
  </section>
</template>

<script>
import { isActive } from '../util'
import DropdownTransition from '@theme/components/DropdownTransition.vue'

export default {
  name: 'SidebarGroup',

  components: {
    DropdownTransition
  },

  props: [
    'item',
    'open',
    'collapsable',
    'depth'
  ],

  // ref: https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components
  beforeCreate () {
    this.$options.components.SidebarLinks = require('@theme/components/SidebarLinks.vue').default
  },

  methods: { isActive }
}
</script>

<style lang="stylus">
.sidebar-group
  .sidebar-group
    padding-left 0.5em
  &:not(.collapsable)
    .sidebar-heading:not(.clickable)
      cursor auto
      color inherit
  // refine styles of nested sidebar groups
  &.is-sub-group
    padding-left 0
    & > .sidebar-heading
      font-size 0.95em
      line-height 1.4
      font-weight normal
      padding-left 2rem
      &:not(.clickable)
        opacity 0.5
    & > .sidebar-group-items
      padding-left 1rem
      & > li > .sidebar-link
        font-size: 0.95em;
        border-left none
  &.depth-2
    & > .sidebar-heading
      border-left none

.sidebar-heading
  color $textColor
  transition color .15s ease
  cursor pointer
  font-size 1.1em
  font-weight bold
  // text-transform uppercase
  padding 0.35rem 1.5rem 0.35rem 1.25rem
  width 100%
  box-sizing border-box
  margin 0
  border-left 0.25rem solid transparent
  &.open, &:hover
    color inherit
  .arrow
    position relative
    top -0.12em
    left 0.5em
  &.clickable
    &.active
      font-weight 600
      color $accentColor
      border-left-color $accentColor
    &:hover
      color $accentColor

.sidebar-group-items
  transition height .1s ease-out
  font-size 0.95em
  overflow hidden
</style>


================================================
FILE: docs/.vuepress/theme/components/SidebarLink.vue
================================================
<script>
import { isActive, hashRE, groupHeaders } from '../util'

export default {
  functional: true,

  props: ['item', 'sidebarDepth'],

  render (h,
    {
      parent: {
        $page,
        $site,
        $route,
        $themeConfig,
        $themeLocaleConfig
      },
      props: {
        item,
        sidebarDepth
      }
    }) {
    // use custom active class matching logic
    // due to edge case of paths ending with / + hash
    const selfActive = isActive($route, item.path)
    // for sidebar: auto pages, a hash link should be active if one of its child
    // matches
    const active = item.type === 'auto'
      ? selfActive || item.children.some(c => isActive($route, item.basePath + '#' + c.slug))
      : selfActive
    const link = item.type === 'external'
      ? renderExternal(h, item.path, item.title || item.path)
      : renderLink(h, item.path, item.title || item.path, active)

    const maxDepth = [
      $page.frontmatter.sidebarDepth,
      sidebarDepth,
      $themeLocaleConfig.sidebarDepth,
      $themeConfig.sidebarDepth,
      1
    ].find(depth => depth !== undefined)

    const displayAllHeaders = $themeLocaleConfig.displayAllHeaders
      || $themeConfig.displayAllHeaders

    if (item.type === 'auto') {
      return [link, renderChildren(h, item.children, item.basePath, $route, maxDepth)]
    } else if ((active || displayAllHeaders) && item.headers && !hashRE.test(item.path)) {
      const children = groupHeaders(item.headers)
      return [link, renderChildren(h, children, item.path, $route, maxDepth)]
    } else {
      return link
    }
  }
}

function renderLink (h, to, text, active, level) {
  const component = {
    props: {
      to,
      activeClass: '',
      exactActiveClass: ''
    },
    class: {
      active,
      'sidebar-link': true
    }
  }

  if (level > 2) {
    component.style = {
      'padding-left': level + 'rem'
    }
  }

  return h('RouterLink', component, text)
}

function renderChildren (h, children, path, route, maxDepth, depth = 1) {
  if (!children || depth > maxDepth) return null
  return h('ul', { class: 'sidebar-sub-headers' }, children.map(c => {
    const active = isActive(route, path + '#' + c.slug)
    return h('li', { class: 'sidebar-sub-header' }, [
      renderLink(h, path + '#' + c.slug, c.title, active, c.level - 1),
      renderChildren(h, c.children, path, route, maxDepth, depth + 1)
    ])
  }))
}

function renderExternal (h, to, text) {
  return h('a', {
    attrs: {
      href: to,
      target: '_blank',
      rel: 'noopener noreferrer'
    },
    class: {
      'sidebar-link': true
    }
  }, [text, h('OutboundLink')])
}
</script>

<style lang="stylus">
.sidebar .sidebar-sub-headers
  padding-left 1rem
  font-size 0.95em

a.sidebar-link
  font-size 1em
  font-weight 400
  display inline-block
  color $textColor
  border-left 0.25rem solid transparent
  padding 0.35rem 1rem 0.35rem 1.25rem
  line-height 1.4
  width: 100%
  box-sizing: border-box
  &:hover
    color $accentColor
  &.active
    font-weight 600
    color $accentColor
    border-left-color $accentColor
  .sidebar-group &
    padding-left 2rem
  .sidebar-sub-headers &
    padding-top 0.25rem
    padding-bottom 0.25rem
    border-left none
    &.active
      font-weight 500
</style>


================================================
FILE: docs/.vuepress/theme/components/SidebarLinks.vue
================================================
<template>
  <ul
    v-if="items.length"
    class="sidebar-links"
  >
    <li
      v-for="(item, i) in items"
      :key="i"
    >
      <SidebarGroup
        v-if="item.type === 'group'"
        :item="item"
        :open="i === openGroupIndex"
        :collapsable="item.collapsable || item.collapsible"
        :depth="depth"
        @toggle="toggleGroup(i)"
      />
      <SidebarLink
        v-else
        :sidebar-depth="sidebarDepth"
        :item="item"
      />
    </li>
  </ul>
</template>

<script>
import SidebarGroup from '@theme/components/SidebarGroup.vue'
import SidebarLink from '@theme/components/SidebarLink.vue'
import { isActive } from '../util'

export default {
  name: 'SidebarLinks',

  components: { SidebarGroup, SidebarLink },

  props: [
    'items',
    'depth',  // depth of current sidebar links
    'sidebarDepth', // depth of headers to be extracted
    'initialOpenGroupIndex'
  ],

  data () {
    return {
      openGroupIndex: this.initialOpenGroupIndex || 0
    }
  },

  watch: {
    '$route' () {
      this.refreshIndex()
    }
  },

  created () {
    this.refreshIndex()
  },

  methods: {
    refreshIndex () {
      const index = resolveOpenGroupIndex(
        this.$route,
        this.items
      )
      if (index > -1) {
        this.openGroupIndex = index
      }
    },

    toggleGroup (index) {
      this.openGroupIndex = index === this.openGroupIndex ? -1 : index
    },

    isActive (page) {
      return isActive(this.$route, page.regularPath)
    }
  }
}

function resolveOpenGroupIndex (route, items) {
  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    if (descendantIsActive(route, item)) {
      return i
    }
  }
  return -1
}

function descendantIsActive (route, item) {
  if (item.type === 'group') {
    const childIsActive = item.path && isActive(route, item.path)
    const grandChildIsActive = item.children.some(child => {
      if (child.type === 'group') {
        return descendantIsActive(route, child)
      } else {
        return child.type === 'page' && isActive(route, child.path)
      }
    })

    return childIsActive || grandChildIsActive
  }
  return false
}
</script>


================================================
FILE: docs/.vuepress/theme/global-components/Badge.vue
================================================
<script>
export default {
  functional: true,
  props: {
    type: {
      type: String,
      default: 'tip'
    },
    text: String,
    vertical: {
      type: String,
      default: 'top'
    }
  },
  render (h, { props, slots }) {
    return h('span', {
      class: ['badge', props.type],
      style: {
        verticalAlign: props.vertical
      }
    }, props.text || slots().default)
  }
}
</script>

<style lang="stylus" scoped>
.badge
  display inline-block
  font-size 14px
  height 18px
  line-height 18px
  border-radius 3px
  padding 0 6px
  color white
  background-color #42b983
  &.tip, &.green
    background-color $badgeTipColor
  &.error
    background-color $badgeErrorColor
  &.warning, &.warn, &.yellow
    background-color $badgeWarningColor
  & + &
    margin-left 5px
</style>


================================================
FILE: docs/.vuepress/theme/global-components/CodeBlock.vue
================================================
<template>
  <div
    class="theme-code-block"
    :class="{ 'theme-code-block__active': active }"
  >
    <slot />
  </div>
</template>

<script>
export default {
  name: 'CodeBlock',
  props: {
    title: {
      type: String,
      required: true
    },
    active: {
      type: Boolean,
      default: false
    }
  },
  mounted () {
    if (this.$parent && this.$parent.loadTabs) {
      this.$parent.loadTabs()
    }
  }
}
</script>

<style scoped>
  .theme-code-block {
    display: none;
  }
  .theme-code-block__active {
    display: block;
  }
  .theme-code-block > pre {
    background-color: orange;
  }
</style>


================================================
FILE: docs/.vuepress/theme/global-components/CodeGroup.vue
================================================
<template>
  <ClientOnly>
    <div class="theme-code-group">
      <div class="theme-code-group__nav">
        <ul class="theme-code-group__ul">
          <li
            v-for="(tab, i) in codeTabs"
            :key="tab.title"
            class="theme-code-group__li"
          >
            <button
              class="theme-code-group__nav-tab"
              :class="{
                'theme-code-group__nav-tab-active': i === activeCodeTabIndex,
              }"
              @click="changeCodeTab(i)"
            >
              {{ tab.title }}
            </button>
          </li>
        </ul>
      </div>
      <slot />
      <pre
        v-if="codeTabs.length < 1"
        class="pre-blank"
      >// Make sure to add code blocks to your code group</pre>
    </div>
  </ClientOnly>
</template>

<script>
export default {
  name: 'CodeGroup',
  data () {
    return {
      codeTabs: [],
      activeCodeTabIndex: -1
    }
  },
  watch: {
    activeCodeTabIndex (index) {
      this.activateCodeTab(index)
    }
  },
  mounted () {
    this.loadTabs()
  },
  methods: {
    changeCodeTab (index) {
      this.activeCodeTabIndex = index
    },
    loadTabs () {
      this.codeTabs = (this.$slots.default || []).filter(slot => Boolean(slot.componentOptions)).map((slot, index) => {
        if (slot.componentOptions.propsData.active === '') {
          this.activeCodeTabIndex = index
        }

        return {
          title: slot.componentOptions.propsData.title,
          elm: slot.elm
        }
      })

      if (this.activeCodeTabIndex === -1 && this.codeTabs.length > 0) {
        this.activeCodeTabIndex = 0
      }

      this.activateCodeTab(0)
    },
    activateCodeTab (index) {
      this.codeTabs.forEach(tab => {
        if (tab.elm) {
          tab.elm.classList.remove('theme-code-block__active')
        }
      })

      if (this.codeTabs[index].elm) {
        this.codeTabs[index].elm.classList.add('theme-code-block__active')
      }
    }
  }
}
</script>

<style lang="stylus" scoped>
  .theme-code-group {}
  .theme-code-group__nav {
    margin-bottom: -35px;
    background-color: $codeBgColor;
    padding-bottom: 22px;
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    padding-left: 10px;
    padding-top: 10px;
  }
  .theme-code-group__ul {
    margin: auto 0;
    padding-left: 0;
    display: inline-flex;
    list-style: none;
  }
  .theme-code-group__li {}
  .theme-code-group__nav-tab {
    border: 0;
    padding: 5px;
    cursor: pointer;
    background-color: transparent;
    font-size: 0.85em;
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.9);
    font-weight: 600;
  }
  .theme-code-group__nav-tab-active {
    border-bottom: #42b983 1px solid;
  }
  .pre-blank {
    color: #42b983;
  }
</style>


================================================
FILE: docs/.vuepress/theme/index.js
================================================
const path = require("path")

// Theme API.
module.exports = (options, ctx) => {
  const {themeConfig, siteConfig} = ctx

  // resolve algolia
  const isAlgoliaSearch =
    themeConfig.algolia ||
    Object.keys((siteConfig.locales && themeConfig.locales) || {}).some(
      (base) => themeConfig.locales[base].algolia
    )

  const enableSmoothScroll = themeConfig.smoothScroll === true

  return {
    alias() {
      return {
        "@AlgoliaSearchBox": isAlgoliaSearch
          ? path.resolve(__dirname, "components/AlgoliaSearchBox.vue")
          : path.resolve(__dirname, "noopModule.js"),
      }
    },

    plugins: [
      ["@vuepress/active-header-links", options.activeHeaderLinks],
      "@vuepress/search",
      "@vuepress/plugin-nprogress",
      [
        "container",
        {
          type: "tip",
          defaultTitle: {
            "/": "TIP",
            "/zh/": "提示",
          },
        },
      ],
      [
        "container",
        {
          type: "warning",
          defaultTitle: {
            "/": "WARNING",
            "/zh/": "注意",
          },
        },
      ],
      [
        "container",
        {
          type: "danger",
          defaultTitle: {
            "/": "WARNING",
            "/zh/": "警告",
          },
        },
      ],
      [
        "container",
        {
          type: "details",
          before: (info) =>
            `<details class="custom-block details">${info ? `<summary>${info}</summary>` : ""}\n`,
          after: () => "</details>\n",
        },
      ],
      ["smooth-scroll", enableSmoothScroll],
    ],
  }
}


================================================
FILE: docs/.vuepress/theme/layouts/404.vue
================================================
<template>
  <div class="theme-container">
    <div class="theme-default-content">
      <h1>404</h1>

      <blockquote>{{ getMsg() }}</blockquote>

      <RouterLink to="/">
        Take me home.
      </RouterLink>
    </div>
  </div>
</template>

<script>
const msgs = [
  `There's nothing here.`,
  `How did we get here?`,
  `That's a Four-Oh-Four.`,
  `Looks like we've got some broken links.`
]

export default {
  methods: {
    getMsg () {
      return msgs[Math.floor(Math.random() * msgs.length)]
    }
  }
}
</script>


================================================
FILE: docs/.vuepress/theme/layouts/Layout.vue
================================================
<template>
  <div
    class="theme-container"
    :class="pageClasses"
    @touchstart="onTouchStart"
    @touchend="onTouchEnd"
  >
    <Navbar
      v-if="shouldShowNavbar"
      @toggle-sidebar="toggleSidebar"
    />

    <div
      class="sidebar-mask"
      @click="toggleSidebar(false)"
    />

    <Sidebar
      :items="sidebarItems"
      @toggle-sidebar="toggleSidebar"
    >
      <template #top>
        <slot name="sidebar-top" />
      </template>
      <template #bottom>
        <slot name="sidebar-bottom" />
      </template>
    </Sidebar>

    <HomePage
      v-if="$page.frontmatter.homepage"
      :sidebar-items="sidebarItems"
    >
      <template #top>
        <slot name="page-top" />
      </template>
      <template #bottom>
        <slot name="page-bottom" />
      </template>
    </HomePage>

    <NewsPost
      v-else-if="$page.frontmatter.news"
      :sidebar-items="sidebarItems"
    >
      <template #top>
        <slot name="page-top" />
      </template>
      <template #bottom>
        <slot name="page-bottom" />
      </template>
    </NewsPost>

    <Page
      v-else
      :sidebar-items="sidebarItems"
    >
      <template #top>
        <slot name="page-top" />
      </template>
      <template #bottom>
        <slot name="page-bottom" />
      </template>
    </Page>
  </div>
</template>

<script>
import Home from '@theme/components/Home.vue'
import Navbar from '@theme/components/Navbar.vue'
import Page from '@theme/components/Page.vue'
import Sidebar from '@theme/components/Sidebar.vue'
import { resolveSidebarItems } from '../util'

export default {
  name: 'Layout',

  components: {
    Home,
    Page,
    Sidebar,
    Navbar
  },

  data () {
    return {
      isSidebarOpen: false
    }
  },

  computed: {
    shouldShowNavbar () {
      const { themeConfig } = this.$site
      const { frontmatter } = this.$page
      if (
        frontmatter.navbar === false
        || themeConfig.navbar === false) {
        return false
      }
      return (
        this.$title
        || themeConfig.logo
        || themeConfig.repo
        || themeConfig.nav
        || this.$themeLocaleConfig.nav
      )
    },

    shouldShowSidebar () {
      const { frontmatter } = this.$page
      return (
        !frontmatter.home
        && frontmatter.sidebar !== false
        && this.sidebarItems.length
      )
    },

    sidebarItems () {
      return resolveSidebarItems(
        this.$page,
        this.$page.regularPath,
        this.$site,
        this.$localePath
      )
    },

    pageClasses () {
      const userPageClass = this.$page.frontmatter.pageClass
      return [
        {
          'no-navbar': !this.shouldShowNavbar,
          'sidebar-open': this.isSidebarOpen,
          'no-sidebar': !this.shouldShowSidebar
        },
        userPageClass
      ]
    }
  },

  mounted () {
    this.$router.afterEach(() => {
      this.isSidebarOpen = false
    })
  },

  methods: {
    toggleSidebar (to) {
      this.isSidebarOpen = typeof to === 'boolean' ? to : !this.isSidebarOpen
      this.$emit('toggle-sidebar', this.isSidebarOpen)
    },

    // side swipe
    onTouchStart (e) {
      this.touchStart = {
        x: e.changedTouches[0].clientX,
        y: e.changedTouches[0].clientY
      }
    },

    onTouchEnd (e) {
      const dx = e.changedTouches[0].clientX - this.touchStart.x
      const dy = e.changedTouches[0].clientY - this.touchStart.y
      if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
        if (dx > 0 && this.touchStart.x <= 80) {
          this.toggleSidebar(true)
        } else {
          this.toggleSidebar(false)
        }
      }
    }
  }
}
</script>


================================================
FILE: docs/.vuepress/theme/noopModule.js
================================================
export default {}


================================================
FILE: docs/.vuepress/theme/styles/arrow.styl
================================================
@require './config'

.arrow
  display inline-block
  width 0
  height 0
  &.up
    border-left 4px solid transparent
    border-right 4px solid transparent
    border-bottom 6px solid $arrowBgColor
  &.down
    border-left 4px solid transparent
    border-right 4px solid transparent
    border-top 6px solid $arrowBgColor
  &.right
    border-top 4px solid transparent
    border-bottom 4px solid transparent
    border-left 6px solid $arrowBgColor
  &.left
    border-top 4px solid transparent
    border-bottom 4px solid transparent
    border-right 6px solid $arrowBgColor


================================================
FILE: docs/.vuepress/theme/styles/code.styl
================================================
{$contentClass}
  code
    color lighten($textColor, 20%)
    padding 0.25rem 0.5rem
    margin 0
    font-size 0.85em
    background-color rgba(27,31,35,0.05)
    border-radius 3px
    .token
      &.deleted
        color #EC5975
      &.inserted
        color $accentColor

{$contentClass}
  pre, pre[class*="language-"]
    line-height 1.4
    padding 1.25rem 1.5rem
    margin 0.85rem 0
    background-color $codeBgColor
    border-radius 6px
    overflow auto
    code
      color #fff
      padding 0
      background-color transparent
      border-radius 0

div[class*="language-"]
  position relative
  background-color $codeBgColor
  border-radius 6px
  .highlight-lines
    user-select none
    padding-top 1.3rem
    position absolute
    top 0
    left 0
    width 100%
    line-height 1.4
    .highlighted
      background-color rgba(0, 0, 0, 66%)
  pre, pre[class*="language-"]
    background transparent
    position relative
    z-index 1
  &::before
    position absolute
    z-index 3
    top 0.8em
    right 1em
    font-size 0.75rem
    color rgba(255, 255, 255, 0.4)
  &:not(.line-numbers-mode)
    .line-numbers-wrapper
      display none
  &.line-numbers-mode
    .highlight-lines .highlighted
        position relative
        &:before
          content ' '
          position absolute
          z-index 3
          left 0
          top 0
          display block
          width $lineNumbersWrapperWidth
          height 100%
          background-color rgba(0, 0, 0, 66%)
    pre
      padding-left $lineNumbersWrapperWidth + 1 rem
      vertical-align middle
    .line-numbers-wrapper
      position absolute
      top 0
      width $lineNumbersWrapperWidth
      text-align center
      color rgba(255, 255, 255, 0.3)
      padding 1.25rem 0
      line-height 1.4
      br
        user-select none
      .line-number
        position relative
        z-index 4
        user-select none
        font-size 0.85em
    &::after
      content ''
      position absolute
      z-index 2
      top 0
      left 0
      width $lineNumbersWrapperWidth
      height 100%
      border-radius 6px 0 0 6px
      border-right 1px solid rgba(0, 0, 0, 66%)
      background-color $codeBgColor


for lang in $codeLang
  div{'[class~="language-' + lang + '"]'}
    &:before
      content ('' + lang)

div[class~="language-javascript"]
  &:before
    content "js"

div[class~="language-typescript"]
  &:before
    content "ts"

div[class~="language-markup"]
  &:before
    content "html"

div[class~="language-markdown"]
  &:before
    content "md"

div[class~="language-json"]:before
  content "json"

div[class~="language-ruby"]:before
  content "rb"

div[class~="language-python"]:before
  content "py"

div[class~="language-bash"]:before
  content "sh"

div[class~="language-php"]:before
  content "php"

@import '~prismjs/themes/prism-tomorrow.css'


================================================
FILE: docs/.vuepress/theme/styles/config.styl
================================================
$contentClass = '.theme-default-content'


================================================
FILE: docs/.vuepress/theme/styles/custom-blocks.styl
================================================
.custom-block
  .custom-block-title
    font-weight 600
    margin-bottom -0.4rem
  &.tip, &.warning, &.danger
    padding .1rem 1.5rem
    border-left-width .5rem
    border-left-style solid
    margin 1rem 0
  &.tip
    background-color #f3f5f7
    border-color #42b983
  &.warning
    background-color rgba(255,229,100,.3)
    border-color darken(#ffe564, 35%)
    color darken(#ffe564, 70%)
    .custom-block-title
      color darken(#ffe564, 50%)
    a
      color $textColor
  &.danger
    background-color #ffe6e6
    border-color darken(red, 20%)
    color darken(red, 70%)
    .custom-block-title
      color darken(red, 40%)
    a
      color $textColor
  &.details
    display block
    position relative
    border-radius 2px
    margin 1.6em 0
    padding 1.6em
    background-color #eee
    h4
      margin-top 0
    figure, p
      &:last-child
        margin-bottom 0
        padding-bottom 0
    summary
      outline none
      cursor pointer


================================================
FILE: docs/.vuepress/theme/styles/index.styl
================================================
@require './config'
@require './code'
@require './custom-blocks'
@require './arrow'
@require './wrapper'
@require './toc'

html, body
  padding 0
  margin 0
  background-color #fff

body
  font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif
  -webkit-font-smoothing antialiased
  -moz-osx-font-smoothing grayscale
  font-size 16px
  color $textColor

.page
  padding-left $sidebarWidth

.navbar
  position fixed
  z-index 20
  top 0
  left 0
  right 0
  height $navbarHeight
  background-color #fff
  box-sizing border-box
  border-bottom 1px solid $borderColor

.sidebar-mask
  position fixed
  z-index 9
  top 0
  left 0
  width 100vw
  height 100vh
  display none

.sidebar
  font-size 16px
  background-color #fff
  width $sidebarWidth
  position fixed
  z-index 10
  margin 0
  top $navbarHeight
  left 0
  bottom 0
  box-sizing border-box
  border-right 1px solid $borderColor
  overflow-y auto

{$contentClass}:not(.custom)
  @extend $wrapper
  > *:first-child
    margin-top $navbarHeight

  a:hover
    text-decoration underline

  p.demo
    padding 1rem 1.5rem
    border 1px solid #ddd
    border-radius 4px

  img
    max-width 100%

{$contentClass}.custom
  padding 0
  margin 0

  img
    max-width 100%

a
  font-weight 500
  color $accentColor
  text-decoration none

p a code
  font-weight 400
  color $accentColor

kbd
  background #eee
  border solid 0.15rem #ddd
  border-bottom solid 0.25rem #ddd
  border-radius 0.15rem
  padding 0 0.15em

blockquote
  font-size 1rem
  color #999;
  border-left .2rem solid #dfe2e5
  margin 1rem 0
  padding .25rem 0 .25rem 1rem

  & > p
    margin 0

ul, ol
  padding-left 1.2em

strong
  font-weight 600

h1, h2, h3, h4, h5, h6
  font-weight 600
  line-height 1.25

  {$contentClass}:not(.custom) > &
    margin-top (0.5rem - $navbarHeight)
    padding-top ($navbarHeight + 1rem)
    margin-bottom 0

    &:first-child
      margin-top -1.5rem
      margin-bottom 1rem

      + p, + pre, + .custom-block
        margin-top 2rem

  &:focus .header-anchor,
  &:hover .header-anchor
    opacity: 1

h1
  font-size 2.2rem

h2
  font-size 1.65rem
  padding-bottom .3rem
  border-bottom 1px solid $borderColor

h3
  font-size 1.35rem

a.header-anchor
  font-size 0.85em
  float left
  margin-left -0.87em
  padding-right 0.23em
  margin-top 0.125em
  opacity 0

  &:focus,
  &:hover
    text-decoration none

code, kbd, .line-number
  font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace

p, ul, ol
  line-height 1.7

hr
  border 0
  border-top 1px solid $borderColor

table
  border-collapse collapse
  margin 1rem 0
  display: block
  overflow-x: auto

tr
  border-top 1px solid #dfe2e5

  &:nth-child(2n)
    background-color #f6f8fa

th, td
  border 1px solid #dfe2e5
  padding .6em 1em

.theme-container
  &.sidebar-open
    .sidebar-mask
      display: block

  &.no-navbar
    {$contentClass}:not(.custom) > h1, h2, h3, h4, h5, h6
      margin-top 1.5rem
      padding-top 0

    .sidebar
      top 0

@media (min-width: ($MQMobile + 1px))
  .theme-container.no-sidebar
    .sidebar
      display none

    .page
      padding-left 0

@require 'mobile.styl'


================================================
FILE: docs/.vuepress/theme/styles/mobile.styl
================================================
@require './config'

$mobileSidebarWidth = $sidebarWidth * 0.82

// narrow desktop / iPad
@media (max-width: $MQNarrow)
  .sidebar
    font-size 15px
    width $mobileSidebarWidth
  .page
    padding-left $mobileSidebarWidth

// wide mobile
@media (max-width: $MQMobile)
  .sidebar
    top 0
    padding-top $navbarHeight
    transform translateX(-100%)
    transition transform .2s ease
  .page
    padding-left 0
  .theme-container
    &.sidebar-open
      .sidebar
        transform translateX(0)
    &.no-navbar
      .sidebar
        padding-top: 0

// narrow mobile
@media (max-width: $MQMobileNarrow)
  h1
    font-size 1.9rem
  {$contentClass}
    div[class*="language-"]
      margin 0.85rem -1.5rem
      border-radius 0


================================================
FILE: docs/.vuepress/theme/styles/toc.styl
================================================
.table-of-contents
  .badge
    vertical-align middle


================================================
FILE: docs/.vuepress/theme/styles/wrapper.styl
================================================
$wrapper
  max-width $contentWidth
  margin 0 auto
  padding 2rem 2.5rem
  @media (max-width: $MQNarrow)
    padding 2rem
  @media (max-width: $MQMobileNarrow)
    padding 1.5rem



================================================
FILE: docs/.vuepress/theme/util/index.js
================================================
export const hashRE = /#.*$/
export const extRE = /\.(md|html)$/
export const endingSlashRE = /\/$/
export const outboundRE = /^[a-z]+:/i

export function normalize(path) {
  return decodeURI(path).replace(hashRE, "").replace(extRE, "")
}

export function getHash(path) {
  const match = path.match(hashRE)
  if (match) {
    return match[0]
  }
}

export function isExternal(path) {
  return outboundRE.test(path)
}

export function isMailto(path) {
  return /^mailto:/.test(path)
}

export function isTel(path) {
  return /^tel:/.test(path)
}

export function ensureExt(path) {
  if (isExternal(path)) {
    return path
  }
  const hashMatch = path.match(hashRE)
  const hash = hashMatch ? hashMatch[0] : ""
  const normalized = normalize(path)

  if (endingSlashRE.test(normalized)) {
    return path
  }
  return normalized + ".html" + hash
}

export function isActive(route, path) {
  const routeHash = decodeURIComponent(route.hash)
  const linkHash = getHash(path)
  if (linkHash && routeHash !== linkHash) {
    return false
  }
  const routePath = normalize(route.path)
  const pagePath = normalize(path)
  return routePath === pagePath
}

export function resolvePage(pages, rawPath, base) {
  if (isExternal(rawPath)) {
    return {
      type: "external",
      path: rawPath,
    }
  }
  if (base) {
    rawPath = resolvePath(rawPath, base)
  }
  const path = normalize(rawPath)
  for (let i = 0; i < pages.length; i++) {
    if (normalize(pages[i].regularPath) === path) {
      return Object.assign({}, pages[i], {
        type: "page",
        path: ensureExt(pages[i].path),
      })
    }
  }
  console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`)
  return {}
}

function resolvePath(relative, base, append) {
  const firstChar = relative.charAt(0)
  if (firstChar === "/") {
    return relative
  }

  if (firstChar === "?" || firstChar === "#") {
    return base + relative
  }

  const stack = base.split("/")

  // remove trailing segment if:
  // - not appending
  // - appending to trailing slash (last segment is empty)
  if (!append || !stack[stack.length - 1]) {
    stack.pop()
  }

  // resolve relative path
  const segments = relative.replace(/^\//, "").split("/")
  for (let i = 0; i < segments.length; i++) {
    const segment = segments[i]
    if (segment === "..") {
      stack.pop()
    } else if (segment !== ".") {
      stack.push(segment)
    }
  }

  // ensure leading slash
  if (stack[0] !== "") {
    stack.unshift("")
  }

  return stack.join("/")
}

/**
 * @param { Page } page
 * @param { string } regularPath
 * @param { SiteData } site
 * @param { string } localePath
 * @returns { SidebarGroup }
 */
export function resolveSidebarItems(page, regularPath, site, localePath) {
  const {pages, themeConfig} = site

  const localeConfig =
    localePath && themeConfig.locales ? themeConfig.locales[localePath] || themeConfig : themeConfig

  const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar
  if (pageSidebarConfig === "auto") {
    return resolveHeaders(page)
  }

  const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar
  if (!sidebarConfig) {
    return []
  } else {
    const {base, config} = resolveMatchingConfig(regularPath, sidebarConfig)
    if (config === "auto") {
      return resolveHeaders(page)
    }
    return config ? config.map((item) => resolveItem(item, pages, base)) : []
  }
}

/**
 * @param { Page } page
 * @returns { SidebarGroup }
 */
function resolveHeaders(page) {
  const headers = groupHeaders(page.headers || [])
  return [
    {
      type: "group",
      collapsable: false,
      title: page.title,
      path: null,
      children: headers.map((h) => ({
        type: "auto",
        title: h.title,
        basePath: page.path,
        path: page.path + "#" + h.slug,
        children: h.children || [],
      })),
    },
  ]
}

export function groupHeaders(headers) {
  // group h3s under h2
  headers = headers.map((h) => Object.assign({}, h))
  let lastH2
  headers.forEach((h) => {
    if (h.level === 2) {
      lastH2 = h
    } else if (lastH2) {
      ;(lastH2.children || (lastH2.children = [])).push(h)
    }
  })
  return headers.filter((h) => h.level === 2)
}

export function resolveNavLinkItem(linkItem) {
  return Object.assign(linkItem, {
    type: linkItem.items && linkItem.items.length ? "links" : "link",
  })
}

/**
 * @param { Route } route
 * @param { Array<string|string[]> | Array<SidebarGroup> | [link: string]: SidebarConfig } config
 * @returns { base: string, config: SidebarConfig }
 */
export function resolveMatchingConfig(regularPath, config) {
  if (Array.isArray(config)) {
    return {
      base: "/",
      config: config,
    }
  }
  for (const base in config) {
    if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) {
      return {
        base,
        config: config[base],
      }
    }
  }
  return {}
}

function ensureEndingSlash(path) {
  return /(\.html|\/)$/.test(path) ? path : path + "/"
}

function resolveItem(item, pages, base, groupDepth = 1) {
  if (typeof item === "string") {
    return resolvePage(pages, item, base)
  } else if (Array.isArray(item)) {
    return Object.assign(resolvePage(pages, item[0], base), {
      title: item[1],
    })
  } else {
    const children = item.children || []
    if (children.length === 0 && item.path) {
      return Object.assign(resolvePage(pages, item.path, base), {
        title: item.title,
      })
    }
    return {
      type: "group",
      path: item.path,
      title: item.title,
      sidebarDepth: item.sidebarDepth,
      initialOpenGroupIndex: item.initialOpenGroupIndex,
      children: children.map((child) => resolveItem(child, pages, base, groupDepth + 1)),
      collapsable: item.collapsable !== false,
    }
  }
}


================================================
FILE: docs/README.md
================================================
---
homepage: true
sidebar: false
---

<HeroSection>

# Ajv JSON schema validator

## Security and reliability for JavaScript applications

<Features>
<Feature type="less-code" link="/guide/why-ajv.html#write-less-code">

### Write less code

Ensure your data is valid once it is received

</Feature>
<Feature type="fast-secure" link="/guide/why-ajv.html#super-fast-secure">

### Super fast & secure

Compiles your schemas to optimized JavaScript code

</Feature>

<Feature type="multi-spec" link="/guide/why-ajv.html#multi-standard">

### Multi-standard

Use JSON Type Definition or JSON Schema

</Feature>
</Features>

<Sponsors level="platinum">

## Ajv sponsors

[![mozilla](/img/mozilla.svg)](https://www.mozilla.org)
[![reserved](/img/reserved.svg)](https://opencollective.com/ajv)

</Sponsors>

<Sponsors level="gold">

[![microsoft](/img/microsoft.png)](https://opensource.microsoft.com)
[![reserved](/img/reserved.svg)](https://opencollective.com/ajv)
[![reserved](/img/reserved.svg)](https://opencollective.com/ajv)

</Sponsors>

<Sponsors level="bronze">

[![Retool](/img/retool.svg)](https://retool.com/?utm_source=sponsor&utm_campaign=ajv)
[![Tidelift](/img/tidelift.svg)](https://tidelift.com/subscription/pkg/npm-ajv?utm_source=npm-ajv&utm_medium=referral&utm_campaign=enterprise)
[![SimpleX](/img/simplex.svg)](https://github.com/simplex-chat/simplex-chat)
[![reserved](/img/reserved.svg)](https://opencollective.com/ajv)

</Sponsors>

</HeroSection>

<HomeSection>
<Columns>
<Column side="left">

Ajv is used by a large number of JavaScript applications and libraries in all JavaScript environments - Node.js, browser, Electron apps, WeChat mini-apps etc.

It allows implementing complex data validation logic via declarative schemas for your JSON data, without writing code.

Out of the box, Ajv supports [JSON Schema](./json-schema.md) (drafts 04, 06, 07, 2019-09 and 2020-12) and [JSON Type Definition](./json-type-definition.md) ([RFC8927](https://datatracker.ietf.org/doc/rfc8927/)).

<br/>

<Button link="/guide/getting-started.html">Learn Ajv</Button>

<br/>

</Column>

<Column side="right">
<code-group>
<code-block title="JSON Schema">
```javascript
const Ajv = require("ajv")
const ajv = new Ajv()

const schema = {
  type: "object",
  properties: {
    foo: {type: "integer"},
    bar: {type: "string"}
  },
  required: ["foo"],
  additionalProperties: false
}

const data = {foo: 1, bar: "abc"}
const valid = ajv.validate(schema, data)
if (!valid) console.log(ajv.errors)
```
</code-block>

<code-block title="JSON Type Definition">
```javascript
const Ajv = require("ajv/dist/jtd")
const ajv = new Ajv()

const schema = {
  properties: {
    foo: {type: "int32"}
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}


const data = {foo: 1, bar: "abc"}
const valid = ajv.validate(schema, data)
if (!valid) console.log(ajv.errors)
```
</code-block>
</code-group>
</Column>
</Columns>
</HomeSection>

<HomeSection section="testimonials">

## What users say

<Testimonials>
<Testimonial color="green">

Ajv stands out as the implementation of choice - it provides a rich API which many thousands of people use in production... Ajv is partly responsible for the success of JSON Schema.

[Ben Hutton](https://github.com/relequestual), JSON Schema Specification Lead

</Testimonial>

<Testimonial color="blue">

[ESLint](https://eslint.org/) has used Ajv for validating our complex configurations. Ajv has proven to be reliable over the years we’ve been using it and ESLint is proud to sponsor Ajv’s continued development.

[Nicholas C. Zakas](https://github.com/nzakas), ESLint creator and TSC member

</Testimonial>
</Testimonials>

<span style="float:right;">[All quotes](./testimonials.md)</span>

</HomeSection>

<HomeSection>

## News

<NewsHome/>

</HomeSection>

<HomeSection>

## Who uses Ajv

<Projects>
[![eslint](./projects/eslint.png)](https://eslint.org)
[![stoplight](./projects/stoplight.png)](https://stoplight.io)
[![webpack](./projects/webpack.svg)](https://webpack.js.org)
[table](https://github.com/gajus/table)
[![fastify](./projects/fastify.png)](https://www.fastify.io)
[restbase](https://github.com/wikimedia/restbase)
[objection.js](https://github.com/vincit/objection.js)
[![Taskcluster](./projects/taskcluster.png)](https://taskcluster.net)
[![RxDB](./projects/rxdb.svg)](https://rxdb.info)
[![react-jsonschema-form](./projects/rjsf.png)](https://github.com/rjsf-team/react-jsonschema-form)
[![autorest](./projects/autorest.png)](https://github.com/Azure/autorest)
[![node-red](./projects/nodered.png)](https://github.com/node-red/node-red)
[![MDN](./projects/mdn.svg)](https://developer.mozilla.org)
[![quicktype](./projects/quicktype.svg)](https://github.com/quicktype/quicktype)
[![vue-form-generator](./projects/vue-form-generator.png)](https://github.com/vue-generators/vue-form-generator)
[![teambit](./projects/teambit.png)](https://github.com/teambit/bit)
[React Page](https://react-page.github.io)
[![Backstage](./projects/backstage.svg)](https://backstage.io)
[![rushstack](./projects/rushstack.svg)](https://github.com/microsoft/rushstack)
[JupyterLab](https://github.com/jupyterlab/jupyterlab)
[![0x](./projects/0x.png)](https://github.com/davidmarkclements/0x)
[Plank.js](https://piqnt.com/planck.js/)
[![fast](./projects/fast.svg)](https://www.fast.design)
[![netlify cms](./projects/netlify-cms.png)](https://www.netlifycms.org)
[![ng-alain](./projects/ng-alain.svg)](https://ng-alain.com/en)
[![Vercel](./projects/vercel.svg)](https://vercel.com)
[![AWS Amplify](./projects/aws-amplify.png)](https://github.com/aws-amplify/amplify-cli)
[![FB flipper](./projects/flipper.png)](https://github.com/facebook/flipper)
[![nx.dev](./projects/nx.svg)](https://nx.dev)
[![express gateway](./projects/express-gateway.svg)](https://www.express-gateway.io)
[![zigbee2mqtt](./projects/zigbee2mqtt.png)](https://www.zigbee2mqtt.io)
[![dependency-cruiser](./projects/dependency-cruiser.png)](https://github.com/sverweij/dependency-cruiser)
[![theia](./projects/theia.svg)](https://theia-ide.org)
[![TSDoc](./projects/tsdoc.svg)](https://tsdoc.org)
[![webhint](./projects/webhint.jpg)](https://webhint.io)
[Vega-Lite](https://vega.github.io/vega-lite/)
[![middy](./projects/middy.png)](https://middy.js.org)
[JSDoc](https://github.com/jsdoc/jsdoc)
[![Ts.ED](./projects/tsed.png)](https://tsed.io)

</Projects>
</HomeSection>

<HomeSection section="contributors">

## Contributors

Ajv is free to use and open-source that many developers contributed to. Join us!

<Contributors />

</HomeSection>

<HomeSection section="footer">

<FooterColumns>
<FooterColumn type="ajv">
![ajv](/img/ajv.svg)

</FooterColumn>

<FooterColumn type="links">

[Learn Ajv](./guide/getting-started.md)

[Reference](./api.md)

[Security](./security.md)

</FooterColumn>

<FooterColumn type="links">

[JSON Schema](./json-schema.md)

[JSON Type Definition](./json-type-definition.md)

[Contributing](./contributing.md)

</FooterColumn>

<FooterColumn type="sponsors">

[![mozilla](/img/mozilla.svg)](https://www.mozilla.org)
[![reserved](/img/reserved.svg)](https://opencollective.com/ajv)

</FooterColumn>
</FooterColumns>

[&copy; 2015-2021](./license.md) | Ajv JSON schema validator | [ajv.validator@gmail.com](mailto:ajv.validator@gmail.com)

</HomeSection>


================================================
FILE: docs/api.md
================================================
# API Reference

[[toc]]

## Ajv constructor and methods

### new Ajv(options: object)

Create Ajv instance:

```javascript
const ajv = new Ajv()
```

See [Options](./options)

### ajv.compile(schema: object): (data: any) => boolean | Promise < any >

Generate validating function and cache the compiled schema for future use.

Validating function returns a boolean value (or promise for async schemas that must have `$async: true` property - see [Asynchronous validation](./guide/async-validation.md)). This function has properties `errors` and `schema`. Errors encountered during the last validation are assigned to `errors` property (it is assigned `null` if there was no errors). `schema` property contains the reference to the original schema.

The schema passed to this method will be validated against meta-schema unless `validateSchema` option is false. If schema is invalid, an error will be thrown. See [options](#options).

In typescript returned validation function can be a type guard if you pass type parameter:

```typescript
interface Foo {
  foo: number
}

const FooSchema: JSONSchemaType<Foo> = {
  type: "object",
  properties: {foo: {type: "number"}},
  required: ["foo"],
  additionalProperties: false,
}

const validate = ajv.compile<Foo>(FooSchema) // type of validate extends `(data: any) => data is Foo`
const data: any = {foo: 1}
if (validate(data)) {
  // data is Foo here
  console.log(data.foo)
} else {
  console.log(validate.errors)
}
```

See more advanced example in [the test](https://github.com/ajv-validator/ajv/blob/master/spec/types/json-schema.spec.ts).

<a name="jtd-serialize"></a>

### ajv.compileSerializer(schema: object): (data: any) => string <Badge text="NEW" />

Generate serializing function based on the [JTD schema](./json-type-definition.md) (caches the schema) - only in JTD instance of Ajv (see example below).

Serializers compiled from JTD schemas can be more than 10 times faster than using `JSON.stringify`, because they do not traverse all the data, only the properties that are defined in the schema.

Properties not defined in the schema will not be included in serialized JSON, unless the schema has `additionalProperties: true` flag. It can also be beneficial from the application security point of view, as it prevents leaking accidentally/temporarily added additional properties to the API responses.

If you use JTD with typescript, the type for the schema can be derived from the data type, and generated serializer would only accept correct data type in this case:

```typescript
import Ajv, {JTDSchemaType} from "ajv/dist/jtd"
const ajv = new Ajv()

interface MyData {
  foo: number
  bar?: string
}

const mySchema: JTDSchemaType<MyData> = {
  properties: {
    foo: {type: "int32"} // any JTD number type would be accepted here
  },
  optionalProperties: {
    bar: {type: "string"}
  }
}

const serializeMyData = ajv.compileSerializer(mySchema)

// serializeMyData has type (x: MyData) => string
// it prevents you from accidentally passing the wrong type
```

::: warning Compiled serializers do NOT validate data!
It is assumed that the data is valid according to the schema.
:::

<a name="jtd-parse"></a>

### ajv.compileParser(schema: object): (json: string) => any <Badge text="NEW" />

Generate parsing function based on the [JTD schema](./json-type-definition.md) (caches the schema) - only in JTD instance of Ajv (see example below).

Parsers compiled from JTD schemas have comparable performance to `JSON.parse`<sup>\*</sup> in case JSON string is valid according to the schema (and they do not just parse JSON - they ensure that parsed JSON is valid according to the schema as they parse), but they can be many times faster in case the string is invalid - for example, if schema expects an object, and JSON string is array the parser would fail on the first character.

Parsing will fail if there are properties not defined in the schema, unless the schema has `additionalProperties: true` flag.

If you use JTD with typescript, the type for the schema can be derived from the data type, and generated parser will return correct data type (see definitions example in the [serialize](#jtd-serialize) section):

```typescript
const parseMyData = ajv.compileParser(mySchema)

// parseMyData has type (s: string) => MyData | undefined
// it returns correct data type in case parsing is successful and undefined if not

const validData = parseMyData('{"foo":1}') // {foo: 1} - success

const invalidData = parseMyData('{"x":1}') // undefined - failure
console.log(parseMyData.position) // 4
console.log(parseMyData.message) // property x not allowed
```

<sup>\*</sup> As long as empty schema `{}` is not used - there is a possibility to improve performance in this case. Also, the performance of parsing `discriminator` schemas depends on the position of discriminator tag in the schema - the best parsing performance will be achieved if the tag is the first property - this is how compiled JTD serializers generate JSON in case of discriminator schemas.

<a name="api-compileAsync"></a>

### ajv.compileAsync(schema: object, meta?: boolean): Promise < Function >

Asynchronous version of `compile` method that loads missing remote schemas using asynchronous function in `options.loadSchema`. This function returns a Promise that resolves to a validation function. An optional callback passed to `compileAsync` will be called with 2 parameters: error (or null) and validating function. The returned promise will reject (and the callback will be called with an error) when:

- missing schema can't be loaded (`loadSchema` returns a Promise that rejects).
- a schema containing a missing reference is loaded, but the reference cannot be resolved.
- schema (or some loaded/referenced schema) is invalid.

The function compiles schema and loads the first missing schema (or meta-schema) until all missing schemas are loaded.

You can asynchronously compile meta-schema by passing `true` as the second parameter.

Similarly to `compile`, it can return type guard in typescript.

See example in [Asynchronous schema loading](./guide/managing-schemas.md#asynchronous-schema-loading).

### ajv.validate(schemaOrRef: object | string, data: any): boolean

Validate data using passed schema (it will be compiled and cached).

Instead of the schema you can use the key that was previously passed to `addSchema`, the schema id if it was present in the schema or any previously resolved reference.

Validation errors will be available in the `errors` property of Ajv instance (`null` if there were no errors).

In typescript this method can act as a type guard (similarly to function returned by `compile` method - see example there).

::: warning Save errors property
Every time this method is called the errors are overwritten so you need to copy them to another variable if you want to use them later.
:::

If the schema is asynchronous (has `$async` keyword on the top level) this method returns a Promise. See [Asynchronous validation](./guide/async-validation.md).

<a id="add-schema"></a>

### ajv.addSchema(schema: object | object[], key?: string): Ajv

Add schema(s) to validator instance. This method does not compile schemas (but it still validates them). Because of that dependencies can be added in any order and circular dependencies are supported. It also prevents unnecessary compilation of schemas that are containers for other schemas but not used as a whole.

Array of schemas can be passed (schemas should have ids), the second parameter will be ignored.

Key can be passed that can be used to reference the schema and will be used as the schema id if there is no id inside the schema. If the key is not passed, the schema id will be used as the key.

Once the schema is added, it (and all the references inside it) can be referenced in other schemas and used to validate data.

Although `addSchema` does not compile schemas, explicit compilation is not required - the schema will be compiled when it is used first time.

By default the schema is validated against meta-schema before it is added, and if the schema does not pass validation the exception is thrown. This behaviour is controlled by `validateSchema` option.

::: tip Method chaining
Ajv returns its instance for chaining from all methods prefixed `add*` and `remove*`:

```javascript
const validate = new Ajv().addSchema(schema).addFormat(name, regex).getSchema(uri)
```
:::

### ajv.addMetaSchema(schema: object | object[], key?: string): Ajv

Adds meta schema(s) that can be used to validate other schemas. That function should be used instead of `addSchema` because there may be instance options that would compile a meta schema incorrectly (at the moment it is `removeAdditional` option).

There is no need to explicitly add draft-07 meta schema (http://json-schema.org/draft-07/schema) - it is added by default, unless option `meta` is set to `false`. You only need to use it if you have a changed meta-schema that you want to use to validate your schemas. See `validateSchema`.

<a name="api-validateschema"></a>

### ajv.validateSchema(schema: object): boolean

Validates schema. This method should be used to validate schemas rather than `validate` due to the inconsistency of `uri` format in JSON Schema standard.

By default this method is called automatically when the schema is added, so you rarely need to use it directly.

If schema doesn't have `$schema` property, it is validated against draft 6 meta-schema (option `meta` should not be false).

If schema has `$schema` property, then the schema with this id (that should be previously added) is used to validate passed schema.

Errors will be available at `ajv.errors`.

### ajv.getSchema(key: string): undefined | ((data: any) => boolean | Promise < any >)

Retrieve compiled schema previously added with `addSchema` by the key passed to `addSchema` or by its full reference (id). The returned validating function has `schema` property with the reference to the original schema.

### ajv.removeSchema(schemaOrRef: object | string | RegExp): Ajv

Remove added/cached schema. Even if schema is referenced by other schemas it can be safely removed as dependent schemas have local references.

Schema can be removed using:

- key passed to `addSchema`
- it's full reference (id)
- RegExp that should match schema id or key (meta-schemas won't be removed)
- actual schema object (that will be optionally serialized) to remove schema from cache

If no parameter is passed all schemas but meta-schemas will be removed and the cache will be cleared.

<a name="api-addformat"></a>

### ajv.addFormat(name: string, format: Format): Ajv

```typescript
type Format =
  | true // to ignore this format (and pass validation)
  | string // will be converted to RegExp
  | RegExp
  | (data: string) => boolean
  | Object // format definition (see below and in types)
```

Add format to validate strings or numbers.

If object is passed it should have properties `validate`, `compare` and `async`:

```typescript
interface FormatDefinition { // actual type definition is more precise - see types.ts
  validate: string | RegExp | (data: number | string) => boolean | Promise<boolean>
  compare: (data1: string, data2: string): number // an optional function that accepts two strings
    // and compares them according to the format meaning.
    // This function is used with keywords `formatMaximum`/`formatMinimum`
    // (defined in [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package).
    // It should return `1` if the first value is bigger than the second value,
    // `-1` if it is smaller and `0` if it is equal.
  async?: true // if `validate` is an asynchronous function
  type?: "string" | "number" // "string" is default. If data type is different, the validation will pass.
}
```

Formats can be also added via `formats` option.

<a name="api-addkeyword"></a>

### ajv.addKeyword(definition: string | object): Ajv

Add validation keyword to Ajv instance.

Keyword should be different from all standard JSON Schema keywords and different from previously defined keywords. There is no way to redefine keywords or to remove keyword definition from the instance.

Keyword must start with an ASCII letter, `_` or `$`, and may continue with ASCII letters, numbers, `_`, `$`, `-`, or `:`.
It is recommended to use an application-specific prefix for keywords to avoid current and future name collisions.

Example Keywords:

- `"xyz-example"`: valid, and uses prefix for the xyz project to avoid name collisions.
- `"example"`: valid, but not recommended as it may collide with future versions of JSON Schema etc.
- `"3-example"`: invalid as numbers are not allowed to be the first character in a keyword

Keyword definition is an object with the following properties:

```typescript
interface KeywordDefinition {
  // actual type definition is more precise - see types.ts
  keyword: string // keyword name
  type?: string | string[] // JSON data type(s) the keyword applies to. Default - all types.
  schemaType?: string | string[] // the required schema JSON type
  code?: Function // function to generate code, used for all pre-defined keywords
  validate?: Function // validating function
  compile?: Function // compiling function
  macro?: Function // macro function
  error?: object // error definition object - see types.ts
  schema?: false // used with "validate" keyword to not pass schema to function
  metaSchema?: object // meta-schema for keyword schema
  dependencies?: string[] // properties that must be present in the parent schema -
  // it will be checked during schema compilation
  implements?: string[] // keyword names to reserve that this keyword implements
  modifying?: true // MUST be passed if keyword modifies data
  valid?: boolean // to pre-define validation result, validation function result will be ignored -
  // this option MUST NOT be used with `macro` keywords.
  $data?: true // to support [\$data reference](./guide/combining-schemas.md#data-reference) as the value of keyword.
  // The reference will be resolved at validation time. If the keyword has meta-schema,
  // it would be extended to allow $data and it will be used to validate the resolved value.
  // Supporting $data reference requires that keyword has `code` or `validate` function
  // (the latter can be used in addition to `compile` or `macro`).
  $dataError?: object // error definition object for invalid \$data schema - see types.ts
  async?: true // if the validation function is asynchronous
  // (whether it is returned from `compile` or passed in `validate` property).
  // It should return a promise that resolves with a value `true` or `false`.
  // This option is ignored in case of "macro" and "code" keywords.
  errors?: boolean | "full" // whether keyword returns errors.
  // If this property is not passed Ajv will determine
  // if the errors were set in case of failed validation.
}
```

If only the property `keyword` is provided in the definition object, you can also pass the keyword name as the argument.

`compile`, `macro` and `code` are mutually exclusive, only one should be used at a time. `validate` can be used separately or in addition to `compile` or `macro` to support [\$data reference](./guide/combining-schemas.md#data-reference).

::: tip Keyword is validated only for applicable data types
If the keyword is validating data type that is different from the type(s) in its definition, the validation function will not be called (and expanded macro will not be used), so there is no need to check for data type inside validation function or inside schema returned by macro function (unless you want to enforce a specific type and for some reason do not want to use a separate `type` keyword for that). In the same way as standard keywords work, if the keyword does not apply to the data type being validated, the validation of this keyword will succeed.
:::

See [User defined keywords](./keywords.md) for more details.

### ajv.getKeyword(keyword: string): object | boolean

Returns keyword definition, `false` if the keyword is unknown.

### ajv.removeKeyword(keyword: string): Ajv

Removes added or pre-defined keyword so you can redefine them.

While this method can be used to extend pre-defined keywords, it can also be used to completely change their meaning - it may lead to unexpected results.

::: warning Compiled schemas and removed keywords
The schemas compiled before the keyword is removed will continue to work without changes. To recompile schemas use `removeSchema` method and compile them again.
:::

### ajv.errorsText(errors?: object[], options?: object): string

Returns the text with all errors in a String.

Options can have properties `separator` (string used to separate errors, ", " by default) and `dataVar` (the variable name that instancePath is prefixed with, "data" by default).

## Validation errors

In case of validation failure, Ajv assigns the array of errors to `errors` property of validation function (or to `errors` property of Ajv instance when `validate` or `validateSchema` methods were called). In case of [asynchronous validation](./guide/async-validation.md), the returned promise is rejected with exception `Ajv.ValidationError` that has `errors` property.

### Error objects

Each reported error is an object with the following properties:

```typescript
interface ErrorObject {
  keyword: string // validation keyword.
  instancePath: string // JSON Pointer to the location in the data instance (e.g., `"/prop/1/subProp"`).
  schemaPath: string // JSON Pointer to the location of the failing keyword in the schema
  params: object // type is defined by keyword value, see below
                 // params property is the object with the additional information about error
                 // it can be used to generate error messages
                 // (e.g., using [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) package).
                 // See below for parameters set by all keywords.
  propertyName?: string // set for errors in `propertyNames` keyword schema.
                        // `instancePath` still points to the object in this case.
  message?: string // the error message (can be excluded with option `messages: false`).
  // Options below are added with `verbose` option:
  schema?: any // the value of the failing keyword in the schema.
  parentSchema?: object // the schema containing the keyword.
  data?: any // the data validated by the keyword.
}
```

For [JTD](./json-type-definition.md) schemas `instancePath` and `schemaPath` depend on the nature of the failure - the errors are consistent with [RFC8927](https://datatracker.ietf.org/doc/rfc8927/).

### Error parameters

Properties of `params` object in errors depend on the keyword that failed validation.

In typescript, the ErrorObject is a discriminated union that allows to determine the type of error parameters based on the value of keyword:

```typescript
const ajv = new Ajv()
const validate = ajv.compile<MyData>(schema)
if (validate(data)) {
  // data is MyData here
  // ...
} else {
  // DefinedError is a type for all pre-defined keywords errors,
  // validate.errors has type ErrorObject[] - to allow user-defined keywords with any error parameters.
  // Users can extend DefinedError to include the keywords errors they defined.
  for (const err of validate.errors as DefinedError[]) {
    switch (err.keyword) {
      case "maximum":
        console.log(err.limit)
        break
      case "pattern":
        console.log(err.pattern)
        break
      // ...
    }
  }
}
```

Also see an example in [this test](https://github.com/ajv-validator/ajv/blob/master/spec/types/error-parameters.spec.ts)

- `maxItems`, `minItems`, `maxLength`, `minLength`, `maxProperties`, `minProperties`:

```typescript
type ErrorParams = {limit: number} // keyword value
```

- `additionalItems`:

```typescript
// when `items` is an array of schemas and `additionalItems` is false:
type ErrorParams = {limit: number} // the maximum number of allowed items
```

- `additionalProperties`:

```typescript
type ErrorParams = {additionalProperty: string}
// the property not defined in `properties` and `patternProperties` keywords
```

- `dependencies`:

```typescript
type ErrorParams = {
  property: string // dependent property,
  missingProperty: string // required missing dependency - only the first one is reported
  deps: string // required dependencies, comma separated list as a string (TODO change to string[])
  depsCount: number // the number of required dependencies
}
```

- `format`:

```typescript
type ErrorParams = {format: string} // keyword value
```

- `maximum`, `minimum`, `exclusiveMaximum`, `exclusiveMinimum`:

```typescript
type ErrorParams = {
  limit: number // keyword value
  comparison: "<=" | ">=" | "<" | ">" // operation to compare the data to the limit,
  // with data on the left and the limit on the right
}
```

- `multipleOf`:

```typescript
type ErrorParams = {multipleOf: number} // keyword value
```

- `pattern`:

```typescript
type ErrorParams = {pattern: string} // keyword value
```

- `required`:

```typescript
type ErrorParams = {missingProperty: string} // required property that is missing
```

- `propertyNames`:

```typescript
type ErrorParams = {propertyName: string} // invalid property name
```

User-defined keywords can define other keyword parameters.

### Errors i18n

You can use [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) package to generate errors in other languages.

### Error logging

A logger instance can be passed via `logger` option to Ajv constructor. The use of other logging packages is supported as long as the package or its associated wrapper exposes the required methods. If any of the required methods are missing an exception will be thrown.

- **Required Methods**: `log`, `warn`, `error`

```javascript
const otherLogger = new OtherLogger()
const ajv = new Ajv({
  logger: {
    log: console.log.bind(console),
    warn: function warn() {
      otherLogger.logWarn.apply(otherLogger, arguments)
    },
    error: function error() {
      otherLogger.logError.apply(otherLogger, arguments)
      console.error.apply(console, arguments)
    },
  },
})
```

##### Options

This section is moved to [Initialization options](./options.md) page


================================================
FILE: docs/codegen.md
================================================
# Code generation design

[[toc]]

Starting from v7 Ajv uses [CodeGen module](https://github.com/ajv-validator/ajv/blob/master/lib/compile/codegen/index.ts) that replaced [doT](https://github.com/olado/dot) templates used earlier.

The motivations for this change:

- doT templates were difficult to maintain and to change, particularly for the occasional contributors.
- they discouraged modularity within validation keywords code and also led to implicit dependencies between different parts of code.
- they had risks of remote code execution in case untrusted schemas were used, even though all identified issues were patched.
- ES6 template literals that are now widely supported offer a great alternative to both ASTs and to plain string concatenation - this option was not available when Ajv started.

## Safe code generation

CodeGen module defines two tagged templates that should be passed to all code generation methods and used in other tagged templates:

- `_` - to create instances of private \_Code class that will not be escaped when used in code or other tagged templates.
- `str` - to create code for string expressions.

For example, this code:

```typescript
const x = 0
// Name is a subclass of _Code that can be safely used in code - it only allows valid identifiers
// gen.const creates a unique variable name with the prefix "num".
const num: Name = gen.const("num", 5)
gen.if(
  // _`...` returns the instance of _Code with safe interpolation of `num` and `x`.
  // if `x` was a string, it would be inserted into code as a quoted string value rather than as a code fragment,
  // so if `x` contained some code, it would not be executed.
  _`${num} > ${x}`,
  () => log("greater"),
  () => log("smaller or equal")
)

function log(comparison: string): void {
  // msg creates a string expression with concatenation - see generated code below
  // type Code = _Code | Name, _Code can only be constructed with template literals
  const msg: Code = str`${num} is ${comparison} than ${x}`
  // msg is _Code instance, so it will be inserted via another template without quotes
  gen.code(_`console.log(${msg})`)
}
```

generates this javascript code:

```javascript
const num0 = 5
if (num0 > 0) {
  console.log(num0 + " is greater than 0")
} else {
  console.log(num0 + " is smaller or equal than 0")
}
```

`.const`, `.if` and `.code` above are methods of CodeGen class that generate code inside class instance `gen` - see [source code](https://github.com/ajv-validator/ajv/blob/master/lib/compile/codegen/index.ts) for all available methods and [tests](https://github.com/ajv-validator/ajv/blob/master/spec/codegen.spec.ts) for other code generation examples.

These methods only accept instances of private class `_Code`, other values will be rejected by Typescript compiler - the risk to pass unsafe string is mitigated on type level.

If a string variable were used in `_` template literal, its value would be safely wrapped in quotes - in many cases it is quite useful, as it allows to inject values that can be either string or number via the same template. In the worst case, the generated code could be invalid, but it will prevent the risk of code execution that attacker could pass via untrusted schema as a string value that should be inserted in code (e.g., instead of a number). Also see the comment in the example.

## Code optimization

CodeGen class generates code trees and performs several optimizations before the code is rendered:

1. removes empty and unreachable branches (e.g. `else` branch after `if(true)`, etc.).
2. removes unused variable declarations.
3. replaces variables that are used only once and assigned expressions that are explicitly marked as "constant" (i.e. having referential transparency) with the expressions themselves.

::: warning Optimizations assume no side effects
These optimizations assume that the expressions in `if` conditions, `for` statement headers and assigned expressions are free of any side effects - this is the case for all pre-defined validation keywords.
:::

See [these tests](https://github.com/ajv-validator/ajv/blob/master/spec/codegen.spec.ts) for examples.

By default Ajv does 1-pass optimization - based on the test suite it reduces the code size by 10.5% and the number of tree nodes by 16.7% (TODO benchmark the validation time). The second optimization pass changes it by less than 0.1%, so you won't need it unless you have really complex schemas or if you generate standalone code and want it to pass relevant eslint rules.

Optimization mode can be changed with [options](./api.md#options):

- `{code: {optimize: false}}` - to disable (e.g., when schema compilation time is more important),
- `{code: {optimize: 2}}` - 2-pass optimization.

## User-defined keywords

While tagged template literals wrap passed strings based on their run-time values, CodeGen class methods rely on types to ensure safety of passed parameters - there is no run-time checks that the passed value is an instance of \_Code class.

It is strongly recommended to define additional keywords only with Typescript - using plain JavaScript would still allow passing unsafe strings to code generation methods.

::: warning Optimization and side-effects
If your user-defined keywords need to have side-effects that are removed by optimization (see above), you may need to disable it.
:::


================================================
FILE: docs/coercion.md
================================================
# Type coercion rules

To enable type coercion pass option `coerceTypes` to Ajv with `true` or `array` (it is `false` by default). See [example](./guide/modifying-data.md#coercing-data-types).

The coercion rules are different from JavaScript:

- to validate user input as expected
- to have the coercion reversible
- to correctly validate cases where different types are required in subschemas (e.g., in `anyOf`).

Type coercion only happens if there is `type` keyword and if without coercion the validation would have failed. If coercion to the required type succeeds then the validation continues to other keywords, otherwise the validation fails.

If there are multiple types allowed in `type` keyword the coercion will only happen if none of the types match the data and some of the scalar types are present (coercion to/from `object`/`array` is not possible). In this case the validating function will try coercing the data to each type in order until some of them succeeds.

Application of these rules can have some unexpected consequences. Ajv may coerce the same value multiple times (this is why coercion reversibility is required) as needed at different points in the schema. This is particularly evident when using `oneOf`, which must test all of the subschemas. Ajv will coerce the type for each subschema, possibly resulting in unexpected failure if it can coerce to match more than one of the subschemas. Even if it succeeds, Ajv will not backtrack, so you'll get the type of the final coercion even if that's not the one that allowed the data to pass validation. If possible, structure your schema with `anyOf`, which won't validate subsequent subschemas as soon as it encounters one subschema that matches.

Possible type coercions:

| from&nbsp;type&nbsp;&rarr;<br>to&nbsp;type&nbsp;&darr; |                                     string                                      |                      number                       |                    boolean                     |         null         |                    array\*                     |
| ------------------------------------------------------ | :-----------------------------------------------------------------------------: | :-----------------------------------------------: | :--------------------------------------------: | :------------------: | :--------------------------------------------: |
| string                                                 |                                        -                                        |                  `x`&rarr;`""+x`                  | `false`&rarr;`"false"`<br>`true`&rarr;`"true"` |   `null`&rarr;`""`   |                 `[x]`&rarr;`x`                 |
| number /<br>integer                                    |                  Valid number /<br>integer: `x`&rarr;`+x`<br>                   |                         -                         |      `false`&rarr;`0`<br>`true`&rarr;`1`       |   `null`&rarr;`0`    |                 `[x]`&rarr;`x`                 |
| boolean                                                | `"false"`&rarr;`false`<br>`"true"`&rarr;`true`<br>`"abc"`&#8696;<br>`""`&#8696; | `0`&rarr;`false`<br>`1`&rarr;`true`<br>`x`&#8696; |                       -                        | `null`&rarr;`false`  | `[false]`&rarr;`false`<br>`[true]`&rarr;`true` |
| null                                                   |              `""`&rarr;`null`<br>`"null"`&#8696;<br>`"abc"`&#8696;              |           `0`&rarr;`null`<br>`x`&#8696;           |      `false`&rarr;`null`<br>`true`&#8696;      |          -           |              `[null]`&rarr;`null`              |
| array\*                                                |                                 `x`&rarr;`[x]`                                  |                  `x`&rarr;`[x]`                   | `false`&rarr;`[false]`<br>`true`&rarr;`[true]` | `null`&rarr;`[null]` |                       -                        |

\* Requires option `{coerceTypes: "array"}`

## Coercion from string values

#### To number type

Coercion to `number` is possible if the string is a valid number, `+data` is used.

#### To integer type

Coercion to `integer` is possible if the string is a valid number without fractional part (`data % 1 === 0`).

#### To boolean type

Unlike JavaScript, only these strings can be coerced to `boolean`:

- `"true"` -> `true`
- `"false"` -> `false`

#### To null type

Empty string is coerced to `null`, other strings can't be coerced.

## Coercion from number values

#### To string type

Always possible, `'' + data` is used

#### To boolean type

Unlike JavaScript, only these numbers can be coerced to `boolean`:

- `1` -> `true`
- `0` -> `false`

#### To null type

`0` coerces to `null`, other numbers can't be coerced.

## Coercion from boolean values

#### To string type

- `true` -> `"true"`
- `false` -> `"false"`

#### To number/integer types

- `true` -> `1`
- `false` -> `0`

#### To null type

`false` coerces to `null`, `true` can't be coerced.

## Coercion from null

#### To string type

`null` coerces to the empty string.

#### To number/integer types

`null` coerces to `0`

#### To boolean type

`null` coerces to `false`

## Coercion to and from array

These coercions require that the option `coerceTypes` is `"array"`.

If a scalar data is present and array is required, Ajv wraps scalar data in an array.

If an array with one item is present and a scalar is required, Ajv coerces array into its item.

- `"foo"` -> `[ "foo" ]`
- `[ "foo" ]` -> `"foo"`


================================================
FILE: docs/components.md
================================================
# Code components

[[toc]]

## Ajv classes

[lib/core.ts](https://github.com/ajv-validator/ajv/blob/master/lib/core.ts) - core Ajv class without any keywords. All Ajv methods for managing schemas and extensions are defined in this class.

[lib/ajv.ts](https://github.com/ajv-validator/ajv/blob/master/lib/ajv.ts) - subclass of Ajv core with JSON Schema draft-07 keywords.

[lib/2019.ts](https://github.com/ajv-validator/ajv/blob/master/lib/2019.ts) - subclass of Ajv core with JSON Schema draft-2019-09 keywords.

[lib/jtd.ts](https://github.com/ajv-validator/ajv/blob/master/lib/jtd.ts) - subclass of Ajv core with JSON Type Definition support.

## Schema compilation

[lib/compile](https://github.com/ajv-validator/ajv/blob/master/lib/compile) - code for schema compilation

[lib/compile/index.ts](https://github.com/ajv-validator/ajv/blob/master/lib/compile/index.ts) - the main recursive function code for schema compilation, functions for reference resolution, the interface for schema compilation context (`SchemaCxt`).

[lib/compile/context.ts](https://github.com/ajv-validator/ajv/blob/master/lib/compile/context.ts) - the class for keyword code generation `KeywordCxt`. All pre-defined keywords and user-defined keywords that use `code` function are passed an instance of this class.

[lib/compile/rules.ts](https://github.com/ajv-validator/ajv/blob/master/lib/compile/rules.ts) - data structure to store references to all all keyword definitions that were added to Ajv instance, organised by data type.

[lib/compile/subschema.ts](https://github.com/ajv-validator/ajv/blob/master/lib/compile/subschema.ts) - creates schema context (`SchemaCxt`) to generate code for subschemas - used by all applicator keywords in [lib/vocabularies/applicator](https://github.com/ajv-validator/ajv/blob/master/lib/vocabularies/applicator).

[lib/compile/codegen](https://github.com/ajv-validator/ajv/blob/master/lib/compile/codegen) - the api for [code generation](./codegen.md).

[lib/compile/validate](https://github.com/ajv-validator/ajv/blob/master/lib/compile/validate) - code to iterate the schema to generate code of validation function.

## Other components

[lib/standalone](https://github.com/ajv-validator/ajv/blob/master/lib/standalone) - module to generate [standalone validation code](./standalone.md).

[lib/vocabularies](https://github.com/ajv-validator/ajv/blob/master/lib/vocabularies) - pre-defined validation keywords.

[lib/refs](https://github.com/ajv-validator/ajv/blob/master/lib/refs) - JSON Schema meta-schemas.


================================================
FILE: docs/faq.md
================================================
# Frequently Asked Questions

The purpose of this document is to help find answers quicker. I am happy to continue the discussion about these issues, so please comment on some of the issues mentioned below or create a new issue if it seems more appropriate.

[[toc]]

## Using JSON schema

Ajv implements JSON schema specification. Before submitting the issue about the behaviour of any validation keywords please review them in:

- [JSON Schema specification](https://tools.ietf.org/html/draft-handrews-json-schema-validation-00) (draft-07)
- [JSON Schema reference](./json-schema.md) in Ajv documentation
- [JSON Schema tutorial](https://spacetelescope.github.io/understanding-json-schema/) (for draft-04)

#### Why Ajv validates empty object as valid?

"properties" keyword does not require the presence of any properties, you need to use "required" keyword. It also doesn't require that the data is an object, so any other type of data will also be valid. To require a specific type use "type" keyword. [Strict types mode](./strict-mode.md#strict-types) introduced in v7 requires presence of "type" when "properties" are used, so the mistakes are less likely.

#### Why Ajv validates only the first item of the array?

"items" keyword support [two syntaxes](./json-schema.md#items) - 1) when the schema applies to all items; 2) when there is a different schema for each item in the beginning of the array. This problem means you are using the second syntax.

In v7 with option `strictTuples` (`"log"` by default) this problem is less likely to happen, as Ajv would log warning about missing "minItems" and other keywords that are required to constrain tuple size.

## Ajv API for returning validation errors

See [#65](https://github.com/ajv-validator/ajv/issues/65), [#212](https://github.com/ajv-validator/ajv/issues/212), [#236](https://github.com/ajv-validator/ajv/issues/236), [#242](https://github.com/ajv-validator/ajv/issues/242), [#256](https://github.com/ajv-validator/ajv/issues/256).

#### Why Ajv assigns errors as a property of validation function (or instance) instead of returning an object with validation results and errors?

The reasons are history (other fast validators with the same api) and performance (returning boolean is faster). Although more code is written to process errors than to handle successful results, almost all server-side validations pass. The existing API is more efficient from the performance point of view.

Ajv also supports asynchronous validation (with asynchronous formats and keywords) that returns a promise that either resolves to `true` or rejects with an error.

#### Would errors get overwritten in case of "concurrent" validations?

No. There is no parallel execution in JavaScript, and the cooperative concurrency model of javascript makes this pattern safe. While a validation is run, no other JavaScript code that can access the same memory can be executed. As long as the errors are used in the same execution block, the errors will not be overwritten.

#### Can we change / extend API to add a method that would return errors (rather than assign them to `errors` property)?

No. In many cases there is a module responsible for the validation in the application, usually to load schemas and to process errors. This module is the right place to introduce any user-defined API. Convenience is a subjective thing, changing or extending API purely because of convenience would either break backward compatibility (even if it's done in a new major version it still complicates migration) or bloat API (making it more difficult to maintain).

#### Why don't `"additionalProperties": false` errors display the property name?

Doing this would create a precedent where validated data is used in error messages, creating a vulnerability (e.g., when ajv is used to validate API data/parameters and error messages are logged).

Since the property name is already in the params object, in an application you can modify the messages in any way you need. ajv-errors package allows modifying messages as well.

## Additional properties inside compound keywords anyOf, oneOf, etc.

See [#127](https://github.com/ajv-validator/ajv/issues/127), [#129](https://github.com/ajv-validator/ajv/issues/129), [#134](https://github.com/ajv-validator/ajv/issues/134), [#140](https://github.com/ajv-validator/ajv/issues/140), [#193](https://github.com/ajv-validator/ajv/issues/193), [#205](https://github.com/ajv-validator/ajv/issues/205), [#238](https://github.com/ajv-validator/ajv/issues/238), [#264](https://github.com/ajv-validator/ajv/issues/264).

#### Why the keyword `additionalProperties: false` fails validation when some properties are "declared" inside a subschema in `anyOf`/etc.?

The keyword `additionalProperties` creates the restriction on validated data based on its own value (`false` or schema object) and on the keywords `properties` and `patternProperties` in the SAME schema object. JSON Schema validators must NOT take into account properties used in other schema objects.

While you can expect that the schema below would allow the objects either with properties `foo` and `bar` or with properties `foo` and `baz` and all other properties will be prohibited, this schema will only allow objects with one property `foo` (an empty object and any non-objects will also be valid):

```javascript
{
  type: "object",
  properties: {foo: {type: "number"}},
  additionalProperties: false,
  oneOf: [
    {properties: {bar: {type: "number"}}},
    {properties: {baz: {type: "number"}}}
  ]
}
```

The reason for that is that `additionalProperties` keyword ignores properties inside `oneOf` keyword subschemas. That's not the limitation of Ajv or any other validator, that's how it must work according to the standard.

There are several ways to implement the described logic that would allow two properties, please see the suggestions in the issues mentioned above.

#### Why the validation fails when I use option `removeAdditional` with the keyword `anyOf`/etc.?

This problem is related to the problem explained above - properties treated as additional in the sense of `additionalProperties` keyword, based on `properties`/`patternProperties` keyword in the same schema object.

See the example in the [Removing Additional Data](https://ajv.js.org/guide/modifying-data.html#removing-additional-properties) section of the docs.

## Generating schemas with resolved references ($ref)

See [#22](https://github.com/ajv-validator/ajv/issues/22), [#125](https://github.com/ajv-validator/ajv/issues/125), [#146](https://github.com/ajv-validator/ajv/issues/146), [#228](https://github.com/ajv-validator/ajv/issues/228), [#336](https://github.com/ajv-validator/ajv/issues/336), [#454](https://github.com/ajv-validator/ajv/issues/454).

#### Why Ajv does not replace references ($ref) with the actual referenced schemas as some validators do?

1. The scope of Ajv is validating data against JSON Schemas; inlining referenced schemas is not necessary for validation. When Ajv generates code for validation it either inlines the code of referenced schema or uses function calls. Doing schema manipulation is more complex and out of scope.
2. When schemas are recursive (or mutually recursive) resolving references would result in self-referencing recursive data-structures that can be difficult to process.
3. There are cases when such inlining would also require adding (or modifying) `id` attribute in the inlined schema fragment to make the resulting schema equivalent.

There were many conversations about the meaning of `$ref` in [JSON Schema GitHub organisation](https://github.com/json-schema-org). The consensus is that while it is possible to treat `$ref` as schema inclusion with two caveats (above), this interpretation is unnecessary complex. A more efficient approach is to treat `$ref` as a delegation, i.e. a special keyword that validates the current data instance against the referenced schema. The analogy with programming languages is that `$ref` is a function call rather than a macro. See [here](https://github.com/json-schema-org/json-schema-spec/issues/279), for example.

#### How can I generate a schema where `$ref` keywords are replaced with referenced schemas?

There are two possible approaches:

1. Traverse schema (e.g. with json-schema-traverse) and replace every `$ref` with the referenced schema.
2. Use a specially constructed JSON Schema with a [user-defined keyword](./keywords.md) to traverse and modify your schema.


================================================
FILE: docs/guide/async-validation.md
================================================
# Asynchronous validation

You can define formats and keywords that perform validation asynchronously by accessing database or some other service. You should add `async: true` in the keyword or format definition (see [addFormat](./api.md#api-addformat), [addKeyword](./api.md#api-addkeyword) and [User-defined keywords](./keywords.md)).

If your schema uses asynchronous formats/keywords or refers to some schema that contains them it should have `"$async": true` keyword so that Ajv can compile it correctly. If asynchronous format/keyword or reference to asynchronous schema is used in the schema without `$async` keyword Ajv will throw an exception during schema compilation.

::: warning Use $async: true in referenced schemas
All asynchronous subschemas that are referenced from the current or other schemas should have `"$async": true` keyword as well, otherwise the schema compilation will fail.
:::

Validation function for an asynchronous format/keyword should return a promise that resolves with `true` or `false` (or
Download .txt
gitextract_hfo2xbb4/

├── .eslintrc.js
├── .github/
│   ├── CODEOWNERS
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-or-error-report.md
│   │   ├── change.md
│   │   ├── compatibility.md
│   │   ├── installation.md
│   │   └── typescript.md
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── config.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── build.yml
│       └── publish.yml
├── .gitignore
├── .gitmodules
├── .npmrc
├── .prettierignore
├── .runkit_example.js
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── benchmark/
│   ├── jtd.js
│   └── package.json
├── bower.json
├── docs/
│   ├── .vuepress/
│   │   ├── components/
│   │   │   ├── Button.vue
│   │   │   ├── Column.vue
│   │   │   ├── Columns.vue
│   │   │   ├── Contributors.vue
│   │   │   ├── Feature.vue
│   │   │   ├── Features.vue
│   │   │   ├── FooterColumn.vue
│   │   │   ├── FooterColumns.vue
│   │   │   ├── GitHub.vue
│   │   │   ├── HeroSection.vue
│   │   │   ├── HomePage.vue
│   │   │   ├── HomeSection.vue
│   │   │   ├── NewsHome.vue
│   │   │   ├── NewsIndex.vue
│   │   │   ├── NewsPost.vue
│   │   │   ├── NewsPostMeta.vue
│   │   │   ├── Projects.vue
│   │   │   ├── Sponsors.vue
│   │   │   ├── Subscribe.vue
│   │   │   ├── Testimonial.vue
│   │   │   └── Testimonials.vue
│   │   ├── config.js
│   │   ├── styles/
│   │   │   ├── index.styl
│   │   │   └── palette.styl
│   │   └── theme/
│   │       ├── LICENSE
│   │       ├── components/
│   │       │   ├── AlgoliaSearchBox.vue
│   │       │   ├── DropdownLink.vue
│   │       │   ├── DropdownTransition.vue
│   │       │   ├── Home.vue
│   │       │   ├── NavLink.vue
│   │       │   ├── NavLinks.vue
│   │       │   ├── Navbar.vue
│   │       │   ├── Page.vue
│   │       │   ├── PageEdit.vue
│   │       │   ├── PageNav.vue
│   │       │   ├── Sidebar.vue
│   │       │   ├── SidebarButton.vue
│   │       │   ├── SidebarGroup.vue
│   │       │   ├── SidebarLink.vue
│   │       │   └── SidebarLinks.vue
│   │       ├── global-components/
│   │       │   ├── Badge.vue
│   │       │   ├── CodeBlock.vue
│   │       │   └── CodeGroup.vue
│   │       ├── index.js
│   │       ├── layouts/
│   │       │   ├── 404.vue
│   │       │   └── Layout.vue
│   │       ├── noopModule.js
│   │       ├── styles/
│   │       │   ├── arrow.styl
│   │       │   ├── code.styl
│   │       │   ├── config.styl
│   │       │   ├── custom-blocks.styl
│   │       │   ├── index.styl
│   │       │   ├── mobile.styl
│   │       │   ├── toc.styl
│   │       │   └── wrapper.styl
│   │       └── util/
│   │           └── index.js
│   ├── README.md
│   ├── api.md
│   ├── codegen.md
│   ├── coercion.md
│   ├── components.md
│   ├── faq.md
│   ├── guide/
│   │   ├── async-validation.md
│   │   ├── combining-schemas.md
│   │   ├── environments.md
│   │   ├── formats.md
│   │   ├── getting-started.md
│   │   ├── managing-schemas.md
│   │   ├── modifying-data.md
│   │   ├── schema-language.md
│   │   ├── typescript.md
│   │   ├── user-keywords.md
│   │   └── why-ajv.md
│   ├── json-schema.md
│   ├── json-type-definition.md
│   ├── keywords.md
│   ├── news/
│   │   ├── 2020-08-14-mozilla-grant-openjs-foundation.md
│   │   ├── 2020-12-15-ajv-version-7-released.md
│   │   ├── 2021-03-07-ajv-supports-json-type-definition.md
│   │   ├── 2021-03-27-ajv-version-8-released.md
│   │   ├── 2021-04-24-ajv-online-event.md
│   │   ├── 2021-05-24-ajv-online-event-video.md
│   │   ├── 2021-07-22-ajv-microsoft-foss-fund-award.md
│   │   └── README.md
│   ├── options.md
│   ├── packages/
│   │   └── README.md
│   ├── security.md
│   ├── standalone.md
│   ├── strict-mode.md
│   ├── testimonials.md
│   └── v6-to-v8-migration.md
├── karma.conf.js
├── lib/
│   ├── 2019.ts
│   ├── 2020.ts
│   ├── ajv.ts
│   ├── compile/
│   │   ├── codegen/
│   │   │   ├── code.ts
│   │   │   ├── index.ts
│   │   │   └── scope.ts
│   │   ├── errors.ts
│   │   ├── index.ts
│   │   ├── jtd/
│   │   │   ├── parse.ts
│   │   │   ├── serialize.ts
│   │   │   └── types.ts
│   │   ├── names.ts
│   │   ├── ref_error.ts
│   │   ├── resolve.ts
│   │   ├── rules.ts
│   │   ├── util.ts
│   │   └── validate/
│   │       ├── applicability.ts
│   │       ├── boolSchema.ts
│   │       ├── dataType.ts
│   │       ├── defaults.ts
│   │       ├── index.ts
│   │       ├── keyword.ts
│   │       └── subschema.ts
│   ├── core.ts
│   ├── jtd.ts
│   ├── refs/
│   │   ├── data.json
│   │   ├── json-schema-2019-09/
│   │   │   ├── index.ts
│   │   │   ├── meta/
│   │   │   │   ├── applicator.json
│   │   │   │   ├── content.json
│   │   │   │   ├── core.json
│   │   │   │   ├── format.json
│   │   │   │   ├── meta-data.json
│   │   │   │   └── validation.json
│   │   │   └── schema.json
│   │   ├── json-schema-2020-12/
│   │   │   ├── index.ts
│   │   │   ├── meta/
│   │   │   │   ├── applicator.json
│   │   │   │   ├── content.json
│   │   │   │   ├── core.json
│   │   │   │   ├── format-annotation.json
│   │   │   │   ├── meta-data.json
│   │   │   │   ├── unevaluated.json
│   │   │   │   └── validation.json
│   │   │   └── schema.json
│   │   ├── json-schema-draft-06.json
│   │   ├── json-schema-draft-07.json
│   │   ├── json-schema-secure.json
│   │   └── jtd-schema.ts
│   ├── runtime/
│   │   ├── equal.ts
│   │   ├── parseJson.ts
│   │   ├── quote.ts
│   │   ├── re2.ts
│   │   ├── timestamp.ts
│   │   ├── ucs2length.ts
│   │   ├── uri.ts
│   │   └── validation_error.ts
│   ├── standalone/
│   │   ├── index.ts
│   │   └── instance.ts
│   ├── types/
│   │   ├── index.ts
│   │   ├── json-schema.ts
│   │   └── jtd-schema.ts
│   └── vocabularies/
│       ├── applicator/
│       │   ├── additionalItems.ts
│       │   ├── additionalProperties.ts
│       │   ├── allOf.ts
│       │   ├── anyOf.ts
│       │   ├── contains.ts
│       │   ├── dependencies.ts
│       │   ├── dependentSchemas.ts
│       │   ├── if.ts
│       │   ├── index.ts
│       │   ├── items.ts
│       │   ├── items2020.ts
│       │   ├── not.ts
│       │   ├── oneOf.ts
│       │   ├── patternProperties.ts
│       │   ├── prefixItems.ts
│       │   ├── properties.ts
│       │   ├── propertyNames.ts
│       │   └── thenElse.ts
│       ├── code.ts
│       ├── core/
│       │   ├── id.ts
│       │   ├── index.ts
│       │   └── ref.ts
│       ├── discriminator/
│       │   ├── index.ts
│       │   └── types.ts
│       ├── draft2020.ts
│       ├── draft7.ts
│       ├── dynamic/
│       │   ├── dynamicAnchor.ts
│       │   ├── dynamicRef.ts
│       │   ├── index.ts
│       │   ├── recursiveAnchor.ts
│       │   └── recursiveRef.ts
│       ├── errors.ts
│       ├── format/
│       │   ├── format.ts
│       │   └── index.ts
│       ├── jtd/
│       │   ├── discriminator.ts
│       │   ├── elements.ts
│       │   ├── enum.ts
│       │   ├── error.ts
│       │   ├── index.ts
│       │   ├── metadata.ts
│       │   ├── nullable.ts
│       │   ├── optionalProperties.ts
│       │   ├── properties.ts
│       │   ├── ref.ts
│       │   ├── type.ts
│       │   ├── union.ts
│       │   └── values.ts
│       ├── metadata.ts
│       ├── next.ts
│       ├── unevaluated/
│       │   ├── index.ts
│       │   ├── unevaluatedItems.ts
│       │   └── unevaluatedProperties.ts
│       └── validation/
│           ├── const.ts
│           ├── dependentRequired.ts
│           ├── enum.ts
│           ├── index.ts
│           ├── limitContains.ts
│           ├── limitItems.ts
│           ├── limitLength.ts
│           ├── limitNumber.ts
│           ├── limitProperties.ts
│           ├── multipleOf.ts
│           ├── pattern.ts
│           ├── required.ts
│           └── uniqueItems.ts
├── package.json
├── rollup.config.js
├── scripts/
│   ├── .eslintrc.yml
│   ├── bundle.js
│   ├── get-ajv-packages
│   ├── get-contributors.js
│   ├── jsontests.js
│   ├── prepare-site
│   ├── prepare-tests
│   ├── publish-bundles
│   └── publish-site
├── spec/
│   ├── .eslintrc.yml
│   ├── _json/
│   │   └── README.md
│   ├── after_test.ts
│   ├── ajv.spec.ts
│   ├── ajv.ts
│   ├── ajv2019.ts
│   ├── ajv2020.ts
│   ├── ajv_all_instances.ts
│   ├── ajv_async_instances.ts
│   ├── ajv_instances.ts
│   ├── ajv_jtd.ts
│   ├── ajv_options.ts
│   ├── ajv_standalone.ts
│   ├── async/
│   │   ├── boolean.json
│   │   ├── compound.json
│   │   ├── format.json
│   │   ├── items.json
│   │   ├── keyword.json
│   │   ├── no_async.json
│   │   └── properties.json
│   ├── async.spec.ts
│   ├── async_schemas.spec.ts
│   ├── async_validate.spec.ts
│   ├── boolean.spec.ts
│   ├── chai.ts
│   ├── chai_type.ts
│   ├── codegen.spec.ts
│   ├── coercion.spec.ts
│   ├── discriminator.spec.ts
│   ├── dynamic-ref.spec.ts
│   ├── errors.spec.ts
│   ├── extras/
│   │   ├── $data/
│   │   │   ├── absolute_ref.json
│   │   │   ├── const.json
│   │   │   ├── enum.json
│   │   │   ├── exclusiveMaximum.json
│   │   │   ├── exclusiveMinimum.json
│   │   │   ├── format.json
│   │   │   ├── maxItems.json
│   │   │   ├── maxLength.json
│   │   │   ├── maxProperties.json
│   │   │   ├── maximum.json
│   │   │   ├── minItems.json
│   │   │   ├── minLength.json
│   │   │   ├── minProperties.json
│   │   │   ├── minimum.json
│   │   │   ├── multipleOf.json
│   │   │   ├── pattern.json
│   │   │   ├── required.json
│   │   │   └── uniqueItems.json
│   │   ├── const.json
│   │   ├── contains.json
│   │   ├── exclusiveMaximum.json
│   │   └── exclusiveMinimum.json
│   ├── extras.spec.ts
│   ├── issues/
│   │   ├── 1001_addKeyword_and_schema_without_id.spec.ts
│   │   ├── 1344_non_root_recursive_ref_standalone.spec.ts
│   │   ├── 1414_base_uri_change.spec.ts
│   │   ├── 1501_jtd_many_properties.spec.ts
│   │   ├── 1515_evaluated_properties_nested_anyof.spec.ts
│   │   ├── 1539_add_keyword_name_to_validation_error.spec.ts
│   │   ├── 1625_evaluated_truthy_pattern_properties.spec.ts
│   │   ├── 1683_re2_engine.spec.ts
│   │   ├── 1819_mincontains.spec.ts
│   │   ├── 181_allErrors_custom_keyword_skipped.spec.ts
│   │   ├── 182_nan_validation.spec.ts
│   │   ├── 1935_integer_narrowing_subschema.spec.ts
│   │   ├── 1949_jtd_empty_values.spec.ts
│   │   ├── 1971_jtd_discriminator.spec.ts
│   │   ├── 2001_jtd_only_optional_properties.spec.ts
│   │   ├── 204_options_schemas_data_together.spec.ts
│   │   ├── 210_mutual_recur_frags.spec.ts
│   │   ├── 240_mutual_recur_frags_common_ref.spec.ts
│   │   ├── 259_validate_meta_against_itself.spec.ts
│   │   ├── 273_error_schemaPath_refd_schema.spec.ts
│   │   ├── 342_uniqueItems_non-json_objects.spec.ts
│   │   ├── 485_type_validation_priority.spec.ts
│   │   ├── 50_refs_with_definitions.spec.ts
│   │   ├── 521_wrong_warning_id_property.spec.ts
│   │   ├── 743_removeAdditional_to_remove_proto.spec.ts
│   │   ├── 768_passContext_recursive_ref.spec.ts
│   │   ├── 815_id_updates_ref_base.spec.ts
│   │   ├── 8_shared_refs.spec.ts
│   │   ├── 955_removeAdditional_custom_keywords.spec.ts
│   │   ├── cve_2025_69873_redos_attack.spec.ts
│   │   └── re2.ts
│   ├── javacript.spec.js
│   ├── json-schema.spec.ts
│   ├── json_parse_tests.json
│   ├── jtd-schema.spec.ts
│   ├── jtd-timestamps.spec.ts
│   ├── keyword.spec.ts
│   ├── options/
│   │   ├── comment.spec.ts
│   │   ├── int32range.spec.ts
│   │   ├── meta_validateSchema.spec.ts
│   │   ├── nullable.spec.ts
│   │   ├── options_add_schemas.spec.ts
│   │   ├── options_code.spec.ts
│   │   ├── options_refs.spec.ts
│   │   ├── options_reporting.spec.ts
│   │   ├── options_validation.spec.ts
│   │   ├── ownProperties.spec.ts
│   │   ├── removeAdditional.spec.ts
│   │   ├── schemaId.spec.ts
│   │   ├── strict.spec.ts
│   │   ├── strictDefaults.spec.ts
│   │   ├── strictKeywords.spec.ts
│   │   ├── strictNumbers.spec.ts
│   │   ├── unicodeRegExp.spec.ts
│   │   ├── unknownFormats.spec.ts
│   │   └── useDefaults.spec.ts
│   ├── remotes/
│   │   ├── bar.json
│   │   ├── buu.json
│   │   ├── first.json
│   │   ├── foo.json
│   │   ├── hyper-schema.json
│   │   ├── name.json
│   │   ├── node.json
│   │   ├── scope_change.json
│   │   ├── second.json
│   │   └── tree.json
│   ├── resolve.spec.ts
│   ├── schema-tests.spec.ts
│   ├── security/
│   │   ├── array.json
│   │   ├── object.json
│   │   └── string.json
│   ├── security.spec.ts
│   ├── standalone.spec.ts
│   ├── tests/
│   │   ├── issues/
│   │   │   ├── 12_restoring_root_after_resolve.json
│   │   │   ├── 13_root_ref_in_ref_in_remote_ref.json
│   │   │   ├── 14_ref_in_remote_ref_with_id.json
│   │   │   ├── 1668_not_with_other_keywords.json
│   │   │   ├── 170_ref_and_id_in_sibling.json
│   │   │   ├── 17_escaping_pattern_property.json
│   │   │   ├── 19_required_many_properties.json
│   │   │   ├── 1_ids_in_refs.json
│   │   │   ├── 20_failing_to_parse_schema.json
│   │   │   ├── 226_json_with_control_chars.json
│   │   │   ├── 27_1_recursive_raml_schema.json
│   │   │   ├── 27_recursive_reference.json
│   │   │   ├── 28_escaping_pattern_error.json
│   │   │   ├── 2_root_ref_in_ref.json
│   │   │   ├── 311_quotes_in_refs.json
│   │   │   ├── 33_json_schema_latest.json
│   │   │   ├── 413_dependencies_with_quote.json
│   │   │   ├── 490_integer_validation.json
│   │   │   ├── 502_contains_empty_array_with_ref_in_another_property.json
│   │   │   ├── 5_adding_dependency_after.json
│   │   │   ├── 5_recursive_references.json
│   │   │   ├── 62_resolution_scope_change.json
│   │   │   ├── 63_id_property_not_in_schema.json
│   │   │   ├── 70_1_recursive_hash_ref_in_remote_ref.json
│   │   │   ├── 70_swagger_schema.json
│   │   │   ├── 861_empty_propertynames.json
│   │   │   ├── 87_$_property.json
│   │   │   └── 94_dependencies_fail.json
│   │   ├── rules/
│   │   │   ├── allOf.json
│   │   │   ├── anyOf.json
│   │   │   ├── comment.json
│   │   │   ├── dependencies.json
│   │   │   ├── format.json
│   │   │   ├── if.json
│   │   │   ├── items.json
│   │   │   ├── oneOf.json
│   │   │   ├── required.json
│   │   │   ├── type.json
│   │   │   └── uniqueItems.json
│   │   └── schemas/
│   │       ├── advanced.json
│   │       ├── basic.json
│   │       ├── complex.json
│   │       ├── complex2.json
│   │       ├── complex3.json
│   │       ├── cosmicrealms.json
│   │       └── medium.json
│   ├── tsconfig.json
│   └── types/
│       ├── async-validate.spec.ts
│       ├── error-parameters.spec.ts
│       ├── json-schema.spec.ts
│       └── jtd-schema.spec.ts
└── tsconfig.json
Download .txt
SYMBOL INDEX (1013 symbols across 152 files)

FILE: .runkit_example.js
  function test (line 19) | function test(data) {

FILE: docs/.vuepress/theme/index.js
  method alias (line 17) | alias() {

FILE: docs/.vuepress/theme/util/index.js
  function normalize (line 6) | function normalize(path) {
  function getHash (line 10) | function getHash(path) {
  function isExternal (line 17) | function isExternal(path) {
  function isMailto (line 21) | function isMailto(path) {
  function isTel (line 25) | function isTel(path) {
  function ensureExt (line 29) | function ensureExt(path) {
  function isActive (line 43) | function isActive(route, path) {
  function resolvePage (line 54) | function resolvePage(pages, rawPath, base) {
  function resolvePath (line 77) | function resolvePath(relative, base, append) {
  function resolveSidebarItems (line 122) | function resolveSidebarItems(page, regularPath, site, localePath) {
  function resolveHeaders (line 149) | function resolveHeaders(page) {
  function groupHeaders (line 168) | function groupHeaders(headers) {
  function resolveNavLinkItem (line 182) | function resolveNavLinkItem(linkItem) {
  function resolveMatchingConfig (line 193) | function resolveMatchingConfig(regularPath, config) {
  function ensureEndingSlash (line 211) | function ensureEndingSlash(path) {
  function resolveItem (line 215) | function resolveItem(item, pages, base, groupDepth = 1) {

FILE: lib/2019.ts
  constant META_SCHEMA_ID (line 11) | const META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema"
  class Ajv2019 (line 13) | class Ajv2019 extends AjvCore {
    method constructor (line 14) | constructor(opts: Options = {}) {
    method _addVocabularies (line 23) | _addVocabularies(): void {
    method _addDefaultMetaSchema (line 32) | _addDefaultMetaSchema(): void {
    method defaultMeta (line 40) | defaultMeta(): string | AnySchemaObject | undefined {

FILE: lib/2020.ts
  constant META_SCHEMA_ID (line 8) | const META_SCHEMA_ID = "https://json-schema.org/draft/2020-12/schema"
  class Ajv2020 (line 10) | class Ajv2020 extends AjvCore {
    method constructor (line 11) | constructor(opts: Options = {}) {
    method _addVocabularies (line 20) | _addVocabularies(): void {
    method _addDefaultMetaSchema (line 26) | _addDefaultMetaSchema(): void {
    method defaultMeta (line 34) | defaultMeta(): string | AnySchemaObject | undefined {

FILE: lib/ajv.ts
  constant META_SUPPORT_DATA (line 7) | const META_SUPPORT_DATA = ["/properties"]
  constant META_SCHEMA_ID (line 9) | const META_SCHEMA_ID = "http://json-schema.org/draft-07/schema"
  class Ajv (line 11) | class Ajv extends AjvCore {
    method _addVocabularies (line 12) | _addVocabularies(): void {
    method _addDefaultMetaSchema (line 18) | _addDefaultMetaSchema(): void {
    method defaultMeta (line 28) | defaultMeta(): string | AnySchemaObject | undefined {

FILE: lib/compile/codegen/code.ts
  constant IDENTIFIER (line 9) | const IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i
  class Name (line 11) | class Name extends _CodeOrName {
    method constructor (line 13) | constructor(s: string) {
    method toString (line 19) | toString(): string {
    method emptyStr (line 23) | emptyStr(): boolean {
    method names (line 27) | get names(): UsedNames {
  class _Code (line 32) | class _Code extends _CodeOrName {
    method constructor (line 37) | constructor(code: string | readonly CodeItem[]) {
    method toString (line 42) | toString(): string {
    method emptyStr (line 46) | emptyStr(): boolean {
    method str (line 52) | get str(): string {
    method names (line 56) | get names(): UsedNames {
  type CodeItem (line 64) | type CodeItem = Name | string | number | boolean | null
  type UsedNames (line 66) | type UsedNames = Record<string, number | undefined>
  type Code (line 68) | type Code = _Code | Name
  type SafeExpr (line 70) | type SafeExpr = Code | number | boolean | null
  type CodeArg (line 74) | type CodeArg = SafeExpr | string | undefined
  function _ (line 76) | function _(strs: TemplateStringsArray, ...args: CodeArg[]): _Code {
  function str (line 88) | function str(strs: TemplateStringsArray, ...args: (CodeArg | string[])[]...
  function addCodeArg (line 100) | function addCodeArg(code: CodeItem[], arg: CodeArg | string[]): void {
  function optimize (line 106) | function optimize(expr: CodeItem[]): void {
  function mergeExprItems (line 121) | function mergeExprItems(a: CodeItem, b: CodeItem): CodeItem | undefined {
  function strConcat (line 134) | function strConcat(c1: Code, c2: Code): Code {
  function interpolate (line 139) | function interpolate(x?: string | string[] | number | boolean | null): S...
  function stringify (line 145) | function stringify(x: unknown): Code {
  function safeStringify (line 149) | function safeStringify(x: unknown): string {
  function getProperty (line 155) | function getProperty(key: Code | string | number): Code {
  function getEsmExportName (line 160) | function getEsmExportName(key: Code | string | number): Code {
  function regexpCode (line 167) | function regexpCode(rx: RegExp): Code {

FILE: lib/compile/codegen/index.ts
  type SafeExpr (line 9) | type SafeExpr = Code | number | boolean | null
  type Block (line 12) | type Block = Code | (() => void)
  method optimizeNodes (line 30) | optimizeNodes(): this | ChildNode | ChildNode[] | undefined {
  method optimizeNames (line 34) | optimizeNames(_names: UsedNames, _constants: Constants): this | undefined {
  class Def (line 43) | class Def extends Node {
    method constructor (line 44) | constructor(
    method render (line 52) | render({es5, _n}: CGOptions): string {
    method optimizeNames (line 58) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
    method names (line 64) | get names(): UsedNames {
  class Assign (line 69) | class Assign extends Node {
    method constructor (line 70) | constructor(
    method render (line 78) | render({_n}: CGOptions): string {
    method optimizeNames (line 82) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
    method names (line 88) | get names(): UsedNames {
  class AssignOp (line 94) | class AssignOp extends Assign {
    method constructor (line 95) | constructor(
    method render (line 104) | render({_n}: CGOptions): string {
  class Label (line 109) | class Label extends Node {
    method constructor (line 111) | constructor(readonly label: Name) {
    method render (line 115) | render({_n}: CGOptions): string {
  class Break (line 120) | class Break extends Node {
    method constructor (line 122) | constructor(readonly label?: Code) {
    method render (line 126) | render({_n}: CGOptions): string {
  class Throw (line 132) | class Throw extends Node {
    method constructor (line 133) | constructor(readonly error: Code) {
    method render (line 137) | render({_n}: CGOptions): string {
    method names (line 141) | get names(): UsedNames {
  class AnyCode (line 146) | class AnyCode extends Node {
    method constructor (line 147) | constructor(private code: SafeExpr) {
    method render (line 151) | render({_n}: CGOptions): string {
    method optimizeNodes (line 155) | optimizeNodes(): this | undefined {
    method optimizeNames (line 159) | optimizeNames(names: UsedNames, constants: Constants): this {
    method names (line 164) | get names(): UsedNames {
  method constructor (line 170) | constructor(readonly nodes: ChildNode[] = []) {
  method render (line 174) | render(opts: CGOptions): string {
  method optimizeNodes (line 178) | optimizeNodes(): this | ChildNode | ChildNode[] | undefined {
  method optimizeNames (line 190) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
  method names (line 203) | get names(): UsedNames {
  method render (line 213) | render(opts: CGOptions): string {
  class Root (line 218) | class Root extends ParentNode {}
  class Else (line 220) | class Else extends BlockNode {
  class If (line 224) | class If extends BlockNode {
    method constructor (line 227) | constructor(
    method render (line 234) | render(opts: CGOptions): string {
    method optimizeNodes (line 240) | optimizeNodes(): If | ChildNode[] | undefined {
    method optimizeNames (line 258) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
    method names (line 265) | get names(): UsedNames {
  class ForLoop (line 281) | class ForLoop extends For {
    method constructor (line 282) | constructor(private iteration: Code) {
    method render (line 286) | render(opts: CGOptions): string {
    method optimizeNames (line 290) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
    method names (line 296) | get names(): UsedNames {
  class ForRange (line 301) | class ForRange extends For {
    method constructor (line 302) | constructor(
    method render (line 311) | render(opts: CGOptions): string {
    method names (line 317) | get names(): UsedNames {
  class ForIter (line 323) | class ForIter extends For {
    method constructor (line 324) | constructor(
    method render (line 333) | render(opts: CGOptions): string {
    method optimizeNames (line 337) | optimizeNames(names: UsedNames, constants: Constants): this | undefined {
    method names (line 343) | get names(): UsedNames {
  class Func (line 348) | class Func extends BlockNode {
    method constructor (line 350) | constructor(
    method render (line 358) | render(opts: CGOptions): string {
  class Return (line 364) | class Return extends ParentNode {
    method render (line 367) | render(opts: CGOptions): string {
  class Try (line 372) | class Try extends BlockNode {
    method render (line 376) | render(opts: CGOptions): string {
    method optimizeNodes (line 383) | optimizeNodes(): this {
    method optimizeNames (line 390) | optimizeNames(names: UsedNames, constants: Constants): this {
    method names (line 397) | get names(): UsedNames {
  class Catch (line 409) | class Catch extends BlockNode {
    method constructor (line 411) | constructor(readonly error: Name) {
    method render (line 415) | render(opts: CGOptions): string {
  class Finally (line 420) | class Finally extends BlockNode {
    method render (line 422) | render(opts: CGOptions): string {
  type StartBlockNode (line 427) | type StartBlockNode = If | For | Func | Return | Try
  type LeafNode (line 429) | type LeafNode = Def | Assign | Label | Break | Throw | AnyCode
  type ChildNode (line 431) | type ChildNode = StartBlockNode | LeafNode
  type EndBlockNodeType (line 433) | type EndBlockNodeType =
  type Constants (line 442) | type Constants = Record<string, SafeExpr | undefined>
  type CodeGenOptions (line 444) | interface CodeGenOptions {
  type CGOptions (line 450) | interface CGOptions extends CodeGenOptions {
  class CodeGen (line 454) | class CodeGen {
    method constructor (line 463) | constructor(extScope: ValueScope, opts: CodeGenOptions = {}) {
    method toString (line 470) | toString(): string {
    method name (line 475) | name(prefix: string): Name {
    method scopeName (line 480) | scopeName(prefix: string): ValueScopeName {
    method scopeValue (line 485) | scopeValue(prefixOrName: ValueScopeName | string, value: NameValue): N...
    method getScopeValue (line 492) | getScopeValue(prefix: string, keyOrRef: unknown): ValueScopeName | und...
    method scopeRefs (line 498) | scopeRefs(scopeName: Name): Code {
    method scopeCode (line 502) | scopeCode(): Code {
    method _def (line 506) | private _def(
    method const (line 519) | const(nameOrPrefix: Name | string, rhs: SafeExpr, _constant?: boolean)...
    method let (line 524) | let(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean):...
    method var (line 529) | var(nameOrPrefix: Name | string, rhs?: SafeExpr, _constant?: boolean):...
    method assign (line 534) | assign(lhs: Code, rhs: SafeExpr, sideEffects?: boolean): CodeGen {
    method add (line 539) | add(lhs: Code, rhs: SafeExpr): CodeGen {
    method code (line 544) | code(c: Block | SafeExpr): CodeGen {
    method object (line 551) | object(...keyValues: [Name | string, SafeExpr | string][]): _Code {
    method if (line 566) | if(condition: Code | boolean, thenBody?: Block, elseBody?: Block): Cod...
    method elseIf (line 580) | elseIf(condition: Code | boolean): CodeGen {
    method else (line 585) | else(): CodeGen {
    method endIf (line 590) | endIf(): CodeGen {
    method _for (line 594) | private _for(node: For, forBody?: Block): CodeGen {
    method for (line 601) | for(iteration: Code, forBody?: Block): CodeGen {
    method forRange (line 606) | forRange(
    method forOf (line 618) | forOf(
    method forIn (line 637) | forIn(
    method endFor (line 651) | endFor(): CodeGen {
    method label (line 656) | label(label: Name): CodeGen {
    method break (line 661) | break(label?: Code): CodeGen {
    method return (line 666) | return(value: Block | SafeExpr): CodeGen {
    method try (line 675) | try(tryBody: Block, catchCode?: (e: Name) => void, finallyCode?: Block...
    method throw (line 693) | throw(error: Code): CodeGen {
    method block (line 698) | block(body?: Block, nodeCount?: number): CodeGen {
    method endBlock (line 705) | endBlock(nodeCount?: number): CodeGen {
    method func (line 717) | func(name: Name, args: Code = nil, async?: boolean, funcBody?: Block):...
    method endFunc (line 724) | endFunc(): CodeGen {
    method optimize (line 728) | optimize(n = 1): void {
    method _leafNode (line 735) | private _leafNode(node: LeafNode): CodeGen {
    method _blockNode (line 740) | private _blockNode(node: StartBlockNode): void {
    method _endBlockNode (line 745) | private _endBlockNode(N1: EndBlockNodeType, N2?: EndBlockNodeType): Co...
    method _elseNode (line 754) | private _elseNode(node: If | Else): CodeGen {
    method _root (line 763) | private get _root(): Root {
    method _currNode (line 767) | private get _currNode(): ParentNode {
    method _currNode (line 772) | private set _currNode(node: ParentNode) {
  function addNames (line 782) | function addNames(names: UsedNames, from: UsedNames): UsedNames {
  function addExprNames (line 787) | function addExprNames(names: UsedNames, from: SafeExpr): UsedNames {
  function optimizeExpr (line 792) | function optimizeExpr(expr: SafeExpr, names: UsedNames, constants: Const...
  function subtractNames (line 821) | function subtractNames(names: UsedNames, from: UsedNames): void {
  function not (line 826) | function not(x: Code | SafeExpr): Code | SafeExpr {
  function and (line 833) | function and(...args: Code[]): Code {
  function or (line 840) | function or(...args: Code[]): Code {
  type MAppend (line 844) | type MAppend = (x: Code, y: Code) => Code
  function mappend (line 846) | function mappend(op: Code): MAppend {
  function par (line 850) | function par(x: Code): Code {

FILE: lib/compile/codegen/scope.ts
  type NameGroup (line 3) | interface NameGroup {
  type NameValue (line 8) | interface NameValue {
  type ValueReference (line 14) | type ValueReference = unknown // possibly make CodeGen parameterized typ...
  class ValueError (line 16) | class ValueError extends Error {
    method constructor (line 18) | constructor(name: ValueScopeName) {
  type ScopeOptions (line 24) | interface ScopeOptions {
  type ValueScopeOptions (line 29) | interface ValueScopeOptions extends ScopeOptions {
  type ScopeStore (line 35) | type ScopeStore = Record<string, ValueReference[] | undefined>
  type ScopeValues (line 37) | type ScopeValues = {
  type ScopeValueSets (line 41) | type ScopeValueSets = {
  type UsedValueState (line 45) | enum UsedValueState {
  type UsedScopeValues (line 50) | type UsedScopeValues = {
  class Scope (line 60) | class Scope {
    method constructor (line 65) | constructor({prefixes, parent}: ScopeOptions = {}) {
    method toName (line 70) | toName(nameOrPrefix: Name | string): Name {
    method name (line 74) | name(prefix: string): Name {
    method _newName (line 78) | protected _newName(prefix: string): string {
    method _nameGroup (line 83) | private _nameGroup(prefix: string): NameGroup {
  type ScopePath (line 91) | interface ScopePath {
  class ValueScopeName (line 96) | class ValueScopeName extends Name {
    method constructor (line 101) | constructor(prefix: string, nameStr: string) {
    method setValue (line 106) | setValue(value: NameValue, {property, itemIndex}: ScopePath): void {
  type VSOptions (line 112) | interface VSOptions extends ValueScopeOptions {
  class ValueScope (line 118) | class ValueScope extends Scope {
    method constructor (line 123) | constructor(opts: ValueScopeOptions) {
    method get (line 129) | get(): ScopeStore {
    method name (line 133) | name(prefix: string): ValueScopeName {
    method value (line 137) | value(nameOrPrefix: ValueScopeName | string, value: NameValue): ValueS...
    method getValue (line 158) | getValue(prefix: string, keyOrRef: unknown): ValueScopeName | undefined {
    method scopeRefs (line 164) | scopeRefs(scopeName: Name, values: ScopeValues | ScopeValueSets = this...
    method scopeCode (line 171) | scopeCode(
    method _reduceValues (line 187) | private _reduceValues(

FILE: lib/compile/errors.ts
  type ErrorPaths (line 19) | interface ErrorPaths {
  function reportError (line 25) | function reportError(
  function reportExtraError (line 41) | function reportExtraError(
  function resetErrorsCount (line 55) | function resetErrorsCount(gen: CodeGen, errsCount: Name): void {
  function extendErrors (line 66) | function extendErrors({
  function addError (line 90) | function addError(gen: CodeGen, errObj: Code): void {
  function returnErrors (line 100) | function returnErrors(it: SchemaCxt, errs: Code): void {
  function errorObjectCode (line 120) | function errorObjectCode(
  function errorObject (line 130) | function errorObject(
  function errorInstancePath (line 144) | function errorInstancePath({errorPath}: SchemaCxt, {instancePath}: Error...
  function errorSchemaPath (line 151) | function errorSchemaPath(
  function extraErrorProps (line 162) | function extraErrorProps(

FILE: lib/compile/index.ts
  type SchemaRefs (line 20) | type SchemaRefs = {
  type SchemaCxt (line 24) | interface SchemaCxt {
  type SchemaObjCxt (line 61) | interface SchemaObjCxt extends SchemaCxt {
  type SchemaEnvArgs (line 64) | interface SchemaEnvArgs {
  class SchemaEnv (line 74) | class SchemaEnv implements SchemaEnvArgs {
    method constructor (line 92) | constructor(env: SchemaEnvArgs) {
  function compileSchema (line 111) | function compileSchema(this: Ajv, sch: SchemaEnv): SchemaEnv {
  function resolveRef (line 205) | function resolveRef(
  function inlineOrCompile (line 226) | function inlineOrCompile(this: Ajv, sch: SchemaEnv): AnySchema | SchemaE...
  function getCompilingSchema (line 232) | function getCompilingSchema(this: Ajv, schEnv: SchemaEnv): SchemaEnv | v...
  function sameSchemaEnv (line 238) | function sameSchemaEnv(s1: SchemaEnv, s2: SchemaEnv): boolean {
  function resolve (line 244) | function resolve(
  function resolveSchema (line 255) | function resolveSchema(
  constant PREVENT_SCOPE_CHANGE (line 288) | const PREVENT_SCOPE_CHANGE = new Set([
  function getJsonPointer (line 296) | function getJsonPointer(

FILE: lib/compile/jtd/parse.ts
  type GenParse (line 15) | type GenParse = (cxt: ParseCxt) => void
  type ParseCxt (line 28) | interface ParseCxt {
  function compileParser (line 39) | function compileParser(
  function parserFunction (line 86) | function parserFunction(cxt: ParseCxt): void {
  function parseCode (line 106) | function parseCode(cxt: ParseCxt): void {
  function parseNullable (line 120) | function parseNullable(cxt: ParseCxt, parseForm: GenParse): void {
  function parseElements (line 126) | function parseElements(cxt: ParseCxt): void {
  function parseValues (line 138) | function parseValues(cxt: ParseCxt): void {
  function parseItems (line 145) | function parseItems(cxt: ParseCxt, endToken: string, block: () => void):...
  function tryParseItems (line 150) | function tryParseItems(cxt: ParseCxt, endToken: string, block: () => voi...
  function parseKeyValue (line 162) | function parseKeyValue(cxt: ParseCxt, schema: SchemaObject): void {
  function parseDiscriminator (line 170) | function parseDiscriminator(cxt: ParseCxt): void {
  function parseProperties (line 204) | function parseProperties(cxt: ParseCxt): void {
  function parseSchemaProperties (line 211) | function parseSchemaProperties(cxt: ParseCxt, discriminator?: string): v...
  function parseDefinedProperty (line 243) | function parseDefinedProperty(cxt: ParseCxt, key: Name, schemas: SchemaO...
  function parsePropertyValue (line 251) | function parsePropertyValue(cxt: ParseCxt, key: Name, schema: SchemaObje...
  function parseType (line 255) | function parseType(cxt: ParseCxt): void {
  function parseString (line 297) | function parseString(cxt: ParseCxt): void {
  function parseEnum (line 302) | function parseEnum(cxt: ParseCxt): void {
  function parseNumber (line 319) | function parseNumber(cxt: ParseCxt, maxDigits?: number): void {
  function parseBooleanToken (line 329) | function parseBooleanToken(bool: boolean, fail: GenParse): GenParse {
  function parseRef (line 341) | function parseRef(cxt: ParseCxt): void {
  function getParser (line 352) | function getParser(gen: CodeGen, sch: SchemaEnv): Code {
  function parseEmpty (line 358) | function parseEmpty(cxt: ParseCxt): void {
  function parseWith (line 362) | function parseWith(cxt: ParseCxt, parseFunc: {code: string}, args?: Safe...
  function partialParse (line 366) | function partialParse(cxt: ParseCxt, parseFunc: Name, args?: SafeExpr): ...
  function parseToken (line 373) | function parseToken(cxt: ParseCxt, tok: string): void {
  function tryParseToken (line 377) | function tryParseToken(cxt: ParseCxt, tok: string, fail: GenParse, succe...
  function skipWhitespace (line 391) | function skipWhitespace({gen, char: c}: ParseCxt): void {
  function jsonSlice (line 397) | function jsonSlice(len: number | Name): Code {
  function jsonSyntaxError (line 403) | function jsonSyntaxError(cxt: ParseCxt): void {
  function parsingError (line 407) | function parsingError({gen, parseName}: ParseCxt, msg: Code): void {

FILE: lib/compile/jtd/serialize.ts
  type SerializeCxt (line 24) | interface SerializeCxt {
  function compileSerializer (line 33) | function compileSerializer(
  function serializeCode (line 80) | function serializeCode(cxt: SerializeCxt): void {
  function serializeNullable (line 91) | function serializeNullable(cxt: SerializeCxt, serializeForm: (_cxt: Seri...
  function serializeElements (line 101) | function serializeElements(cxt: SerializeCxt): void {
  function serializeValues (line 112) | function serializeValues(cxt: SerializeCxt): void {
  function serializeKeyValue (line 120) | function serializeKeyValue(cxt: SerializeCxt, key: Name, schema: SchemaO...
  function serializeDiscriminator (line 129) | function serializeDiscriminator(cxt: SerializeCxt): void {
  function serializeProperties (line 145) | function serializeProperties(cxt: SerializeCxt): void {
  function serializeSchemaProperties (line 152) | function serializeSchemaProperties(cxt: SerializeCxt, discriminator?: st...
  function serializeType (line 206) | function serializeType(cxt: SerializeCxt): void {
  function serializeString (line 227) | function serializeString({gen, data}: SerializeCxt): void {
  function serializeNumber (line 231) | function serializeNumber({gen, data, self}: SerializeCxt): void {
  function serializeRef (line 246) | function serializeRef(cxt: SerializeCxt): void {
  function getSerialize (line 257) | function getSerialize(gen: CodeGen, sch: SchemaEnv): Code {
  function serializeEmpty (line 263) | function serializeEmpty({gen, data}: SerializeCxt): void {
  function addComma (line 267) | function addComma({gen}: SerializeCxt, first?: Name): void {

FILE: lib/compile/jtd/types.ts
  type SchemaObjectMap (line 3) | type SchemaObjectMap = {[Ref in string]?: SchemaObject}
  type JTDForm (line 16) | type JTDForm = (typeof jtdForms)[number]

FILE: lib/compile/ref_error.ts
  class MissingRefError (line 4) | class MissingRefError extends Error {
    method constructor (line 8) | constructor(resolver: UriResolver, baseId: string, ref: string, msg?: ...

FILE: lib/compile/resolve.ts
  type LocalRefs (line 9) | type LocalRefs = {[Ref in string]?: AnySchemaObject}
  constant SIMPLE_INLINED (line 12) | const SIMPLE_INLINED = new Set([
  function inlineRef (line 31) | function inlineRef(schema: AnySchema, limit: boolean | number = true): b...
  constant REF_KEYWORDS (line 38) | const REF_KEYWORDS = new Set([
  function hasRef (line 46) | function hasRef(schema: AnySchemaObject): boolean {
  function countKeys (line 56) | function countKeys(schema: AnySchemaObject): number {
  function getFullPath (line 70) | function getFullPath(resolver: UriResolver, id = "", normalize?: boolean...
  function _getFullPath (line 76) | function _getFullPath(resolver: UriResolver, p: URIComponent): string {
  constant TRAILING_SLASH_HASH (line 81) | const TRAILING_SLASH_HASH = /#\/?$/
  function normalizeId (line 82) | function normalizeId(id: string | undefined): string {
  function resolveUrl (line 86) | function resolveUrl(resolver: UriResolver, baseId: string, id: string): ...
  constant ANCHOR (line 91) | const ANCHOR = /^[a-z_][-a-z0-9._]*$/i
  function getSchemaRefs (line 93) | function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): Lo...

FILE: lib/compile/rules.ts
  type JSONType (line 5) | type JSONType = (typeof _jsonTypes)[number]
  function isJSONType (line 9) | function isJSONType(x: unknown): x is JSONType {
  type ValidationTypes (line 13) | type ValidationTypes = {
  type ValidationRules (line 17) | interface ValidationRules {
  type RuleGroup (line 25) | interface RuleGroup {
  type Rule (line 31) | interface Rule {
  function getRules (line 36) | function getRules(): ValidationRules {

FILE: lib/compile/util.ts
  function toHash (line 8) | function toHash<T extends string = string>(arr: T[]): {[K in T]?: true} {
  function alwaysValidSchema (line 14) | function alwaysValidSchema(it: SchemaCxt, schema: AnySchema): boolean | ...
  function checkUnknownRules (line 21) | function checkUnknownRules(it: SchemaCxt, schema: AnySchema = it.schema)...
  function schemaHasRules (line 31) | function schemaHasRules(
  function schemaHasRulesButRef (line 40) | function schemaHasRulesButRef(schema: AnySchema, RULES: ValidationRules)...
  function schemaRefOrVal (line 46) | function schemaRefOrVal(
  function unescapeFragment (line 59) | function unescapeFragment(str: string): string {
  function escapeFragment (line 63) | function escapeFragment(str: string | number): string {
  function escapeJsonPointer (line 67) | function escapeJsonPointer(str: string | number): string {
  function unescapeJsonPointer (line 72) | function unescapeJsonPointer(str: string): string {
  function eachItem (line 76) | function eachItem<T>(xs: T | T[], f: (x: T) => void): void {
  type SomeEvaluated (line 84) | type SomeEvaluated = EvaluatedProperties | EvaluatedItems
  type MergeEvaluatedFunc (line 86) | type MergeEvaluatedFunc<T extends SomeEvaluated> = (
  type MakeMergeFuncArgs (line 93) | interface MakeMergeFuncArgs<T extends SomeEvaluated> {
  function makeMergeEvaluated (line 100) | function makeMergeEvaluated<T extends SomeEvaluated>({
  type MergeEvaluated (line 119) | interface MergeEvaluated {
  function evaluatedPropsToName (line 160) | function evaluatedPropsToName(gen: CodeGen, ps?: EvaluatedProperties): N...
  function setEvaluated (line 167) | function setEvaluated(gen: CodeGen, props: Name, ps: {[K in string]?: tr...
  function useFunc (line 173) | function useFunc(gen: CodeGen, f: {code: string}): Name {
  type Type (line 180) | enum Type {
  function getErrorPath (line 185) | function getErrorPath(
  function checkStrictMode (line 204) | function checkStrictMode(

FILE: lib/compile/validate/applicability.ts
  function schemaHasRulesForType (line 5) | function schemaHasRulesForType(
  function shouldUseGroup (line 13) | function shouldUseGroup(schema: AnySchemaObject, group: RuleGroup): bool...
  function shouldUseRule (line 17) | function shouldUseRule(schema: AnySchemaObject, rule: Rule): boolean | u...

FILE: lib/compile/validate/boolSchema.ts
  function topBoolOrEmptySchema (line 11) | function topBoolOrEmptySchema(it: SchemaCxt): void {
  function boolOrEmptySchema (line 23) | function boolOrEmptySchema(it: SchemaCxt, valid: Name): void {
  function falseSchemaError (line 33) | function falseSchemaError(it: SchemaCxt, overrideAllErrors?: boolean): v...

FILE: lib/compile/validate/dataType.ts
  type DataType (line 14) | enum DataType {
  function getSchemaTypes (line 19) | function getSchemaTypes(schema: AnySchemaObject): JSONType[] {
  function getJSONTypes (line 34) | function getJSONTypes(ts: unknown | unknown[]): JSONType[] {
  function coerceAndCheckDataType (line 40) | function coerceAndCheckDataType(it: SchemaObjCxt, types: JSONType[]): bo...
  constant COERCIBLE (line 56) | const COERCIBLE: Set<JSONType> = new Set(["string", "number", "integer",...
  function coerceToTypes (line 57) | function coerceToTypes(types: JSONType[], coerceTypes?: boolean | "array...
  function coerceData (line 63) | function coerceData(it: SchemaObjCxt, types: JSONType[], coerceTo: JSONT...
  function assignParentData (line 138) | function assignParentData({gen, parentData, parentDataProperty}: SchemaO...
  function checkDataType (line 145) | function checkDataType(
  function checkDataTypes (line 178) | function checkDataTypes(
  type TypeError (line 203) | type TypeError = ErrorObject<"type", {type: string}>
  function reportTypeError (line 211) | function reportTypeError(it: SchemaObjCxt): void {
  function getTypeErrorContext (line 216) | function getTypeErrorContext(it: SchemaObjCxt): KeywordErrorCxt {

FILE: lib/compile/validate/defaults.ts
  function assignDefaults (line 5) | function assignDefaults(it: SchemaObjCxt, ty?: string): void {
  function assignDefault (line 16) | function assignDefault(it: SchemaObjCxt, prop: string | number, defaultV...

FILE: lib/compile/validate/index.ts
  function validateFunctionCode (line 38) | function validateFunctionCode(it: SchemaCxt): void {
  function validateFunction (line 49) | function validateFunction(
  function destructureValCxt (line 66) | function destructureValCxt(opts: InstanceOptions): Code {
  function destructureValCxtES5 (line 72) | function destructureValCxtES5(gen: CodeGen, opts: InstanceOptions): void {
  function topSchemaObjCode (line 92) | function topSchemaObjCode(it: SchemaObjCxt): void {
  function resetEvaluated (line 106) | function resetEvaluated(it: SchemaObjCxt): void {
  function funcSourceUrl (line 114) | function funcSourceUrl(schema: AnySchema, opts: InstanceOptions): Code {
  function subschemaCode (line 120) | function subschemaCode(it: SchemaCxt, valid: Name): void {
  function schemaCxtHasRules (line 131) | function schemaCxtHasRules({schema, self}: SchemaCxt): boolean {
  function isSchemaObj (line 137) | function isSchemaObj(it: SchemaCxt): it is SchemaObjCxt {
  function subSchemaObjCode (line 141) | function subSchemaObjCode(it: SchemaObjCxt, valid: Name): void {
  function checkKeywords (line 152) | function checkKeywords(it: SchemaObjCxt): void {
  function typeAndKeywords (line 157) | function typeAndKeywords(it: SchemaObjCxt, errsCount?: Name): void {
  function checkRefsAndKeywords (line 164) | function checkRefsAndKeywords(it: SchemaObjCxt): void {
  function checkNoDefault (line 171) | function checkNoDefault(it: SchemaObjCxt): void {
  function updateContext (line 178) | function updateContext(it: SchemaObjCxt): void {
  function checkAsyncSchema (line 183) | function checkAsyncSchema(it: SchemaObjCxt): void {
  function commentKeyword (line 187) | function commentKeyword({gen, schemaEnv, schema, errSchemaPath, opts}: S...
  function returnResults (line 198) | function returnResults(it: SchemaCxt): void {
  function assignEvaluated (line 214) | function assignEvaluated({gen, evaluated, props, items}: SchemaCxt): void {
  function schemaKeywords (line 219) | function schemaKeywords(
  function iterateKeywords (line 255) | function iterateKeywords(it: SchemaObjCxt, group: RuleGroup): void {
  function checkStrictTypes (line 271) | function checkStrictTypes(it: SchemaObjCxt, types: JSONType[]): void {
  function checkContextTypes (line 278) | function checkContextTypes(it: SchemaObjCxt, types: JSONType[]): void {
  function checkMultipleTypes (line 292) | function checkMultipleTypes(it: SchemaObjCxt, ts: JSONType[]): void {
  function checkKeywordTypes (line 298) | function checkKeywordTypes(it: SchemaObjCxt, ts: JSONType[]): void {
  function hasApplicableType (line 311) | function hasApplicableType(schTs: JSONType[], kwdT: JSONType): boolean {
  function includesType (line 315) | function includesType(ts: JSONType[], t: JSONType): boolean {
  function narrowSchemaTypes (line 319) | function narrowSchemaTypes(it: SchemaObjCxt, withTypes: JSONType[]): void {
  function strictTypesError (line 328) | function strictTypesError(it: SchemaObjCxt, msg: string): void {
  class KeywordCxt (line 334) | class KeywordCxt implements KeywordErrorCxt {
    method constructor (line 351) | constructor(it: SchemaObjCxt, def: AddedKeywordDefinition, keyword: st...
    method result (line 380) | result(condition: Code, successAction?: () => void, failAction?: () =>...
    method failResult (line 384) | failResult(condition: Code, successAction?: () => void, failAction?: (...
    method pass (line 398) | pass(condition: Code, failAction?: () => void): void {
    method fail (line 402) | fail(condition?: Code): void {
    method fail$data (line 414) | fail$data(condition: Code): void {
    method error (line 420) | error(append?: boolean, errorParams?: KeywordCxtParams, errorPaths?: E...
    method _error (line 430) | private _error(append?: boolean, errorPaths?: ErrorPaths): void {
    method $dataError (line 434) | $dataError(): void {
    method reset (line 438) | reset(): void {
    method ok (line 443) | ok(cond: Code | boolean): void {
    method setParams (line 447) | setParams(obj: KeywordCxtParams, assign?: true): void {
    method block$data (line 452) | block$data(valid: Name, codeBlock: () => void, $dataValid: Code = nil)...
    method check$data (line 459) | check$data(valid: Name = nil, $dataValid: Code = nil): void {
    method invalid$data (line 472) | invalid$data(): Code {
    method subschema (line 495) | subschema(appl: SubschemaArgs, valid: Name): SchemaCxt {
    method mergeEvaluated (line 504) | mergeEvaluated(schemaCxt: SchemaCxt, toName?: typeof Name): void {
    method mergeValidEvaluated (line 515) | mergeValidEvaluated(schemaCxt: SchemaCxt, valid: Name): boolean | void {
  function keywordCode (line 524) | function keywordCode(
  constant JSON_POINTER (line 542) | const JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/
  constant RELATIVE_JSON_POINTER (line 543) | const RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/
  function getData (line 544) | function getData(

FILE: lib/compile/validate/keyword.ts
  type KeywordCompilationResult (line 17) | type KeywordCompilationResult = AnySchema | SchemaValidateFunction | Any...
  function macroKeywordCode (line 19) | function macroKeywordCode(cxt: KeywordCxt, def: MacroKeywordDefinition):...
  function funcKeywordCode (line 39) | function funcKeywordCode(cxt: KeywordCxt, def: FuncKeywordDefinition): v...
  function modifyData (line 97) | function modifyData(cxt: KeywordCxt): void {
  function addErrs (line 102) | function addErrs(cxt: KeywordCxt, errs: Code): void {
  function checkAsyncKeyword (line 116) | function checkAsyncKeyword({schemaEnv}: SchemaObjCxt, def: FuncKeywordDe...
  function useKeyword (line 120) | function useKeyword(gen: CodeGen, keyword: string, result?: KeywordCompi...
  function validSchemaType (line 128) | function validSchemaType(
  function validateKeywordUsage (line 146) | function validateKeywordUsage(

FILE: lib/compile/validate/subschema.ts
  type SubschemaContext (line 7) | interface SubschemaContext {
  type SubschemaArgs (line 29) | type SubschemaArgs = Partial<{
  function getSubschema (line 49) | function getSubschema(
  function extendSubschemaData (line 87) | function extendSubschemaData(
  function extendSubschemaMode (line 126) | function extendSubschemaMode(

FILE: lib/core.ts
  type Plugin (line 24) | interface Plugin<Opts> {
  constant META_IGNORE_OPTIONS (line 71) | const META_IGNORE_OPTIONS: (keyof Options)[] = ["removeAdditional", "use...
  constant EXT_SCOPE_NAMES (line 72) | const EXT_SCOPE_NAMES = new Set([
  type Options (line 88) | type Options = CurrentOptions & DeprecatedOptions
  type CurrentOptions (line 90) | interface CurrentOptions {
  type CodeOptions (line 145) | interface CodeOptions {
  type InstanceCodeOptions (line 156) | interface InstanceCodeOptions extends CodeOptions {
  type DeprecatedOptions (line 161) | interface DeprecatedOptions {
  type RemovedOptions (line 170) | interface RemovedOptions {
  type OptionsInfo (line 188) | type OptionsInfo<T extends RemovedOptions | DeprecatedOptions> = {
  type RequiredInstanceOptions (line 216) | type RequiredInstanceOptions = {
  type InstanceOptions (line 237) | type InstanceOptions = Options & RequiredInstanceOptions
  constant MAX_EXPRESSION (line 239) | const MAX_EXPRESSION = 200
  function requiredOptions (line 242) | function requiredOptions(o: Options): RequiredInstanceOptions {
  type Logger (line 270) | interface Logger {
  class Ajv (line 276) | class Ajv {
    method constructor (line 294) | constructor(opts: Options = {}) {
    method _addVocabularies (line 317) | _addVocabularies(): void {
    method _addDefaultMetaSchema (line 321) | _addDefaultMetaSchema(): void {
    method defaultMeta (line 332) | defaultMeta(): string | AnySchemaObject | undefined {
    method validate (line 355) | validate<T>(
    method compile (line 388) | compile<T = unknown>(schema: AnySchema, _meta?: boolean): AnyValidateF...
    method compileAsync (line 410) | compileAsync<T = unknown>(
    method addSchema (line 471) | addSchema(
    method addMetaSchema (line 497) | addMetaSchema(
    method validateSchema (line 507) | validateSchema(schema: AnySchema, throwOrLogError?: boolean): boolean ...
    method getSchema (line 531) | getSchema<T = unknown>(keyRef: string): AnyValidateFunction<T> | undef...
    method removeSchema (line 548) | removeSchema(schemaKeyRef?: AnySchema | string | RegExp): Ajv {
    method addVocabulary (line 584) | addVocabulary(definitions: Vocabulary): Ajv {
    method addKeyword (line 589) | addKeyword(
    method getKeyword (line 630) | getKeyword(keyword: string): AddedKeywordDefinition | boolean {
    method removeKeyword (line 636) | removeKeyword(keyword: string): Ajv {
    method addFormat (line 649) | addFormat(name: string, format: Format): Ajv {
    method errorsText (line 655) | errorsText(
    method $dataMetaSchema (line 665) | $dataMetaSchema(metaSchema: AnySchemaObject, keywordsJsonPointers: str...
    method _removeAllSchemas (line 685) | private _removeAllSchemas(schemas: {[Ref in string]?: SchemaEnv | stri...
    method _addSchema (line 699) | _addSchema(
    method _checkUnique (line 730) | private _checkUnique(id: string): void {
    method _compileSchemaEnv (line 736) | private _compileSchemaEnv(sch: SchemaEnv): AnyValidateFunction {
    method _compileMetaSchema (line 745) | private _compileMetaSchema(sch: SchemaEnv): void {
  type ErrorsTextOptions (line 756) | interface ErrorsTextOptions {
  function checkOptions (line 761) | function checkOptions(
  function getSchEnv (line 774) | function getSchEnv(this: Ajv, keyRef: string): SchemaEnv | string | unde...
  function addInitialSchemas (line 779) | function addInitialSchemas(this: Ajv): void {
  function addInitialFormats (line 786) | function addInitialFormats(this: Ajv): void {
  function addInitialKeywords (line 793) | function addInitialKeywords(
  function getMetaSchemaOptions (line 809) | function getMetaSchemaOptions(this: Ajv): InstanceOptions {
  method log (line 815) | log() {}
  method warn (line 815) | warn() {}
  method error (line 815) | error() {}
  function getLogger (line 817) | function getLogger(logger?: Partial<Logger> | false): Logger {
  constant KEYWORD_NAME (line 824) | const KEYWORD_NAME = /^[a-z_$][a-z0-9_$:-]*$/i
  function checkKeyword (line 826) | function checkKeyword(this: Ajv, keyword: string | string[], def?: Keywo...
  function addRule (line 838) | function addRule(
  function addBeforeRule (line 869) | function addBeforeRule(this: Ajv, ruleGroup: RuleGroup, rule: Rule, befo...
  function keywordMetaschema (line 879) | function keywordMetaschema(this: Ajv, def: KeywordDefinition): void {
  function schemaOrData (line 890) | function schemaOrData(schema: AnySchema): AnySchemaObject {

FILE: lib/jtd.ts
  constant META_SCHEMA_ID (line 10) | const META_SCHEMA_ID = "JTD-meta-schema"
  type JTDOptions (line 12) | type JTDOptions = CurrentOptions & {
  class Ajv (line 38) | class Ajv extends AjvCore {
    method constructor (line 39) | constructor(opts: JTDOptions = {}) {
    method _addVocabularies (line 46) | _addVocabularies(): void {
    method _addDefaultMetaSchema (line 51) | _addDefaultMetaSchema(): void {
    method defaultMeta (line 57) | defaultMeta(): string | AnySchemaObject | undefined {
    method compileSerializer (line 66) | compileSerializer<T = unknown>(schema: SchemaObject): (data: T) => str...
    method compileParser (line 75) | compileParser<T = unknown>(schema: SchemaObject): JTDParser<T> {
    method _compileSerializer (line 80) | private _compileSerializer<T>(sch: SchemaEnv): (data: T) => string {
    method _compileParser (line 87) | private _compileParser(sch: SchemaEnv): JTDParser {

FILE: lib/refs/json-schema-2019-09/index.ts
  constant META_SUPPORT_DATA (line 11) | const META_SUPPORT_DATA = ["/properties"]
  function addMetaSchema2019 (line 13) | function addMetaSchema2019(this: Ajv, $data?: boolean): Ajv {

FILE: lib/refs/json-schema-2020-12/index.ts
  constant META_SUPPORT_DATA (line 12) | const META_SUPPORT_DATA = ["/properties"]
  function addMetaSchema2020 (line 14) | function addMetaSchema2020(this: Ajv, $data?: boolean): Ajv {

FILE: lib/refs/jtd-schema.ts
  type MetaSchema (line 3) | type MetaSchema = (root: boolean) => SchemaObject

FILE: lib/runtime/equal.ts
  type Equal (line 4) | type Equal = typeof equal & {code: string}

FILE: lib/runtime/parseJson.ts
  function parseJson (line 3) | function parseJson(s: string, pos: number): unknown {
  function parseJsonNumber (line 34) | function parseJsonNumber(s: string, pos: number, maxDigits?: number): nu...
  constant CODE_A (line 109) | const CODE_A: number = "a".charCodeAt(0)
  constant CODE_0 (line 110) | const CODE_0: number = "0".charCodeAt(0)
  function parseJsonString (line 112) | function parseJsonString(s: string, pos: number): string | undefined {

FILE: lib/runtime/quote.ts
  function quote (line 15) | function quote(s: string): string {

FILE: lib/runtime/re2.ts
  type Re2 (line 3) | type Re2 = typeof re2 & {code: string}

FILE: lib/runtime/timestamp.ts
  constant DT_SEPARATOR (line 1) | const DT_SEPARATOR = /t|\s/i
  constant DATE (line 2) | const DATE = /^(\d\d\d\d)-(\d\d)-(\d\d)$/
  constant TIME (line 3) | const TIME = /^(\d\d):(\d\d):(\d\d)(?:\.\d+)?(?:z|([+-]\d\d)(?::?(\d\d))...
  constant DAYS (line 4) | const DAYS = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  function validTimestamp (line 6) | function validTimestamp(str: string, allowDate: boolean): boolean {
  function validDate (line 15) | function validDate(str: string): boolean {
  function validTime (line 31) | function validTime(str: string): boolean {

FILE: lib/runtime/ucs2length.ts
  function ucs2length (line 3) | function ucs2length(str: string): number {

FILE: lib/runtime/uri.ts
  type URI (line 3) | type URI = typeof uri & {code: string}

FILE: lib/runtime/validation_error.ts
  class ValidationError (line 3) | class ValidationError extends Error {
    method constructor (line 8) | constructor(errors: Partial<ErrorObject>[]) {

FILE: lib/standalone/index.ts
  function standaloneCode (line 7) | function standaloneCode(

FILE: lib/standalone/instance.ts
  class AjvPack (line 5) | class AjvPack {
    method constructor (line 7) | constructor(readonly ajv: Ajv) {}
    method validate (line 9) | validate(schemaKeyRef: AnySchema | string, data: unknown): boolean | P...
    method compile (line 13) | compile<T = unknown>(schema: AnySchema, meta?: boolean): AnyValidateFu...
    method getSchema (line 17) | getSchema<T = unknown>(keyRef: string): AnyValidateFunction<T> | undef...
    method getStandalone (line 23) | private getStandalone<T = unknown>(v: AnyValidateFunction<T>): AnyVali...
    method addSchema (line 27) | addSchema(...args: Parameters<typeof Ajv.prototype.addSchema>): AjvPack {
    method addKeyword (line 32) | addKeyword(...args: Parameters<typeof Ajv.prototype.addKeyword>): AjvP...

FILE: lib/types/index.ts
  type _SchemaObject (line 8) | interface _SchemaObject {
  type SchemaObject (line 15) | interface SchemaObject extends _SchemaObject {
  type AsyncSchema (line 23) | interface AsyncSchema extends _SchemaObject {
  type AnySchemaObject (line 27) | type AnySchemaObject = SchemaObject | AsyncSchema
  type Schema (line 29) | type Schema = SchemaObject | boolean
  type AnySchema (line 31) | type AnySchema = Schema | AsyncSchema
  type SchemaMap (line 33) | type SchemaMap = {[Key in string]?: AnySchema}
  type SourceCode (line 35) | interface SourceCode {
  type DataValidationCxt (line 42) | interface DataValidationCxt<T extends string | number = string | number> {
  type ValidateFunction (line 50) | interface ValidateFunction<T = unknown> {
  type JTDParser (line 60) | interface JTDParser<T = unknown> {
  type EvaluatedProperties (line 66) | type EvaluatedProperties = {[K in string]?: true} | true
  type EvaluatedItems (line 68) | type EvaluatedItems = number | true
  type Evaluated (line 70) | interface Evaluated {
  type AsyncValidateFunction (line 79) | interface AsyncValidateFunction<T = unknown> extends ValidateFunction<T> {
  type AnyValidateFunction (line 84) | type AnyValidateFunction<T = any> = ValidateFunction<T> | AsyncValidateF...
  type ErrorObject (line 86) | interface ErrorObject<K extends string = string, P = Record<string, any>...
  type ErrorNoParams (line 101) | type ErrorNoParams<K extends string, S = unknown> = ErrorObject<K, Recor...
  type _KeywordDef (line 103) | interface _KeywordDef {
  type CodeKeywordDefinition (line 119) | interface CodeKeywordDefinition extends _KeywordDef {
  type MacroKeywordFunc (line 124) | type MacroKeywordFunc = (
  type CompileKeywordFunc (line 130) | type CompileKeywordFunc = (
  type DataValidateFunction (line 136) | interface DataValidateFunction {
  type SchemaValidateFunction (line 141) | interface SchemaValidateFunction {
  type FuncKeywordDefinition (line 151) | interface FuncKeywordDefinition extends _KeywordDef {
  type MacroKeywordDefinition (line 162) | interface MacroKeywordDefinition extends FuncKeywordDefinition {
  type KeywordDefinition (line 166) | type KeywordDefinition =
  type AddedKeywordDefinition (line 171) | type AddedKeywordDefinition = KeywordDefinition & {
  type KeywordErrorDefinition (line 176) | interface KeywordErrorDefinition {
  type Vocabulary (line 181) | type Vocabulary = (KeywordDefinition | string)[]
  type KeywordErrorCxt (line 183) | interface KeywordErrorCxt {
  type KeywordCxtParams (line 198) | type KeywordCxtParams = {[P in string]?: Code | string | number}
  type FormatValidator (line 200) | type FormatValidator<T extends string | number> = (data: T) => boolean
  type FormatCompare (line 202) | type FormatCompare<T extends string | number> = (data1: T, data2: T) => ...
  type AsyncFormatValidator (line 204) | type AsyncFormatValidator<T extends string | number> = (data: T) => Prom...
  type FormatDefinition (line 206) | interface FormatDefinition<T extends string | number> {
  type AsyncFormatDefinition (line 213) | interface AsyncFormatDefinition<T extends string | number> {
  type AddedFormat (line 220) | type AddedFormat =
  type Format (line 229) | type Format = AddedFormat | string
  type RegExpEngine (line 231) | interface RegExpEngine {
  type RegExpLike (line 236) | interface RegExpLike {
  type UriResolver (line 240) | interface UriResolver {

FILE: lib/types/json-schema.ts
  type StrictNullChecksWrapper (line 2) | type StrictNullChecksWrapper<Name extends string, Type> = undefined exte...
  type UnionToIntersection (line 6) | type UnionToIntersection<U> = (U extends any ? (_: U) => void : never) e...
  type SomeJSONSchema (line 10) | type SomeJSONSchema = UncheckedJSONSchemaType<Known, true>
  type UncheckedPartialSchema (line 12) | type UncheckedPartialSchema<T> = Partial<UncheckedJSONSchemaType<T, true>>
  type PartialSchema (line 14) | type PartialSchema<T> = StrictNullChecksWrapper<"PartialSchema", Uncheck...
  type JSONType (line 16) | type JSONType<T extends string, IsPartial extends boolean> = IsPartial e...
  type NumberKeywords (line 20) | interface NumberKeywords {
  type StringKeywords (line 29) | interface StringKeywords {
  type UncheckedJSONSchemaType (line 36) | type UncheckedJSONSchemaType<T, IsPartial extends boolean> = (
  type JSONSchemaType (line 143) | type JSONSchemaType<T> = StrictNullChecksWrapper<
  type Known (line 148) | type Known =
  type UncheckedPropertiesSchema (line 157) | type UncheckedPropertiesSchema<T> = {
  type PropertiesSchema (line 161) | type PropertiesSchema<T> = StrictNullChecksWrapper<
  type UncheckedRequiredMembers (line 166) | type UncheckedRequiredMembers<T> = {
  type RequiredMembers (line 170) | type RequiredMembers<T> = StrictNullChecksWrapper<
  type Nullable (line 175) | type Nullable<T> = undefined extends T

FILE: lib/types/jtd-schema.ts
  type NumberType (line 2) | type NumberType = "float32" | "float64" | "int8" | "uint8" | "int16" | "...
  type StringType (line 5) | type StringType = "string" | "timestamp"
  type SomeJTDSchemaType (line 8) | type SomeJTDSchemaType = (
  type RequiredKeys (line 44) | type RequiredKeys<T> = {
  type OptionalKeys (line 49) | type OptionalKeys<T> = {
  type IsUnion_ (line 54) | type IsUnion_<T, U extends T = T> = false extends (
  type IsUnion (line 59) | type IsUnion<T> = IsUnion_<T>
  type TypeEquality (line 62) | type TypeEquality<T, E> = [T] extends [E] ? ([E] extends [T] ? true : fa...
  type NullTypeEquality (line 65) | type NullTypeEquality<T, E> = TypeEquality<T | null, E | null>
  type EnumString (line 68) | type EnumString<T> = [T] extends [never]
  type IsEnum (line 77) | type IsEnum<T> = null extends EnumString<T> ? false : true
  type IsElements (line 82) | type IsElements<T> = false extends IsUnion<T>
  type IsValues (line 91) | type IsValues<T> = false extends IsUnion<T> ? TypeEquality<keyof T, stri...
  type IsRecord (line 94) | type IsRecord<T, Union extends boolean> = Union extends IsUnion<T>
  type IsEmptyRecord (line 101) | type IsEmptyRecord<T> = [T] extends [Record<string, never>]
  type JTDSchemaType (line 108) | type JTDSchemaType<T, D extends Record<string, unknown> = Record<string,...
  type JTDDataDef (line 209) | type JTDDataDef<S, D extends Record<string, unknown>> =
  type JTDDataType (line 271) | type JTDDataType<S> = S extends {definitions: Record<string, unknown>}

FILE: lib/vocabularies/applicator/additionalItems.ts
  type AdditionalItemsError (line 11) | type AdditionalItemsError = ErrorObject<"additionalItems", {limit: numbe...
  method code (line 24) | code(cxt: KeywordCxt) {
  function validateAdditionalItems (line 35) | function validateAdditionalItems(cxt: KeywordCxt, items: AnySchema[]): v...

FILE: lib/vocabularies/applicator/additionalProperties.ts
  type AdditionalPropertiesError (line 14) | type AdditionalPropertiesError = ErrorObject<
  method code (line 32) | code(cxt) {

FILE: lib/vocabularies/applicator/allOf.ts
  method code (line 8) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/anyOf.ts
  type AnyOfError (line 4) | type AnyOfError = ErrorNoParams<"anyOf", AnySchema[]>

FILE: lib/vocabularies/applicator/contains.ts
  type ContainsError (line 11) | type ContainsError = ErrorObject<
  method code (line 33) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/dependencies.ts
  type PropertyDependencies (line 13) | type PropertyDependencies = {[K in string]?: string[]}
  type DependenciesErrorParams (line 15) | interface DependenciesErrorParams {
  type SchemaDependencies (line 22) | type SchemaDependencies = SchemaMap
  type DependenciesError (line 24) | type DependenciesError = ErrorObject<
  method code (line 47) | code(cxt: KeywordCxt) {
  function splitDependencies (line 54) | function splitDependencies({schema}: KeywordCxt): [PropertyDependencies,...
  function validatePropertyDeps (line 65) | function validatePropertyDeps(
  function validateSchemaDeps (line 95) | function validateSchemaDeps(cxt: KeywordCxt, schemaDeps: SchemaMap = cxt...

FILE: lib/vocabularies/applicator/if.ts
  type IfKeywordError (line 12) | type IfKeywordError = ErrorObject<"if", {failingKeyword: string}, AnySch...
  method code (line 24) | code(cxt: KeywordCxt) {
  function hasSchema (line 75) | function hasSchema(it: SchemaObjCxt, keyword: string): boolean {

FILE: lib/vocabularies/applicator/index.ts
  function getApplicator (line 19) | function getApplicator(draft2020 = false): Vocabulary {
  type ApplicatorKeywordError (line 42) | type ApplicatorKeywordError =

FILE: lib/vocabularies/applicator/items.ts
  method code (line 12) | code(cxt: KeywordCxt) {
  function validateTuple (line 21) | function validateTuple(

FILE: lib/vocabularies/applicator/items2020.ts
  type ItemsError (line 13) | type ItemsError = ErrorObject<"items", {limit: number}, AnySchema>
  method code (line 26) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/not.ts
  type NotKeywordError (line 5) | type NotKeywordError = ErrorNoParams<"not", AnySchema>
  method code (line 11) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/oneOf.ts
  type OneOfError (line 12) | type OneOfError = ErrorObject<
  method code (line 28) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/patternProperties.ts
  method code (line 13) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/properties.ts
  method code (line 11) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/propertyNames.ts
  type PropertyNamesError (line 11) | type PropertyNamesError = ErrorObject<"propertyNames", {propertyName: st...
  method code (line 23) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/applicator/thenElse.ts
  method code (line 8) | code({keyword, parentSchema, it}: KeywordCxt) {

FILE: lib/vocabularies/code.ts
  function checkReportMissingProp (line 8) | function checkReportMissingProp(cxt: KeywordCxt, prop: string): void {
  function checkMissingProp (line 16) | function checkMissingProp(
  function reportMissingProp (line 28) | function reportMissingProp(cxt: KeywordCxt, missing: Name): void {
  function hasPropFunc (line 33) | function hasPropFunc(gen: CodeGen): Name {
  function isOwnProperty (line 41) | function isOwnProperty(gen: CodeGen, data: Name, property: Name | string...
  function propertyInData (line 45) | function propertyInData(
  function noPropertyInData (line 55) | function noPropertyInData(
  function allSchemaProperties (line 65) | function allSchemaProperties(schemaMap?: SchemaMap): string[] {
  function schemaProperties (line 69) | function schemaProperties(it: SchemaCxt, schemaMap: SchemaMap): string[] {
  function callValidateCode (line 75) | function callValidateCode(
  function usePattern (line 95) | function usePattern({gen, it: {opts}}: KeywordCxt, pattern: string): Name {
  function validateArray (line 107) | function validateArray(cxt: KeywordCxt): Name {
  function validateUnion (line 135) | function validateUnion(cxt: KeywordCxt): void {

FILE: lib/vocabularies/core/id.ts
  method code (line 5) | code() {

FILE: lib/vocabularies/core/ref.ts
  method code (line 13) | code(cxt: KeywordCxt): void {
  function getValidate (line 56) | function getValidate(cxt: KeywordCxt, sch: SchemaEnv): Code {
  function callRef (line 63) | function callRef(cxt: KeywordCxt, v: Code, sch?: SchemaEnv, $async?: boo...

FILE: lib/vocabularies/discriminator/index.ts
  type DiscriminatorError (line 9) | type DiscriminatorError = DiscrErrorObj<DiscrError.Tag> | DiscrErrorObj<...
  method code (line 25) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/discriminator/types.ts
  type DiscrError (line 3) | enum DiscrError {
  type DiscrErrorObj (line 8) | type DiscrErrorObj<E extends DiscrError> = ErrorObject<

FILE: lib/vocabularies/dynamic/dynamicAnchor.ts
  function dynamicAnchor (line 14) | function dynamicAnchor(cxt: KeywordCxt, anchor: string): void {
  function _getValidate (line 22) | function _getValidate(cxt: KeywordCxt): Code {

FILE: lib/vocabularies/dynamic/dynamicRef.ts
  function dynamicRef (line 13) | function dynamicRef(cxt: KeywordCxt, ref: string): void {

FILE: lib/vocabularies/dynamic/recursiveAnchor.ts
  method code (line 8) | code(cxt) {

FILE: lib/vocabularies/errors.ts
  type DefinedError (line 10) | type DefinedError =

FILE: lib/vocabularies/format/format.ts
  type FormatValidate (line 12) | type FormatValidate =
  type FormatError (line 21) | type FormatError = ErrorObject<"format", {format: string}, string | {$da...
  method code (line 34) | code(cxt: KeywordCxt, ruleType?: string) {

FILE: lib/vocabularies/jtd/discriminator.ts
  type JTDDiscriminatorError (line 9) | type JTDDiscriminatorError =
  method code (line 36) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/jtd/elements.ts
  type JTDElementsError (line 10) | type JTDElementsError = _JTDTypeError<"elements", "array", SchemaObject>
  method code (line 16) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/jtd/enum.ts
  type JTDEnumError (line 7) | type JTDEnumError = ErrorObject<"enum", {allowedValues: string[]}, strin...
  method code (line 18) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/jtd/error.ts
  type _JTDTypeError (line 4) | type _JTDTypeError<K extends string, T extends string, S> = ErrorObject<
  function typeError (line 10) | function typeError(t: string): KeywordErrorDefinition {
  function typeErrorMessage (line 17) | function typeErrorMessage({parentSchema}: KeywordErrorCxt, t: string): s...
  function typeErrorParams (line 21) | function typeErrorParams({parentSchema}: KeywordErrorCxt, t: string): Co...

FILE: lib/vocabularies/jtd/index.ts
  type JTDErrorObject (line 31) | type JTDErrorObject =

FILE: lib/vocabularies/jtd/metadata.ts
  method code (line 8) | code(cxt: KeywordCxt) {
  function checkMetadata (line 18) | function checkMetadata({it, keyword}: KeywordCxt, metadata?: boolean): v...

FILE: lib/vocabularies/jtd/nullable.ts
  function checkNullable (line 4) | function checkNullable(
  function checkNullableObject (line 18) | function checkNullableObject(cxt: KeywordCxt, cond: Code): [Name, Code] {

FILE: lib/vocabularies/jtd/optionalProperties.ts
  method code (line 9) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/jtd/properties.ts
  type PropError (line 15) | enum PropError {
  type PropKeyword (line 20) | type PropKeyword = "properties" | "optionalProperties"
  type PropSchema (line 22) | type PropSchema = {[P in string]?: SchemaObject}
  type JTDPropertiesError (line 24) | type JTDPropertiesError =
  function validateProperties (line 60) | function validateProperties(cxt: KeywordCxt): void {

FILE: lib/vocabularies/jtd/ref.ts
  method code (line 13) | code(cxt: KeywordCxt) {
  function hasRef (line 68) | function hasRef(schema: AnySchemaObject): boolean {

FILE: lib/vocabularies/jtd/type.ts
  type JTDTypeError (line 9) | type JTDTypeError = _JTDTypeError<"type", JTDType, JTDType>
  type IntType (line 11) | type IntType = "int8" | "uint8" | "int16" | "uint16" | "int32" | "uint32"
  type JTDType (line 22) | type JTDType = "boolean" | "string" | "timestamp" | "float32" | "float64...
  function timestampCode (line 29) | function timestampCode(cxt: KeywordCxt): Code {
  method code (line 43) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/jtd/values.ts
  type JTDValuesError (line 9) | type JTDValuesError = _JTDTypeError<"values", "object", SchemaObject>
  method code (line 15) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/unevaluated/unevaluatedItems.ts
  type UnevaluatedItemsError (line 11) | type UnevaluatedItemsError = ErrorObject<"unevaluatedItems", {limit: num...
  method code (line 23) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/unevaluated/unevaluatedProperties.ts
  type UnevaluatedPropertiesError (line 11) | type UnevaluatedPropertiesError = ErrorObject<
  method code (line 28) | code(cxt) {

FILE: lib/vocabularies/validation/const.ts
  type ConstError (line 7) | type ConstError = ErrorObject<"const", {allowedValue: any}>
  method code (line 18) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/dependentRequired.ts
  type DependentRequiredError (line 9) | type DependentRequiredError = ErrorObject<

FILE: lib/vocabularies/validation/enum.ts
  type EnumError (line 7) | type EnumError = ErrorObject<"enum", {allowedValues: any[]}, any[] | {$d...
  method code (line 19) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/index.ts
  type LimitError (line 35) | type LimitError = ErrorObject<
  type ValidationKeywordError (line 41) | type ValidationKeywordError =

FILE: lib/vocabularies/validation/limitContains.ts
  method code (line 9) | code({keyword, parentSchema, it}: KeywordCxt) {

FILE: lib/vocabularies/validation/limitItems.ts
  method message (line 6) | message({keyword, schemaCode}) {
  method code (line 19) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/limitLength.ts
  method message (line 8) | message({keyword, schemaCode}) {
  method code (line 21) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/limitNumber.ts
  type Kwd (line 7) | type Kwd = "maximum" | "minimum" | "exclusiveMaximum" | "exclusiveMinimum"
  type Comparison (line 9) | type Comparison = "<=" | ">=" | "<" | ">"
  type LimitNumberError (line 18) | type LimitNumberError = ErrorObject<
  method code (line 36) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/limitProperties.ts
  method message (line 6) | message({keyword, schemaCode}) {
  method code (line 19) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/multipleOf.ts
  type MultipleOfError (line 5) | type MultipleOfError = ErrorObject<
  method code (line 22) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/pattern.ts
  type PatternError (line 7) | type PatternError = ErrorObject<"pattern", {pattern: string}, string | {...
  method code (line 20) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/required.ts
  type RequiredError (line 13) | type RequiredError = ErrorObject<
  method code (line 30) | code(cxt: KeywordCxt) {

FILE: lib/vocabularies/validation/uniqueItems.ts
  type UniqueItemsError (line 8) | type UniqueItemsError = ErrorObject<
  method code (line 26) | code(cxt: KeywordCxt) {

FILE: rollup.config.js
  function createBundleConfig (line 7) | function createBundleConfig(sourceFile, outFile, globalName) {

FILE: scripts/bundle.js
  function saveAndMinify (line 18) | async function saveAndMinify(err, buf) {

FILE: scripts/get-contributors.js
  constant SIZE (line 12) | const SIZE = 64
  function main (line 16) | async function main() {

FILE: spec/after_test.ts
  type TestResult (line 6) | interface TestResult {
  function afterError (line 16) | function afterError(res: TestResult): void {
  function afterEach (line 20) | function afterEach(res: TestResult): void {

FILE: spec/ajv.spec.ts
  function badEvenCode (line 66) | function badEvenCode(cxt: KeywordCxt) {
  function testFormat (line 446) | function testFormat() {
  function passValidationThrowCompile (line 587) | function passValidationThrowCompile(schema: SchemaObject) {

FILE: spec/ajv_all_instances.ts
  function getAjvAllInstances (line 7) | function getAjvAllInstances(options: Options, extraOpts: Options = {}): ...

FILE: spec/ajv_async_instances.ts
  function getAjvSyncInstances (line 6) | function getAjvSyncInstances(extraOpts?: Options): AjvCore[] {

FILE: spec/ajv_instances.ts
  function getAjvInstances (line 4) | function getAjvInstances(

FILE: spec/ajv_standalone.ts
  function withStandalone (line 5) | function withStandalone(instances: AjvCore[]): (AjvCore | AjvPack)[] {
  function makeStandalone (line 9) | function makeStandalone(ajv: AjvCore): AjvPack {
  function getStandalone (line 14) | function getStandalone(_Ajv: typeof AjvCore, opts: Options = {}): AjvPack {

FILE: spec/async.spec.ts
  function test (line 204) | function test(schema, expectedLoadCallCount) {
  function spec (line 243) | function spec(validate) {
  function spec (line 268) | function spec(validate) {
  function badLoadSchema (line 331) | function badLoadSchema() {
  function badCompile (line 341) | function badCompile(/* schema */) {
  function shouldReject (line 346) | function shouldReject(p: Promise<AnyValidateFunction>, rx: RegExp) {
  function loadSchema (line 376) | function loadSchema(uri: string): Promise<SchemaObject> {

FILE: spec/async_schemas.spec.ts
  function addAsyncFormatsAndKeywords (line 26) | function addAsyncFormatsAndKeywords(ajv: Ajv) {
  function checkWordOnServer (line 58) | function checkWordOnServer(str: string): Promise<boolean> {
  function checkIdExists (line 66) | function checkIdExists(schema: {table: string}, data: number): Promise<b...
  function checkIdExistsWithError (line 81) | function checkIdExistsWithError(schema: {table: string}, data: number): ...
  function compileCheckIdExists (line 103) | function compileCheckIdExists(schema: {table: string}): (data: number) =...

FILE: spec/async_validate.spec.ts
  function test (line 27) | function test(_ajv) {
  function checkIdExists (line 147) | function checkIdExists(schema, data) {
  function checkIdExistsWithError (line 162) | function checkIdExistsWithError(schema, data) {
  function recursiveTest (line 355) | function recursiveTest(schema, refSchema?) {
  function addFormatEnglishWord (line 383) | function addFormatEnglishWord() {
  function checkWordOnServer (line 393) | function checkWordOnServer(str) {
  function shouldBeValid (line 401) | function shouldBeValid(p, data) {
  constant SHOULD_BE_INVALID (line 405) | const SHOULD_BE_INVALID = "test: should be invalid"
  function shouldBeInvalid (line 406) | function shouldBeInvalid(p, expectedMessages?: string[]) {
  function shouldThrow (line 418) | function shouldThrow(p, exception) {
  function checkNotValid (line 422) | function checkNotValid(p) {
  function repeat (line 434) | function repeat(func) {

FILE: spec/boolean.spec.ts
  function test (line 31) | function test(boolSchema, valid) {
  function test (line 52) | function test(boolSchema, valid) {
  function test (line 94) | function test(boolSchema, valid) {
  function test (line 151) | function test(boolSchema, valid) {
  function test (line 193) | function test(boolSchema, valid) {
  function test (line 235) | function test(boolSchema, valid) {
  function test (line 264) | function test(boolSchema, valid) {
  function test (line 298) | function test(boolSchema, valid) {
  function test (line 323) | function test(boolSchema, valid) {
  function test (line 355) | function test(boolSchema, valid) {
  function test (line 387) | function test(boolSchema, valid) {
  function test (line 419) | function test(boolSchema, valid) {
  function testSchema (line 434) | function testSchema(validate, valid) {

FILE: spec/chai_type.ts
  type ChaiStatic (line 2) | type ChaiStatic = Chai.ChaiStatic

FILE: spec/codegen.spec.ts
  function log (line 264) | function log(comparison: string): void {
  function assertEqual (line 497) | function assertEqual(code: Code | CodeGen, s: string): void {
  function getGen (line 501) | function getGen(opts?: CodeGenOptions): CodeGen {

FILE: spec/coercion.spec.ts
  function testCoercion (line 238) | function testCoercion(_ajv, _schema, fromData, toData) {
  function testCoercion (line 411) | function testCoercion(_schema, fromData, toData) {
  function testRules (line 471) | function testRules(rules, cb) {

FILE: spec/discriminator.spec.ts
  function getAjvs (line 21) | function getAjvs(AjvClass: typeof AjvCore) {
  method loadSchema (line 210) | loadSchema(url) {
  function assertValid (line 376) | function assertValid(schemas: SchemaObject[], data: unknown): void {
  function assertInvalid (line 382) | function assertInvalid(schemas: SchemaObject[], data: unknown): void {
  function invalidSchema (line 388) | function invalidSchema(schema: SchemaObject, error: any): void {

FILE: spec/dynamic-ref.spec.ts
  function testTree (line 75) | function testTree(treeSchema: SchemaObject, strictTreeSchema: SchemaObje...

FILE: spec/errors.spec.ts
  function createInstances (line 14) | function createInstances() {
  function testAdditional (line 59) | function testAdditional() {
  function testAdditionalIsSchema (line 126) | function testAdditionalIsSchema() {
  function testRequired (line 176) | function testRequired() {
  function testRequiredLargeSchema (line 188) | function testRequiredLargeSchema() {
  function testRequiredAndProperties (line 251) | function testRequiredAndProperties() {
  function testRequiredInAnyOf (line 268) | function testRequiredInAnyOf() {
  function test (line 316) | function test(_ajv: Ajv) {
  function test (line 356) | function test(_ajv: Ajv): void {
  function testDependencies (line 385) | function testDependencies() {
  function _testRequired (line 467) | function _testRequired(schema, schemaPathPrefix = "#", extraErrors = 0) {
  function requiredMsg (line 511) | function requiredMsg(prop: string) {
  function test (line 580) | function test(_ajv) {
  function test (line 617) | function test(_ajv: Ajv, numErrors: number) {
  function test (line 664) | function test(_ajv) {
  function test (line 682) | function test(_ajv) {
  function test (line 713) | function test(_ajv) {
  function test (line 733) | function test(_ajv, numErrors?: number) {
  function test (line 757) | function test(_ajv, numErrors?: number) {
  function test (line 781) | function test(_ajv: Ajv, numErrors?: number) {
  function testError (line 825) | function testError(keyword, message, params) {
  function testError (line 863) | function testError() {
  function prepareTest (line 938) | function prepareTest(_ajv: Ajv, schema) {
  function testIfError (line 943) | function testIfError(ifClause, multipleOf) {
  function testTypeError (line 990) | function testTypeError(i, instancePath) {
  function testSchema1 (line 998) | function testSchema1(schema, schemaPathPrefix = "#/properties/foo") {
  function _testSchema1 (line 1004) | function _testSchema1(_ajv, schema, schemaPathPrefix) {
  function shouldBeValid (line 1021) | function shouldBeValid(validate, data) {
  function shouldBeInvalid (line 1026) | function shouldBeInvalid(validate, data, numErrors = 1) {
  function shouldBeError (line 1031) | function shouldBeError(

FILE: spec/issues/1501_jtd_many_properties.spec.ts
  constant PROP_COUNT (line 5) | const PROP_COUNT = 10

FILE: spec/issues/1539_add_keyword_name_to_validation_error.spec.ts
  method macro (line 14) | macro() {

FILE: spec/issues/181_allErrors_custom_keyword_skipped.spec.ts
  function testKeywordErrors (line 39) | function testKeywordErrors(def: KeywordDefinition): void {

FILE: spec/issues/182_nan_validation.spec.ts
  function testNaN (line 37) | function testNaN(_ajv, schema, NaNisValid) {

FILE: spec/issues/210_mutual_recur_frags.spec.ts
  function spec (line 13) | function spec(ajv: AjvCore | AjvPack): () => void {
  function spec (line 49) | function spec(ajv: AjvCore | AjvPack): () => void {

FILE: spec/issues/240_mutual_recur_frags_common_ref.spec.ts
  function spec (line 49) | function spec(ajv: AjvCore | AjvPack): () => void {
  function spec (line 154) | function spec(ajv: AjvCore | AjvPack): () => void {
  function testSchema (line 233) | function testSchema(validate) {

FILE: spec/issues/273_error_schemaPath_refd_schema.spec.ts
  function test (line 10) | function test(ajv) {

FILE: spec/issues/485_type_validation_priority.spec.ts
  function checkErrors (line 23) | function checkErrors(expectedErrs) {

FILE: spec/issues/50_refs_with_definitions.spec.ts
  function spec (line 57) | function spec(ajv: AjvCore | AjvPack): void {

FILE: spec/issues/768_passContext_recursive_ref.spec.ts
  function getValidate (line 50) | function getValidate(passContext) {
  function getValidateFragments (line 69) | function getValidateFragments(passContext) {
  function storeContext (line 100) | function storeContext(this: any) {

FILE: spec/issues/8_shared_refs.spec.ts
  function spec (line 43) | function spec(ajv: AjvCore | AjvPack): void {

FILE: spec/javacript.spec.js
  function test (line 9) | function test(_Ajv) {

FILE: spec/json-schema.spec.ts
  constant SKIP_FORMATS (line 26) | const SKIP_FORMATS = ["idn-email", "idn-hostname", "iri", "iri-reference"]
  constant SKIP_FORMAT_TESTS (line 27) | const SKIP_FORMAT_TESTS = SKIP_FORMATS.map((f) => `optional/format/${f}`)
  constant SKIP_DRAFT7 (line 28) | const SKIP_DRAFT7 = [
  type TestSuite (line 203) | interface TestSuite {
  type SchemaTest (line 208) | interface SchemaTest {
  function runTest (line 216) | function runTest({instances, draft, tests, skip = [], remotes = {}}: Sch...
  type SkippedTestCases (line 242) | interface SkippedTestCases {
  function skipTestCases (line 248) | function skipTestCases(suites: TestSuite[], skipCases: SkippedTestCases)...

FILE: spec/jtd-schema.spec.ts
  type TestCase (line 13) | interface TestCase {
  type TestCaseError (line 19) | interface TestCaseError {
  type JSONParseTest (line 24) | interface JSONParseTest {
  type JSONParseTestSuite (line 33) | interface JSONParseTestSuite {
  type JTDError (line 38) | interface JTDError {
  constant ONLY (line 55) | const ONLY: RegExp[] = []
  function cleanErrors (line 88) | function cleanErrors(errors?: JTDError[] | null): JTDError[] | null | un...
  function convertErrors (line 95) | function convertErrors(errors: TestCaseError[]): JTDError[] | null | und...
  function sortErrors (line 104) | function sortErrors(errors?: JTDError[] | null): JTDError[] | null | und...
  function jsonPointer (line 115) | function jsonPointer(error: string[]): string {
  type TestFunc (line 258) | type TestFunc = typeof it | typeof it.only | typeof it.skip
  function _it (line 260) | function _it({only, skip}: JSONParseTest): TestFunc {
  function shouldParse (line 264) | function shouldParse(parse: JTDParser, str: string, res: unknown): void {
  function shouldFail (line 270) | function shouldFail(parse: JTDParser, str: string): void {
  function describeOnly (line 276) | function describeOnly(name: string, func: () => void) {

FILE: spec/jtd-timestamps.spec.ts
  function testTimestamp (line 33) | function testTimestamp(

FILE: spec/keyword.spec.ts
  function validateEven (line 32) | function validateEven(schema, data) {
  function validateEven (line 50) | function validateEven(schema, data) {
  function validateRange (line 62) | function validateRange(schema, data, parentSchema) {
  function validateRange (line 87) | function validateRange(schema, data, parentSchema) {
  function _validateRange (line 98) | function _validateRange(schema, data, parentSchema) {
  function compileEven (line 156) | function compileEven(schema) {
  function isEven (line 163) | function isEven(data) {
  function isOdd (line 166) | function isOdd(data) {
  function compileEven (line 183) | function compileEven(schema) {
  function isEven (line 187) | function isEven(data) {
  function isOdd (line 190) | function isOdd(data) {
  function compileEven (line 226) | function compileEven(schema) {
  function compileConstant (line 233) | function compileConstant(schema) {
  function compileRange (line 244) | function compileRange(schema, parentSchema) {
  method macro (line 281) | macro(schema, _parentSchema, it) {
  function macroDeepProperties (line 411) | function macroDeepProperties(_schema) {
  function macroContains (line 522) | function macroContains(_schema) {
  function macroInvalid (line 536) | function macroInvalid(/* schema */) {
  function macroEven (line 541) | function macroEven(schema) {
  function macroConstant (line 547) | function macroConstant(schema /*, parentSchema */) {
  function macroRange (line 551) | function macroRange(schema, parentSchema) {
  method code (line 566) | code(cxt) {
  method code (line 578) | code(cxt) {
  method code (line 594) | code(cxt) {
  function validateEven (line 641) | function validateEven(schema, data) {
  function validateEven (line 658) | function validateEven(schema, data) {
  function compileEven (line 663) | function compileEven(schema) {
  function isEven (line 671) | function isEven(data) {
  function isOdd (line 674) | function isOdd(data) {
  function validateEven (line 695) | function validateEven(schema, data) {
  function compileEven (line 699) | function compileEven(schema) {
  function isEven (line 704) | function isEven(data) {
  function isOdd (line 707) | function isOdd(data) {
  function validateEven (line 726) | function validateEven(schema, data) {
  function macroEven (line 731) | function macroEven(schema) {
  function validateEven (line 758) | function validateEven(schema, data) {
  function macroEven (line 762) | function macroEven(schema): SchemaObject | void {
  method code (line 774) | code(cxt) {
  method code (line 787) | code(cxt) {
  function validateEven (line 822) | function validateEven(schema, data) {
  function testEvenKeyword (line 828) | function testEvenKeyword(evenDefinition, numErrors = 1) {
  function testEvenKeyword$data (line 844) | function testEvenKeyword$data(definition, numErrors = 1) {
  function testConstantKeyword (line 888) | function testConstantKeyword(definition, numErrors?: number) {
  function testMultipleConstantKeyword (line 901) | function testMultipleConstantKeyword(definition, numErrors?: number) {
  function testRangeKeyword (line 929) | function testRangeKeyword(definition, createsErrors?: boolean, numErrors...
  function testMultipleRangeKeyword (line 981) | function testMultipleRangeKeyword(definition, numErrors?: number) {
  function shouldBeRangeError (line 1008) | function shouldBeRangeError(
  function validateRangeSchema (line 1031) | function validateRangeSchema(schema, parentSchema) {
  function shouldBeValid (line 1048) | function shouldBeValid(validate, data) {
  function shouldBeInvalid (line 1053) | function shouldBeInvalid(validate, data, numErrors = 1) {
  function shouldBeInvalidSchema (line 1058) | function shouldBeInvalidSchema(
  function testThrow (line 1076) | function testThrow(keywords) {
  function testThrowDuplicate (line 1084) | function testThrowDuplicate(keywordPrefix) {
  function _addKeyword (line 1163) | function _addKeyword(keyword, dataType) {
  function testModifying (line 1286) | function testModifying(withOption) {

FILE: spec/options/comment.spec.ts
  function log (line 9) | function log(...args: any[]) {
  function test (line 36) | function test(data, valid, expectedLogCalls) {
  function hook (line 48) | function hook(...args: any[]) {
  function test (line 84) | function test(data, valid, expectedHookCalls) {

FILE: spec/options/meta_validateSchema.spec.ts
  function testOptionMeta (line 10) | function testOptionMeta(ajv) {
  method log (line 51) | log() {}

FILE: spec/options/nullable.spec.ts
  function testNullable (line 66) | function testNullable(schema) {
  function testNotNullable (line 73) | function testNotNullable(schema) {

FILE: spec/options/options_code.spec.ts
  function test (line 12) | function test(ajv) {
  function test (line 24) | function test(ajv: Ajv) {
  function getValidate (line 76) | function getValidate(passContext) {
  function storeContext (line 97) | function storeContext(this: any) {
  function compileTestValidate (line 102) | function compileTestValidate() {
  function test (line 116) | function test(ajv, schema) {

FILE: spec/options/options_refs.spec.ts
  function test (line 28) | function test(opts: Options, shouldExtendRef: boolean) {
  function testWarning (line 67) | function testWarning(opts: Options = {}, msgPattern?: RegExp) {

FILE: spec/options/options_reporting.spec.ts
  function testVerbose (line 11) | function testVerbose(ajv) {
  function test (line 38) | function test(ajv, allErrors) {
  function log (line 125) | function log() {

FILE: spec/options/options_validation.spec.ts
  constant DATE_FORMAT (line 6) | const DATE_FORMAT = /^\d\d\d\d-[0-1]\d-[0-3]\d$/
  function testKeyword (line 80) | function testKeyword(ajv: Ajv) {
  function testUnicode (line 99) | function testUnicode(ajv: Ajv) {
  function test (line 120) | function test(ajv) {

FILE: spec/options/ownProperties.spec.ts
  function test (line 166) | function test(schema, obj, proto, errors = 1, reverse?: boolean) {

FILE: spec/options/schemaId.spec.ts
  function test (line 11) | function test(ajv) {
  function test (line 27) | function test(ajv: Ajv) {

FILE: spec/options/strict.spec.ts
  type MyTuple (line 186) | type MyTuple = [string, number]
  function testStrictMode (line 387) | function testStrictMode(schema, logPattern) {
  function getLogger (line 428) | function getLogger(output) {

FILE: spec/options/strictDefaults.spec.ts
  function test (line 54) | function test(ajv) {
  function test (line 68) | function test(ajv) {
  function test (line 139) | function test(ajv) {
  function test (line 157) | function test(ajv) {
  function getLogger (line 178) | function getLogger(output) {

FILE: spec/options/strictKeywords.spec.ts
  function test (line 28) | function test(ajv) {
  function test (line 61) | function test(ajv) {
  function getLogger (line 70) | function getLogger(output) {

FILE: spec/options/strictNumbers.spec.ts
  function testStrict (line 10) | function testStrict(ajv) {
  function testNotStrict (line 32) | function testNotStrict(_ajv) {

FILE: spec/options/unknownFormats.spec.ts
  constant DATE_FORMAT (line 5) | const DATE_FORMAT = /^\d\d\d\d-[0-1]\d-[0-3]\d$/
  function test (line 12) | function test(ajv) {
  function test (line 22) | function test(ajv) {
  function test (line 46) | function test(ajv) {
  function test (line 55) | function test(ajv) {
  function test (line 77) | function test(ajv) {
  function test (line 90) | function test(ajv) {

FILE: spec/options/useDefaults.spec.ts
  function test (line 19) | function test(ajv) {
  function test (line 64) | function test(ajv) {
  function test (line 97) | function test(ajv) {
  function test (line 131) | function test(ajv) {
  function test (line 196) | function test(ajv) {

FILE: spec/resolve.spec.ts
  function testMissingSchemaError (line 266) | function testMissingSchemaError(opts) {
  function testSchemas (line 379) | function testSchemas(ajv, expectedInlined) {
  function testObjSchema (line 391) | function testObjSchema(validate) {
  function testListSchema (line 397) | function testListSchema(validate) {
  function testInlined (line 403) | function testInlined(validate: AnyValidateFunction, expectedInlined) {

FILE: spec/schema-tests.spec.ts
  function addRemoteRefsAndFormats (line 42) | function addRemoteRefsAndFormats(ajv: AjvCore) {

FILE: spec/standalone.spec.ts
  function testExportTypeEsm (line 10) | function testExportTypeEsm(moduleCode: string, singleExport: boolean) {
  function testExportTypeCjs (line 19) | function testExportTypeCjs(moduleCode: string, singleExport: boolean) {
  function testExports (line 134) | function testExports(m: {[n: string]: AnyValidateFunction<unknown>}) {
  function assertNoDuplicateFunctions (line 262) | function assertNoDuplicateFunctions(code: string): void {
  function testExports (line 269) | function testExports(validate: {[n: string]: AnyValidateFunction<unknown...
  function testExport (line 296) | function testExport(validate: AnyValidateFunction<unknown>) {
  function testExport (line 316) | function testExport(validate: AnyValidateFunction<unknown>) {

FILE: spec/types/async-validate.spec.ts
  type Foo (line 6) | interface Foo {

FILE: spec/types/json-schema.spec.ts
  type MyData (line 7) | interface MyData {
  type MyUnionData (line 100) | type MyUnionData = {a: boolean} | string | number
  type MyEnumRecord (line 148) | type MyEnumRecord = Record<"a" | "b" | "c" | "d", number | undefined>

FILE: spec/types/jtd-schema.spec.ts
  type TypeEquality (line 8) | type TypeEquality<T, E> = [T] extends [E] ? ([E] extends [T] ? true : fa...
  type A (line 10) | interface A {
  type B (line 15) | interface B {
  type C (line 20) | interface C {
  type MyData (line 24) | type MyData = A | B
  type Missing (line 26) | type Missing = A | C
  type LinkedList (line 28) | interface LinkedList {
  type Mult (line 267) | type Mult = JTDSchemaType<(A & {typ: "alpha"}) | (B & {typ: "beta"})>
Condensed preview — 433 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,183K chars).
[
  {
    "path": ".eslintrc.js",
    "chars": 947,
    "preview": "const jsConfig = require(\"@ajv-validator/config/.eslintrc_js\")\nconst tsConfig = require(\"@ajv-validator/config/.eslintrc"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 13,
    "preview": "@epoberezkin\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 63,
    "preview": "github: epoberezkin\ntidelift: \"npm/ajv\"\nopen_collective: \"ajv\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-or-error-report.md",
    "chars": 1428,
    "preview": "---\nname: Bug or error report\nabout: Please use for issues related to incorrect validation behaviour\ntitle: \"\"\nlabels: \""
  },
  {
    "path": ".github/ISSUE_TEMPLATE/change.md",
    "chars": 596,
    "preview": "---\nname: Feature or change proposal\nabout: For proposals of new features, options or some other improvements\ntitle: \"\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/compatibility.md",
    "chars": 870,
    "preview": "---\nname: Browser and compatibility issue\nabout: For issues that only happen in a specific environment\ntitle: \"\"\nlabels:"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/installation.md",
    "chars": 883,
    "preview": "---\nname: Installation and dependency issue\nabout: For issues that happen during installation\ntitle: \"\"\nlabels: \"install"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/typescript.md",
    "chars": 755,
    "preview": "---\nname: Missing or incorrect type definition\nabout: Please use for issues related to typescript types\ntitle: \"\"\nlabels"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 1580,
    "preview": "<!--\nFrequently Asked Questions: https://ajv.js.org/faq.html\nPlease provide all info and reduce your schema and data to "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 535,
    "preview": "<!--\nThank you for submitting a pull request to Ajv.\n\nBefore continuing, please read the guidelines:\nhttps://github.com/"
  },
  {
    "path": ".github/config.yml",
    "chars": 1283,
    "preview": "# Please supply comments to be used for GitHub labels \ngithubLabels:\n  bug: >\n    Bug confirmed - to be fixed. PR is wel"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 428,
    "preview": "version: 2\nupdates:\n- package-ecosystem: npm\n  directory: \"/\"\n  schedule:\n    interval: daily\n  open-pull-requests-limit"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 979,
    "preview": "name: build\n\non:\n  push:\n    branches: [master]\n  pull_request:\n    branches: [\"*\"]\n\njobs:\n  build:\n    runs-on: ubuntu-"
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 997,
    "preview": "name: publish\n\non:\n  release:\n    types: [published]\n\njobs:\n  publish-npm:\n    runs-on: ubuntu-latest\n    steps:\n      -"
  },
  {
    "path": ".gitignore",
    "chars": 822,
    "preview": "# Logs\nlogs\n*.log\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nl"
  },
  {
    "path": ".gitmodules",
    "chars": 271,
    "preview": "[submodule \"spec/JSON-Schema-Test-Suite\"]\n\tpath = spec/JSON-Schema-Test-Suite\n\turl = https://github.com/json-schema/JSON"
  },
  {
    "path": ".npmrc",
    "chars": 19,
    "preview": "package-lock=false\n"
  },
  {
    "path": ".prettierignore",
    "chars": 147,
    "preview": "spec/JSON-Schema-Test-Suite\nspec/json-typedef-spec\n.browser\ncoverage\ndist\nbundle\n.nyc_output\nspec/_json\ndocs/.vuepress/c"
  },
  {
    "path": ".runkit_example.js",
    "chars": 496,
    "preview": "const Ajv = require(\"ajv\")\nconst ajv = new Ajv({allErrors: true})\n\nconst schema = {\n  type: \"object\",\n  properties: {\n  "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 4406,
    "preview": "---\npermalink: /code_of_conduct\n---\n\n# Contributor Covenant Code of Conduct\n\n### Our Pledge\n\nWe commit to creating and m"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 8851,
    "preview": "---\npermalink: /contributing\n---\n\n# Contributing guide\n\nThank you for your help making Ajv better! Every contribution is"
  },
  {
    "path": "LICENSE",
    "chars": 1090,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015-2021 Evgeny Poberezkin\n\nPermission is hereby granted, free of charge, to any p"
  },
  {
    "path": "README.md",
    "chars": 13781,
    "preview": "<img align=\"right\" alt=\"Ajv logo\" width=\"160\" src=\"https://ajv.js.org/img/ajv.svg\">\n\n&nbsp;\n\n# Ajv JSON schema validator"
  },
  {
    "path": "benchmark/jtd.js",
    "chars": 2903,
    "preview": "/* eslint-disable no-empty */\n/* eslint-disable no-console */\nconst Ajv = require(\"ajv/dist/jtd\")\nconst Benchmark = requ"
  },
  {
    "path": "benchmark/package.json",
    "chars": 76,
    "preview": "{\n  \"private\": true,\n  \"devDependencies\": {\n    \"benchmark\": \"^2.1.4\"\n  }\n}\n"
  },
  {
    "path": "bower.json",
    "chars": 360,
    "preview": "{\n  \"name\": \"ajv\",\n  \"description\": \"Another JSON Schema Validator\",\n  \"main\": \"bundle/ajv.min.js\",\n  \"authors\": [\"Evgen"
  },
  {
    "path": "docs/.vuepress/components/Button.vue",
    "chars": 441,
    "preview": "<template>\n  <a :href=\"link\" :class=\"cssClass\" class=\"button\"><slot /></a>\n</template>\n\n<script>\nexport default {\n  prop"
  },
  {
    "path": "docs/.vuepress/components/Column.vue",
    "chars": 371,
    "preview": "<template>\n  <div :class=\"side\" class=\"column\">\n    <slot />\n  </div>\n</template>\n\n<script>\nexport default {\n  props: {\n"
  },
  {
    "path": "docs/.vuepress/components/Columns.vue",
    "chars": 182,
    "preview": "<template>\n  <div class=\"columns\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"stylus\" scoped>\n@media only screen an"
  },
  {
    "path": "docs/.vuepress/components/Contributors.vue",
    "chars": 878,
    "preview": "<template>\n  <div>\n    <a\n      v-for=\"(contributor, i) in contributors\"\n      class=\"contributor\"\n      :style=\"'backgr"
  },
  {
    "path": "docs/.vuepress/components/Feature.vue",
    "chars": 1165,
    "preview": "<template>\n  <div :class=\"type\">\n    <slot />\n    <a class=\"read-more\" :href=\"link\">\n      <img src=\"./Feature/arrow.svg"
  },
  {
    "path": "docs/.vuepress/components/Features.vue",
    "chars": 202,
    "preview": "<template>\n  <div class=\"features\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"stylus\" scoped>\n.features\n  padding "
  },
  {
    "path": "docs/.vuepress/components/FooterColumn.vue",
    "chars": 888,
    "preview": "<template>\n  <div :class=\"type\" class=\"column\">\n    <slot />\n  </div>\n</template>\n\n<script>\nexport default {\n  props: {\n"
  },
  {
    "path": "docs/.vuepress/components/FooterColumns.vue",
    "chars": 253,
    "preview": "<template>\n  <div class=\"footer-columns\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"stylus\" scoped>\n.footer-column"
  },
  {
    "path": "docs/.vuepress/components/GitHub.vue",
    "chars": 705,
    "preview": "<template>\n  <ClientOnly>\n    <span>\n      <a\n        class=\"github-button\"\n        href=\"https://github.com/ajv-validat"
  },
  {
    "path": "docs/.vuepress/components/HeroSection.vue",
    "chars": 1656,
    "preview": "<template>\n  <div class=\"hero-section\">\n    <div class=\"section-content\">\n      <img src=\"./HeroSection/hero-image.svg\" "
  },
  {
    "path": "docs/.vuepress/components/HomePage.vue",
    "chars": 261,
    "preview": "<template>\n  <main class=\"homepage\">\n    <slot name=\"top\" />\n\n    <Content />\n\n    <slot name=\"bottom\" />\n  </main>\n</te"
  },
  {
    "path": "docs/.vuepress/components/HomeSection.vue",
    "chars": 1230,
    "preview": "<template>\n  <div class=\"home-section\" :class=\"section\">\n    <div class=\"section-content\">\n      <slot />\n    </div>\n  <"
  },
  {
    "path": "docs/.vuepress/components/NewsHome.vue",
    "chars": 1282,
    "preview": "<template>\n  <div>\n    <div v-for=\"(post, i) in posts\" class=\"post\">\n      <Columns>\n        <Column side=\"left\">\n      "
  },
  {
    "path": "docs/.vuepress/components/NewsIndex.vue",
    "chars": 677,
    "preview": "<template>\n  <div>\n    <div v-for=\"post in posts\">\n      <h2>{{ post.frontmatter.title }}</h2>\n\n      <router-link :to=\""
  },
  {
    "path": "docs/.vuepress/components/NewsPost.vue",
    "chars": 619,
    "preview": "<template>\n  <main class=\"page\">\n    <slot name=\"top\" />\n\n    <div class=\"theme-default-content\" style=\"padding-bottom: "
  },
  {
    "path": "docs/.vuepress/components/NewsPostMeta.vue",
    "chars": 579,
    "preview": "<template>\n  <div class=\"post-meta\">\n    <time class=\"pub-date\" pubdate itemprop=\"datePublished\" :datetime=\"date\">\n     "
  },
  {
    "path": "docs/.vuepress/components/Projects.vue",
    "chars": 772,
    "preview": "<template>\n  <div class=\"projects\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"stylus\" scoped>\n.projects\n  p\n    ma"
  },
  {
    "path": "docs/.vuepress/components/Sponsors.vue",
    "chars": 1126,
    "preview": "<template>\n  <div class=\"sponsors\" :class=\"level\">\n    <slot />\n  </div>\n</template>\n\n<script>\nexport default {\n  props:"
  },
  {
    "path": "docs/.vuepress/components/Subscribe.vue",
    "chars": 1411,
    "preview": "<template>\n  <form\n    action=\"https://ajv.us1.list-manage.com/subscribe/post?u=4343a2a251fa30892c2360003&amp;id=304f51c"
  },
  {
    "path": "docs/.vuepress/components/Testimonial.vue",
    "chars": 1062,
    "preview": "<template>\n  <div class=\"testimonial-content\" :class=\"color\">\n    <slot />\n  </div>\n</template>\n\n<script>\nexport default"
  },
  {
    "path": "docs/.vuepress/components/Testimonials.vue",
    "chars": 208,
    "preview": "<template>\n  <div class=\"testimonials\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"stylus\" scoped>\n.testimonials\n  "
  },
  {
    "path": "docs/.vuepress/config.js",
    "chars": 5653,
    "preview": "const {slugify} = require(\"@vuepress/shared-utils\")\n\nconst title = \"Ajv JSON schema validator\"\nconst description =\n  \"Th"
  },
  {
    "path": "docs/.vuepress/styles/index.styl",
    "chars": 1428,
    "preview": "img + span > .icon.outbound {\n  display: none;\n}\n\nbody {\n  font-family: 'Raleway';\n  font-weight: normal;\n}\n\nstrong {\n  "
  },
  {
    "path": "docs/.vuepress/styles/palette.styl",
    "chars": 498,
    "preview": "$ajvBlueColor = #409cff\n$ajvGreenColor = #23c8d2 // #1fdca3\n$ajvRedColor = #f5775b\n\n$tipColor = $ajvGreenColor\n$warningC"
  },
  {
    "path": "docs/.vuepress/theme/LICENSE",
    "chars": 1091,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2018-present, Yuxi (Evan) You\n\nPermission is hereby granted, free of charge, to any"
  },
  {
    "path": "docs/.vuepress/theme/components/AlgoliaSearchBox.vue",
    "chars": 4643,
    "preview": "<template>\n  <form\n    id=\"search-form\"\n    class=\"algolia-search-wrapper search-box\"\n    role=\"search\"\n  >\n    <input\n "
  },
  {
    "path": "docs/.vuepress/theme/components/DropdownLink.vue",
    "chars": 5678,
    "preview": "<template>\n  <div\n    class=\"dropdown-wrapper\"\n    :class=\"{ open }\"\n  >\n    <button\n      class=\"dropdown-title\"\n      "
  },
  {
    "path": "docs/.vuepress/theme/components/DropdownTransition.vue",
    "chars": 561,
    "preview": "<template>\n  <transition\n    name=\"dropdown\"\n    @enter=\"setHeight\"\n    @after-enter=\"unsetHeight\"\n    @before-leave=\"se"
  },
  {
    "path": "docs/.vuepress/theme/components/Home.vue",
    "chars": 3573,
    "preview": "<template>\n  <main\n    class=\"home\"\n    :aria-labelledby=\"data.heroText !== null ? 'main-title' : null\"\n  >\n    <header "
  },
  {
    "path": "docs/.vuepress/theme/components/NavLink.vue",
    "chars": 1628,
    "preview": "<template>\n  <RouterLink\n    v-if=\"isInternal\"\n    class=\"nav-link\"\n    :to=\"link\"\n    :exact=\"exact\"\n    @focusout.nati"
  },
  {
    "path": "docs/.vuepress/theme/components/NavLinks.vue",
    "chars": 3614,
    "preview": "<template>\n  <nav\n    v-if=\"userLinks.length || repoLink\"\n    class=\"nav-links\"\n  >\n    <!-- user links -->\n    <div\n   "
  },
  {
    "path": "docs/.vuepress/theme/components/Navbar.vue",
    "chars": 3474,
    "preview": "<template>\n  <header class=\"navbar\">\n    <SidebarButton @toggle-sidebar=\"$emit('toggle-sidebar')\" />\n\n    <RouterLink\n  "
  },
  {
    "path": "docs/.vuepress/theme/components/Page.vue",
    "chars": 535,
    "preview": "<template>\n  <main class=\"page\">\n    <slot name=\"top\" />\n\n    <Content class=\"theme-default-content\" />\n    <PageEdit />"
  },
  {
    "path": "docs/.vuepress/theme/components/PageEdit.vue",
    "chars": 3519,
    "preview": "<template>\n  <footer class=\"page-edit\">\n    <div\n      v-if=\"editLink\"\n      class=\"edit-link\"\n    >\n      <a\n        :h"
  },
  {
    "path": "docs/.vuepress/theme/components/PageNav.vue",
    "chars": 3376,
    "preview": "<template>\n  <div\n    v-if=\"prev || next\"\n    class=\"page-nav\"\n  >\n    <p class=\"inner\">\n      <span\n        v-if=\"prev\""
  },
  {
    "path": "docs/.vuepress/theme/components/Sidebar.vue",
    "chars": 1240,
    "preview": "<template>\n  <aside class=\"sidebar\">\n    <NavLinks />\n\n    <slot name=\"top\" />\n\n    <SidebarLinks\n      :depth=\"0\"\n     "
  },
  {
    "path": "docs/.vuepress/theme/components/SidebarButton.vue",
    "chars": 990,
    "preview": "<template>\n  <div\n    class=\"sidebar-button\"\n    @click=\"$emit('toggle-sidebar')\"\n  >\n    <svg\n      class=\"icon\"\n      "
  },
  {
    "path": "docs/.vuepress/theme/components/SidebarGroup.vue",
    "chars": 2955,
    "preview": "<template>\n  <section\n    class=\"sidebar-group\"\n    :class=\"[\n      {\n        collapsable,\n        'is-sub-group': depth"
  },
  {
    "path": "docs/.vuepress/theme/components/SidebarLink.vue",
    "chars": 3291,
    "preview": "<script>\nimport { isActive, hashRE, groupHeaders } from '../util'\n\nexport default {\n  functional: true,\n\n  props: ['item"
  },
  {
    "path": "docs/.vuepress/theme/components/SidebarLinks.vue",
    "chars": 2184,
    "preview": "<template>\n  <ul\n    v-if=\"items.length\"\n    class=\"sidebar-links\"\n  >\n    <li\n      v-for=\"(item, i) in items\"\n      :k"
  },
  {
    "path": "docs/.vuepress/theme/global-components/Badge.vue",
    "chars": 805,
    "preview": "<script>\nexport default {\n  functional: true,\n  props: {\n    type: {\n      type: String,\n      default: 'tip'\n    },\n   "
  },
  {
    "path": "docs/.vuepress/theme/global-components/CodeBlock.vue",
    "chars": 626,
    "preview": "<template>\n  <div\n    class=\"theme-code-block\"\n    :class=\"{ 'theme-code-block__active': active }\"\n  >\n    <slot />\n  </"
  },
  {
    "path": "docs/.vuepress/theme/global-components/CodeGroup.vue",
    "chars": 2783,
    "preview": "<template>\n  <ClientOnly>\n    <div class=\"theme-code-group\">\n      <div class=\"theme-code-group__nav\">\n        <ul class"
  },
  {
    "path": "docs/.vuepress/theme/index.js",
    "chars": 1599,
    "preview": "const path = require(\"path\")\n\n// Theme API.\nmodule.exports = (options, ctx) => {\n  const {themeConfig, siteConfig} = ctx"
  },
  {
    "path": "docs/.vuepress/theme/layouts/404.vue",
    "chars": 530,
    "preview": "<template>\n  <div class=\"theme-container\">\n    <div class=\"theme-default-content\">\n      <h1>404</h1>\n\n      <blockquote"
  },
  {
    "path": "docs/.vuepress/theme/layouts/Layout.vue",
    "chars": 3672,
    "preview": "<template>\n  <div\n    class=\"theme-container\"\n    :class=\"pageClasses\"\n    @touchstart=\"onTouchStart\"\n    @touchend=\"onT"
  },
  {
    "path": "docs/.vuepress/theme/noopModule.js",
    "chars": 18,
    "preview": "export default {}\n"
  },
  {
    "path": "docs/.vuepress/theme/styles/arrow.styl",
    "chars": 577,
    "preview": "@require './config'\n\n.arrow\n  display inline-block\n  width 0\n  height 0\n  &.up\n    border-left 4px solid transparent\n   "
  },
  {
    "path": "docs/.vuepress/theme/styles/code.styl",
    "chars": 2861,
    "preview": "{$contentClass}\n  code\n    color lighten($textColor, 20%)\n    padding 0.25rem 0.5rem\n    margin 0\n    font-size 0.85em\n "
  },
  {
    "path": "docs/.vuepress/theme/styles/config.styl",
    "chars": 41,
    "preview": "$contentClass = '.theme-default-content'\n"
  },
  {
    "path": "docs/.vuepress/theme/styles/custom-blocks.styl",
    "chars": 961,
    "preview": ".custom-block\n  .custom-block-title\n    font-weight 600\n    margin-bottom -0.4rem\n  &.tip, &.warning, &.danger\n    paddi"
  },
  {
    "path": "docs/.vuepress/theme/styles/index.styl",
    "chars": 3242,
    "preview": "@require './config'\n@require './code'\n@require './custom-blocks'\n@require './arrow'\n@require './wrapper'\n@require './toc"
  },
  {
    "path": "docs/.vuepress/theme/styles/mobile.styl",
    "chars": 731,
    "preview": "@require './config'\n\n$mobileSidebarWidth = $sidebarWidth * 0.82\n\n// narrow desktop / iPad\n@media (max-width: $MQNarrow)\n"
  },
  {
    "path": "docs/.vuepress/theme/styles/toc.styl",
    "chars": 54,
    "preview": ".table-of-contents\n  .badge\n    vertical-align middle\n"
  },
  {
    "path": "docs/.vuepress/theme/styles/wrapper.styl",
    "chars": 180,
    "preview": "$wrapper\n  max-width $contentWidth\n  margin 0 auto\n  padding 2rem 2.5rem\n  @media (max-width: $MQNarrow)\n    padding 2re"
  },
  {
    "path": "docs/.vuepress/theme/util/index.js",
    "chars": 5827,
    "preview": "export const hashRE = /#.*$/\nexport const extRE = /\\.(md|html)$/\nexport const endingSlashRE = /\\/$/\nexport const outboun"
  },
  {
    "path": "docs/README.md",
    "chars": 7297,
    "preview": "---\nhomepage: true\nsidebar: false\n---\n\n<HeroSection>\n\n# Ajv JSON schema validator\n\n## Security and reliability for JavaS"
  },
  {
    "path": "docs/api.md",
    "chars": 22328,
    "preview": "# API Reference\n\n[[toc]]\n\n## Ajv constructor and methods\n\n### new Ajv(options: object)\n\nCreate Ajv instance:\n\n```javascr"
  },
  {
    "path": "docs/codegen.md",
    "chars": 5355,
    "preview": "# Code generation design\n\n[[toc]]\n\nStarting from v7 Ajv uses [CodeGen module](https://github.com/ajv-validator/ajv/blob/"
  },
  {
    "path": "docs/coercion.md",
    "chars": 5529,
    "preview": "# Type coercion rules\n\nTo enable type coercion pass option `coerceTypes` to Ajv with `true` or `array` (it is `false` by"
  },
  {
    "path": "docs/components.md",
    "chars": 2531,
    "preview": "# Code components\n\n[[toc]]\n\n## Ajv classes\n\n[lib/core.ts](https://github.com/ajv-validator/ajv/blob/master/lib/core.ts) "
  },
  {
    "path": "docs/faq.md",
    "chars": 8501,
    "preview": "# Frequently Asked Questions\n\nThe purpose of this document is to help find answers quicker. I am happy to continue the d"
  },
  {
    "path": "docs/guide/async-validation.md",
    "chars": 2988,
    "preview": "# Asynchronous validation\n\nYou can define formats and keywords that perform validation asynchronously by accessing datab"
  },
  {
    "path": "docs/guide/combining-schemas.md",
    "chars": 8859,
    "preview": "# Combining schemas\n\n[[toc]]\n\n## <a name=\"ref\"></a>Combining schemas with $ref\n\nYou can structure your validation logic "
  },
  {
    "path": "docs/guide/environments.md",
    "chars": 5319,
    "preview": "# Execution environments\n\n[[toc]]\n\n## Server-side Node.js\n\nThe main consideration for using Ajv server-side is to [manag"
  },
  {
    "path": "docs/guide/formats.md",
    "chars": 4447,
    "preview": "# Format validation\n\n## String formats\n\nFrom version 7 Ajv does not include formats defined by JSON Schema specification"
  },
  {
    "path": "docs/guide/getting-started.md",
    "chars": 5678,
    "preview": "# Getting started\n\n[[toc]]\n\n## Install\n\n::: tip Node REPL\nYou can try Ajv without installing it in the Node.js REPL: [ht"
  },
  {
    "path": "docs/guide/managing-schemas.md",
    "chars": 9118,
    "preview": "# Managing schemas\n\n[[toc]]\n\n## Re-using validation functions\n\nAjv validation model is optimized for server side executi"
  },
  {
    "path": "docs/guide/modifying-data.md",
    "chars": 9695,
    "preview": "# Modifying data during validation\n\n[[toc]]\n\n## General considerations\n\nAjv has several options that allow to modify dat"
  },
  {
    "path": "docs/guide/schema-language.md",
    "chars": 6884,
    "preview": "---\ntags:\n  - JTD\n---\n\n# Choosing schema language\n\n[[toc]]\n\n## JSON Type Definition\n\nAjv supports the new specification "
  },
  {
    "path": "docs/guide/typescript.md",
    "chars": 8373,
    "preview": "# Using with TypeScript\n\n[[toc]]\n\n## Additional functionality\n\nAjv takes advantage of TypeScript type system to provide "
  },
  {
    "path": "docs/guide/user-keywords.md",
    "chars": 2797,
    "preview": "# User-defined keywords\n\nYou can extend keyword available in Ajv by defining your own keywords.\n\nThe advantages of defin"
  },
  {
    "path": "docs/guide/why-ajv.md",
    "chars": 2573,
    "preview": "# Why use AJV\n\n## Write less code\n\n**Ensure your data is valid as soon as it's received**\n\nInstead of having your data v"
  },
  {
    "path": "docs/json-schema.md",
    "chars": 35464,
    "preview": "# JSON Schema\n\nIn a simple way, JSON Schema is an object with validation keywords.\n\nThe keywords and their values define"
  },
  {
    "path": "docs/json-type-definition.md",
    "chars": 14150,
    "preview": "# JSON Type Definition\n\nThis document informally describes JSON Type Definition (JTD) specification to help Ajv users to"
  },
  {
    "path": "docs/keywords.md",
    "chars": 10986,
    "preview": "# User defined keywords\n\n[[toc]]\n\n## Common attributes of keyword definitions\n\nThe usual interface to define all keyword"
  },
  {
    "path": "docs/news/2020-08-14-mozilla-grant-openjs-foundation.md",
    "chars": 1356,
    "preview": "---\nnews: true\ntitle: Mozilla MOSS grant and OpenJS Foundation\ndate: 2020-08-14\n---\n\n[<img src=\"/img/mozilla.svg\" width="
  },
  {
    "path": "docs/news/2020-12-15-ajv-version-7-released.md",
    "chars": 2066,
    "preview": "---\nnews: true\ntitle: Ajv version 7 is released!\ndate: 2020-12-15\n---\n\nAjv version 7 has these new features:\n\n- support "
  },
  {
    "path": "docs/news/2021-03-07-ajv-supports-json-type-definition.md",
    "chars": 1084,
    "preview": "---\nnews: true\ntitle: Ajv supports JSON Type Definition\ndate: 2021-03-07\n---\n\nJSON Type Definition (JTD) is a new specif"
  },
  {
    "path": "docs/news/2021-03-27-ajv-version-8-released.md",
    "chars": 1054,
    "preview": "---\nnews: true\ntitle: Ajv version 8 is released!\ndate: 2021-03-27\n---\n\nAjv version 8 has these new features:\n\n- support "
  },
  {
    "path": "docs/news/2021-04-24-ajv-online-event.md",
    "chars": 1200,
    "preview": "---\nnews: true\ntitle: \"Ajv online event - May 20, 10am PT / 6pm UK\"\ndate: 2021-04-24\nmore: false\n---\n\nWe will talk about"
  },
  {
    "path": "docs/news/2021-05-24-ajv-online-event-video.md",
    "chars": 256,
    "preview": "---\nnews: true\ntitle: Ajv online event video uploaded\ndate: 2021-05-24\nmore: false\n---\n\nHuge thanks to everybody who joi"
  },
  {
    "path": "docs/news/2021-07-22-ajv-microsoft-foss-fund-award.md",
    "chars": 361,
    "preview": "---\nnews: true\ntitle: Microsoft FOSS award\ndate: 2021-07-22\nmore: false\n---\n\nAjv was awarded a sponsorship from [Microso"
  },
  {
    "path": "docs/news/README.md",
    "chars": 66,
    "preview": "---\nnewsIndex: true\neditLink: false\n---\n\n# Ajv News\n\n<NewsIndex/>\n"
  },
  {
    "path": "docs/options.md",
    "chars": 18236,
    "preview": "# Ajv options\n\n[[toc]]\n\n## Usage\n\nThis page describes properties of the options object that can be passed to Ajv constru"
  },
  {
    "path": "docs/packages/README.md",
    "chars": 1658,
    "preview": "# Extending Ajv\n\n## Plugins\n\nAjv can be extended with plugins that add [user defined schema keywords](../guide/user-keyw"
  },
  {
    "path": "docs/security.md",
    "chars": 7087,
    "preview": "# Security considerations\n\nJSON Schema, if properly used, can replace data sanitisation. It doesn't replace other API se"
  },
  {
    "path": "docs/standalone.md",
    "chars": 9738,
    "preview": "# Standalone validation code\n\n[[toc]]\n\nAjv supports generating standalone validation functions from JSON Schemas at comp"
  },
  {
    "path": "docs/strict-mode.md",
    "chars": 11516,
    "preview": "# Strict mode\n\nStrict mode intends to prevent any unexpected behaviours or silently ignored mistakes in user schemas. It"
  },
  {
    "path": "docs/testimonials.md",
    "chars": 1755,
    "preview": "# What users say\n\nIn the past 6 years of working on the JSON Schema Specification itself, Ajv stands out as the implemen"
  },
  {
    "path": "docs/v6-to-v8-migration.md",
    "chars": 9131,
    "preview": "# Changes from Ajv v6.12.6 to v8.0.0\n\nIf you are migrating from v7 see [v8.0.0 release notes](https://github.com/ajv-val"
  },
  {
    "path": "karma.conf.js",
    "chars": 1671,
    "preview": "// Karma configuration\n// Generated on Thu Mar 13 2014 14:12:04 GMT-0700 (PDT)\n\nmodule.exports = function (config) {\n  c"
  },
  {
    "path": "lib/2019.ts",
    "chars": 2502,
    "preview": "import type {AnySchemaObject} from \"./types\"\nimport AjvCore, {Options} from \"./core\"\n\nimport draft7Vocabularies from \"./"
  },
  {
    "path": "lib/2020.ts",
    "chars": 2217,
    "preview": "import type {AnySchemaObject} from \"./types\"\nimport AjvCore, {Options} from \"./core\"\n\nimport draft2020Vocabularies from "
  },
  {
    "path": "lib/ajv.ts",
    "chars": 2229,
    "preview": "import type {AnySchemaObject} from \"./types\"\nimport AjvCore from \"./core\"\nimport draft7Vocabularies from \"./vocabularies"
  },
  {
    "path": "lib/compile/codegen/code.ts",
    "chars": 4474,
    "preview": "// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport abstract class _CodeOrName {\n  abstract readon"
  },
  {
    "path": "lib/compile/codegen/index.ts",
    "chars": 23051,
    "preview": "import type {ScopeValueSets, NameValue, ValueScope, ValueScopeName} from \"./scope\"\nimport {_, nil, _Code, Code, Name, Us"
  },
  {
    "path": "lib/compile/codegen/scope.ts",
    "chars": 5981,
    "preview": "import {_, nil, Code, Name} from \"./code\"\n\ninterface NameGroup {\n  prefix: string\n  index: number\n}\n\nexport interface Na"
  },
  {
    "path": "lib/compile/errors.ts",
    "chars": 5269,
    "preview": "import type {KeywordErrorCxt, KeywordErrorDefinition} from \"../types\"\nimport type {SchemaCxt} from \"./index\"\nimport {Cod"
  },
  {
    "path": "lib/compile/index.ts",
    "chars": 12299,
    "preview": "import type {\n  AnySchema,\n  AnySchemaObject,\n  AnyValidateFunction,\n  AsyncValidateFunction,\n  EvaluatedProperties,\n  E"
  },
  {
    "path": "lib/compile/jtd/parse.ts",
    "chars": 12345,
    "preview": "import type Ajv from \"../../core\"\nimport type {SchemaObject} from \"../../types\"\nimport {jtdForms, JTDForm, SchemaObjectM"
  },
  {
    "path": "lib/compile/jtd/serialize.ts",
    "chars": 8573,
    "preview": "import type Ajv from \"../../core\"\nimport type {SchemaObject} from \"../../types\"\nimport {jtdForms, JTDForm, SchemaObjectM"
  },
  {
    "path": "lib/compile/jtd/types.ts",
    "chars": 311,
    "preview": "import type {SchemaObject} from \"../../types\"\n\nexport type SchemaObjectMap = {[Ref in string]?: SchemaObject}\n\nexport co"
  },
  {
    "path": "lib/compile/names.ts",
    "chars": 1116,
    "preview": "import {Name} from \"./codegen\"\n\nconst names = {\n  // validation function arguments\n  data: new Name(\"data\"), // data pas"
  },
  {
    "path": "lib/compile/ref_error.ts",
    "chars": 513,
    "preview": "import {resolveUrl, normalizeId, getFullPath} from \"./resolve\"\nimport type {UriResolver} from \"../types\"\n\nexport default"
  },
  {
    "path": "lib/compile/resolve.ts",
    "chars": 4674,
    "preview": "import type {AnySchema, AnySchemaObject, UriResolver} from \"../types\"\nimport type Ajv from \"../ajv\"\nimport type {URIComp"
  },
  {
    "path": "lib/compile/rules.ts",
    "chars": 1456,
    "preview": "import type {AddedKeywordDefinition} from \"../types\"\n\nconst _jsonTypes = [\"string\", \"number\", \"integer\", \"boolean\", \"nul"
  },
  {
    "path": "lib/compile/util.ts",
    "chars": 6639,
    "preview": "import type {AnySchema, EvaluatedProperties, EvaluatedItems} from \"../types\"\nimport type {SchemaCxt, SchemaObjCxt} from "
  },
  {
    "path": "lib/compile/validate/applicability.ts",
    "chars": 739,
    "preview": "import type {AnySchemaObject} from \"../../types\"\nimport type {SchemaObjCxt} from \"..\"\nimport type {JSONType, RuleGroup, "
  },
  {
    "path": "lib/compile/validate/boolSchema.ts",
    "chars": 1298,
    "preview": "import type {KeywordErrorDefinition, KeywordErrorCxt} from \"../../types\"\nimport type {SchemaCxt} from \"..\"\nimport {repor"
  },
  {
    "path": "lib/compile/validate/dataType.ts",
    "chars": 7094,
    "preview": "import type {\n  KeywordErrorDefinition,\n  KeywordErrorCxt,\n  ErrorObject,\n  AnySchemaObject,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/compile/validate/defaults.ts",
    "chars": 1215,
    "preview": "import type {SchemaObjCxt} from \"..\"\nimport {_, getProperty, stringify} from \"../codegen\"\nimport {checkStrictMode} from "
  },
  {
    "path": "lib/compile/validate/index.ts",
    "chars": 19445,
    "preview": "import type {\n  AddedKeywordDefinition,\n  AnySchema,\n  AnySchemaObject,\n  KeywordErrorCxt,\n  KeywordCxtParams,\n} from \"."
  },
  {
    "path": "lib/compile/validate/keyword.ts",
    "chars": 5337,
    "preview": "import type {KeywordCxt} from \".\"\nimport type {\n  AnySchema,\n  SchemaValidateFunction,\n  AnyValidateFunction,\n  AddedKey"
  },
  {
    "path": "lib/compile/validate/subschema.ts",
    "chars": 4366,
    "preview": "import type {AnySchema} from \"../../types\"\nimport type {SchemaObjCxt} from \"..\"\nimport {_, str, getProperty, Code, Name}"
  },
  {
    "path": "lib/core.ts",
    "chars": 30773,
    "preview": "export {\n  Format,\n  FormatDefinition,\n  AsyncFormatDefinition,\n  KeywordDefinition,\n  KeywordErrorDefinition,\n  CodeKey"
  },
  {
    "path": "lib/jtd.ts",
    "chars": 4172,
    "preview": "import type {AnySchemaObject, SchemaObject, JTDParser} from \"./types\"\nimport type {JTDSchemaType, SomeJTDSchemaType, JTD"
  },
  {
    "path": "lib/refs/data.json",
    "chars": 409,
    "preview": "{\n  \"$id\": \"https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#\",\n  \"description\": \"Meta-sche"
  },
  {
    "path": "lib/refs/json-schema-2019-09/index.ts",
    "chars": 899,
    "preview": "import type Ajv from \"../../core\"\nimport type {AnySchemaObject} from \"../../types\"\nimport * as metaSchema from \"./schema"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/applicator.json",
    "chars": 1566,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/appl"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/content.json",
    "chars": 477,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/cont"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/core.json",
    "chars": 1273,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/core"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/format.json",
    "chars": 375,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/form"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/meta-data.json",
    "chars": 758,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/meta"
  },
  {
    "path": "lib/refs/json-schema-2019-09/meta/validation.json",
    "chars": 2264,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/meta/vali"
  },
  {
    "path": "lib/refs/json-schema-2019-09/schema.json",
    "chars": 1579,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://json-schema.org/draft/2019-09/schema\",\n"
  },
  {
    "path": "lib/refs/json-schema-2020-12/index.ts",
    "chars": 982,
    "preview": "import type Ajv from \"../../core\"\nimport type {AnySchemaObject} from \"../../types\"\nimport * as metaSchema from \"./schema"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/applicator.json",
    "chars": 1441,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/appl"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/content.json",
    "chars": 479,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/cont"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/core.json",
    "chars": 1344,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/core"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/format-annotation.json",
    "chars": 420,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/form"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/meta-data.json",
    "chars": 758,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/meta"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/unevaluated.json",
    "chars": 472,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/unev"
  },
  {
    "path": "lib/refs/json-schema-2020-12/meta/validation.json",
    "chars": 2264,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/meta/vali"
  },
  {
    "path": "lib/refs/json-schema-2020-12/schema.json",
    "chars": 2166,
    "preview": "{\n  \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n  \"$id\": \"https://json-schema.org/draft/2020-12/schema\",\n"
  },
  {
    "path": "lib/refs/json-schema-draft-06.json",
    "chars": 3449,
    "preview": "{\n  \"$schema\": \"http://json-schema.org/draft-06/schema#\",\n  \"$id\": \"http://json-schema.org/draft-06/schema#\",\n  \"title\":"
  },
  {
    "path": "lib/refs/json-schema-draft-07.json",
    "chars": 3811,
    "preview": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"http://json-schema.org/draft-07/schema#\",\n  \"title\":"
  },
  {
    "path": "lib/refs/json-schema-secure.json",
    "chars": 2521,
    "preview": "{\n  \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n  \"$id\": \"https://raw.githubusercontent.com/ajv-validator/ajv/"
  },
  {
    "path": "lib/refs/jtd-schema.ts",
    "chars": 2586,
    "preview": "import {SchemaObject} from \"../types\"\n\ntype MetaSchema = (root: boolean) => SchemaObject\n\nconst shared: MetaSchema = (ro"
  },
  {
    "path": "lib/runtime/equal.ts",
    "chars": 236,
    "preview": "// https://github.com/ajv-validator/ajv/issues/889\nimport * as equal from \"fast-deep-equal\"\n\ntype Equal = typeof equal &"
  },
  {
    "path": "lib/runtime/parseJson.ts",
    "chars": 4553,
    "preview": "const rxParseJson = /position\\s(\\d+)(?: \\(line \\d+ column \\d+\\))?$/\n\nexport function parseJson(s: string, pos: number): "
  },
  {
    "path": "lib/runtime/quote.ts",
    "chars": 802,
    "preview": "const rxEscapable =\n  // eslint-disable-next-line no-control-regex, no-misleading-character-class\n  /[\\\\\"\\u0000-\\u001f\\u"
  },
  {
    "path": "lib/runtime/re2.ts",
    "chars": 157,
    "preview": "import * as re2 from \"re2\"\n\ntype Re2 = typeof re2 & {code: string}\n;(re2 as Re2).code = 'require(\"ajv/dist/runtime/re2\")"
  },
  {
    "path": "lib/runtime/timestamp.ts",
    "chars": 1492,
    "preview": "const DT_SEPARATOR = /t|\\s/i\nconst DATE = /^(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)$/\nconst TIME = /^(\\d\\d):(\\d\\d):(\\d\\d)(?:\\.\\d+)?(?:z"
  },
  {
    "path": "lib/runtime/ucs2length.ts",
    "chars": 629,
    "preview": "// https://mathiasbynens.be/notes/javascript-encoding\n// https://github.com/bestiejs/punycode.js - punycode.ucs2.decode\n"
  },
  {
    "path": "lib/runtime/uri.ts",
    "chars": 162,
    "preview": "import * as uri from \"fast-uri\"\n\ntype URI = typeof uri & {code: string}\n;(uri as URI).code = 'require(\"ajv/dist/runtime/"
  },
  {
    "path": "lib/runtime/validation_error.ts",
    "chars": 336,
    "preview": "import type {ErrorObject} from \"../types\"\n\nexport default class ValidationError extends Error {\n  readonly errors: Parti"
  },
  {
    "path": "lib/standalone/index.ts",
    "chars": 4151,
    "preview": "import type AjvCore from \"../core\"\nimport type {AnyValidateFunction, SourceCode} from \"../types\"\nimport type {SchemaEnv}"
  },
  {
    "path": "lib/standalone/instance.ts",
    "chars": 1272,
    "preview": "import Ajv, {AnySchema, AnyValidateFunction, ErrorObject} from \"../core\"\nimport standaloneCode from \".\"\nimport * as requ"
  },
  {
    "path": "lib/types/index.ts",
    "chars": 7289,
    "preview": "import {URIComponent} from \"fast-uri\"\nimport type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from \"../compile"
  },
  {
    "path": "lib/types/json-schema.ts",
    "chars": 6380,
    "preview": "/* eslint-disable @typescript-eslint/no-empty-interface */\ntype StrictNullChecksWrapper<Name extends string, Type> = und"
  },
  {
    "path": "lib/types/jtd-schema.ts",
    "chars": 9321,
    "preview": "/** numeric strings */\ntype NumberType = \"float32\" | \"float64\" | \"int8\" | \"uint8\" | \"int16\" | \"uint16\" | \"int32\" | \"uint"
  },
  {
    "path": "lib/vocabularies/applicator/additionalItems.ts",
    "chars": 1824,
    "preview": "import type {\n  CodeKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/additionalProperties.ts",
    "chars": 3782,
    "preview": "import type {\n  CodeKeywordDefinition,\n  AddedKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  AnySchema,\n}"
  },
  {
    "path": "lib/vocabularies/applicator/allOf.ts",
    "chars": 717,
    "preview": "import type {CodeKeywordDefinition, AnySchema} from \"../../types\"\nimport type {KeywordCxt} from \"../../compile/validate\""
  },
  {
    "path": "lib/vocabularies/applicator/anyOf.ts",
    "chars": 380,
    "preview": "import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from \"../../types\"\nimport {validateUnion} from \"../code\"\n\n"
  },
  {
    "path": "lib/vocabularies/applicator/contains.ts",
    "chars": 3278,
    "preview": "import type {\n  CodeKeywordDefinition,\n  KeywordErrorDefinition,\n  ErrorObject,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/dependencies.ts",
    "chars": 3391,
    "preview": "import type {\n  CodeKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  SchemaMap,\n  AnySchema,\n} from \"../../"
  },
  {
    "path": "lib/vocabularies/applicator/dependentSchemas.ts",
    "chars": 280,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\nimport {validateSchemaDeps} from \"./dependencies\"\n\nconst def: Cod"
  },
  {
    "path": "lib/vocabularies/applicator/if.ts",
    "chars": 2395,
    "preview": "import type {\n  CodeKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/index.ts",
    "chars": 1592,
    "preview": "import type {ErrorNoParams, Vocabulary} from \"../../types\"\nimport additionalItems, {AdditionalItemsError} from \"./additi"
  },
  {
    "path": "lib/vocabularies/applicator/items.ts",
    "chars": 1892,
    "preview": "import type {CodeKeywordDefinition, AnySchema, AnySchemaObject} from \"../../types\"\nimport type {KeywordCxt} from \"../../"
  },
  {
    "path": "lib/vocabularies/applicator/items2020.ts",
    "chars": 1053,
    "preview": "import type {\n  CodeKeywordDefinition,\n  KeywordErrorDefinition,\n  ErrorObject,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/not.ts",
    "chars": 859,
    "preview": "import type {CodeKeywordDefinition, ErrorNoParams, AnySchema} from \"../../types\"\nimport type {KeywordCxt} from \"../../co"
  },
  {
    "path": "lib/vocabularies/applicator/oneOf.ts",
    "chars": 2197,
    "preview": "import type {\n  CodeKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/patternProperties.ts",
    "chars": 2870,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\nimport type {KeywordCxt} from \"../../compile/validate\"\nimport {al"
  },
  {
    "path": "lib/vocabularies/applicator/prefixItems.ts",
    "chars": 292,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\nimport {validateTuple} from \"./items\"\n\nconst def: CodeKeywordDefi"
  },
  {
    "path": "lib/vocabularies/applicator/properties.ts",
    "chars": 1845,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\nimport {KeywordCxt} from \"../../compile/validate\"\nimport {propert"
  },
  {
    "path": "lib/vocabularies/applicator/propertyNames.ts",
    "chars": 1247,
    "preview": "import type {\n  CodeKeywordDefinition,\n  ErrorObject,\n  KeywordErrorDefinition,\n  AnySchema,\n} from \"../../types\"\nimport"
  },
  {
    "path": "lib/vocabularies/applicator/thenElse.ts",
    "chars": 441,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\nimport type {KeywordCxt} from \"../../compile/validate\"\nimport {ch"
  },
  {
    "path": "lib/vocabularies/code.ts",
    "chars": 5247,
    "preview": "import type {AnySchema, SchemaMap} from \"../types\"\nimport type {SchemaCxt} from \"../compile\"\nimport type {KeywordCxt} fr"
  },
  {
    "path": "lib/vocabularies/core/id.ts",
    "chars": 224,
    "preview": "import type {CodeKeywordDefinition} from \"../../types\"\n\nconst def: CodeKeywordDefinition = {\n  keyword: \"id\",\n  code() {"
  },
  {
    "path": "lib/vocabularies/core/index.ts",
    "chars": 274,
    "preview": "import type {Vocabulary} from \"../../types\"\nimport idKeyword from \"./id\"\nimport refKeyword from \"./ref\"\n\nconst core: Voc"
  },
  {
    "path": "lib/vocabularies/core/ref.ts",
    "chars": 4384,
    "preview": "import type {CodeKeywordDefinition, AnySchema} from \"../../types\"\nimport type {KeywordCxt} from \"../../compile/validate\""
  }
]

// ... and 233 more files (download for full content)

About this extraction

This page contains the full source code of the ajv-validator/ajv GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 433 files (1.8 MB), approximately 574.5k tokens, and a symbol index with 1013 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!