@salesforcedevs/sfdocs-liquid-lint-frontmatter 0.0.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # liquid-lint-frontmatter
2
+
3
+ Validate the `liquid` frontmatter schema in sfdocs Markdown files.
4
+
5
+ ## What it checks
6
+
7
+ | Check | Example bad input | Error |
8
+ |-------|-------------------|-------|
9
+ | `liquid` must be an object | `liquid: 42` | "must be an object" |
10
+ | `enabled` is required | `liquid: { data: x.yaml }` | "missing required property 'enabled'" |
11
+ | `enabled` must be boolean | `liquid: { enabled: "true" }` | "must be a boolean" |
12
+ | `data` must be a string | `liquid: { enabled: true, data: 42 }` | "must be a string" |
13
+ | `data` must not be empty | `liquid: { enabled: true, data: " " }` | "must not be empty" |
14
+ | `data` must be `.yml`/`.yaml` | `liquid: { enabled: true, data: d.json }` | "must reference a YAML file" |
15
+ | `data` file must exist | `liquid: { enabled: true, data: gone.yaml }` | "data file not found" |
16
+ | `data` file must parse | `liquid: { enabled: true, data: bad.yaml }` | "not valid YAML" |
17
+ | No unknown properties | `liquid: { enabled: true, debug: true }` | "Unknown property 'debug'" |
18
+
19
+ ## Schema
20
+
21
+ ```json
22
+ {
23
+ "liquid": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": ["enabled"],
27
+ "properties": {
28
+ "enabled": { "type": "boolean" },
29
+ "data": { "type": "string", "pattern": "\\.(ya?ml)$" }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ yarn add @salesforcedevs/sfdocs-liquid-lint-frontmatter
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ Configured in the sfdocs validate lint config as `liquid-frontmatter`.
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export = _default;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAqJA,kBAA8C"}
package/dist/index.js ADDED
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const fs_1 = __importDefault(require("fs"));
6
+ const path_1 = __importDefault(require("path"));
7
+ const gray_matter_1 = __importDefault(require("gray-matter"));
8
+ const js_yaml_1 = __importDefault(require("js-yaml"));
9
+ const ajv_1 = __importDefault(require("ajv"));
10
+ const ajv_errors_1 = __importDefault(require("ajv-errors"));
11
+ const yaml_source_map_1 = __importDefault(require("yaml-source-map"));
12
+ const yaml_1 = __importDefault(require("yaml"));
13
+ const vfile_message_1 = __importDefault(require("vfile-message"));
14
+ const unified_lint_rule_1 = __importDefault(require("unified-lint-rule"));
15
+ const SOURCE = 'sfdocs-liquid-lint:liquid-frontmatter';
16
+ const liquidFrontmatterSchema = {
17
+ type: 'object',
18
+ properties: {
19
+ liquid: {
20
+ type: 'object',
21
+ additionalProperties: false,
22
+ required: ['enabled'],
23
+ properties: {
24
+ enabled: { type: 'boolean' },
25
+ data: { type: 'string', pattern: '\\.(ya?ml)$' },
26
+ },
27
+ errorMessage: {
28
+ type: "'liquid' must be an object.",
29
+ required: {
30
+ enabled: "'enabled' property is required in 'liquid' frontmatter.",
31
+ },
32
+ additionalProperties: "Unknown property in 'liquid'. Allowed properties: enabled, data.",
33
+ properties: {
34
+ enabled: "'liquid.enabled' must be a boolean (true or false).",
35
+ data: "'liquid.data' must be a string ending in .yml or .yaml.",
36
+ },
37
+ },
38
+ },
39
+ },
40
+ };
41
+ const ajv = new ajv_1.default({ allErrors: true });
42
+ (0, ajv_errors_1.default)(ajv);
43
+ const validateSchema = ajv.compile(liquidFrontmatterSchema);
44
+ function checkDataFile(file, dataValue) {
45
+ var _a;
46
+ if (!file.path)
47
+ return;
48
+ const trimmed = dataValue.trim();
49
+ if (!trimmed) {
50
+ file.message(`'liquid.data' must not be empty or whitespace.`);
51
+ return;
52
+ }
53
+ const resolved = path_1.default.resolve(path_1.default.dirname(file.path), trimmed);
54
+ if (!fs_1.default.existsSync(resolved)) {
55
+ file.message(`Liquid data file not found: ${resolved}`);
56
+ return;
57
+ }
58
+ try {
59
+ const contents = fs_1.default.readFileSync(resolved, 'utf8');
60
+ js_yaml_1.default.load(contents);
61
+ }
62
+ catch (err) {
63
+ file.message(`Liquid data file is not valid YAML: ${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : String(err)}`);
64
+ }
65
+ }
66
+ function checkLiquidFrontmatter(_tree, file) {
67
+ var _a;
68
+ if (!file.path)
69
+ return;
70
+ const raw = String((_a = file.contents) !== null && _a !== void 0 ? _a : '');
71
+ if (!raw)
72
+ return;
73
+ let frontMatterData;
74
+ try {
75
+ const { data } = (0, gray_matter_1.default)(raw, {});
76
+ frontMatterData = data;
77
+ }
78
+ catch {
79
+ return;
80
+ }
81
+ if (!(frontMatterData === null || frontMatterData === void 0 ? void 0 : frontMatterData.liquid))
82
+ return;
83
+ if (!validateSchema(frontMatterData)) {
84
+ if (validateSchema.errors && validateSchema.errors.length > 0) {
85
+ const frontMatterMatch = raw.match(/---\n([\s\S]+?)\n---/);
86
+ if (!frontMatterMatch)
87
+ return;
88
+ const frontMatterYaml = frontMatterMatch[1];
89
+ const frontMatterStartLine = 2;
90
+ let sourceMap;
91
+ let document;
92
+ try {
93
+ sourceMap = new yaml_source_map_1.default();
94
+ document = sourceMap.index(yaml_1.default.parseDocument(frontMatterYaml, {
95
+ keepCstNodes: true,
96
+ }));
97
+ }
98
+ catch {
99
+ validateSchema.errors.forEach((error) => {
100
+ const errorMessage = new vfile_message_1.default(error.message || 'Invalid liquid frontmatter.', { line: frontMatterStartLine, column: 1 }, SOURCE);
101
+ errorMessage.fatal = true;
102
+ file.messages.push(errorMessage);
103
+ });
104
+ return;
105
+ }
106
+ validateSchema.errors.forEach((error) => {
107
+ const schemaPath = (error.dataPath || error.instancePath || '')
108
+ .split('/')
109
+ .filter((e) => String(e).trim());
110
+ const fileCounter = sourceMap.lookup(schemaPath, document);
111
+ const line = fileCounter && fileCounter.start
112
+ ? fileCounter.start.line + frontMatterStartLine - 1
113
+ : frontMatterStartLine;
114
+ const column = fileCounter && fileCounter.start
115
+ ? fileCounter.start.col
116
+ : 1;
117
+ const errorMessage = new vfile_message_1.default(error.message || 'Invalid liquid frontmatter.', { line, column }, SOURCE);
118
+ errorMessage.fatal = true;
119
+ file.messages.push(errorMessage);
120
+ });
121
+ }
122
+ return;
123
+ }
124
+ const liquid = frontMatterData.liquid;
125
+ if (liquid && typeof liquid === 'object' && typeof liquid.data === 'string') {
126
+ checkDataFile(file, liquid.data);
127
+ }
128
+ }
129
+ module.exports = (0, unified_lint_rule_1.default)(SOURCE, checkLiquidFrontmatter);
130
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/jest.config.js ADDED
@@ -0,0 +1,16 @@
1
+ const BASE_CONFIG = require('../../scripts/jest/common.config');
2
+
3
+ module.exports = {
4
+ ...BASE_CONFIG,
5
+ displayName: 'liquid-lint-frontmatter',
6
+ collectCoverageFrom: ['<rootDir>/**/src/*.{ts,js}'],
7
+ coveragePathIgnorePatterns: ['/node_modules/', '/dist/'],
8
+ testMatch: ['<rootDir>/**/__tests__/**/*.{test,spec}.ts'],
9
+ testPathIgnorePatterns: ['lib/', 'node_modules/'],
10
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
11
+ preset: 'ts-jest',
12
+ testEnvironment: 'node',
13
+ transform: {
14
+ '^.+\\.ts$': 'ts-jest',
15
+ },
16
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@salesforcedevs/sfdocs-liquid-lint-frontmatter",
3
+ "version": "0.0.1-alpha",
4
+ "description": "Validate the 'liquid' frontmatter schema and external data file references in sfdocs Markdown.",
5
+ "author": "SFDocs Team",
6
+ "main": "dist/index.js",
7
+ "scripts": {
8
+ "build": "yarn compile",
9
+ "compile": "tsc -p tsconfig.json",
10
+ "prepublish": "yarn build",
11
+ "test": "jest",
12
+ "test:ci": "yarn test --maxWorkers=1 --ci --coverage",
13
+ "watch": "tsc --watch"
14
+ },
15
+ "license": "MIT",
16
+ "dependencies": {
17
+ "ajv": "^7.2.4",
18
+ "ajv-errors": "^2.0.1",
19
+ "gray-matter": "^4.0.3",
20
+ "js-yaml": "^4.1.0",
21
+ "unified-lint-rule": "^1.0.6",
22
+ "unist-util-visit": "^2.0.3",
23
+ "vfile": "^4.2.1",
24
+ "vfile-message": "^2.0.4",
25
+ "yaml": "^1.10.2",
26
+ "yaml-source-map": "^2.1.1"
27
+ },
28
+ "devDependencies": {
29
+ "@types/jest": "^25.2.2",
30
+ "@types/js-yaml": "^4.0.9",
31
+ "@types/node": "^15.6.1",
32
+ "dedent": "^0.7.0",
33
+ "jest": "^29.7.0",
34
+ "mock-fs": "^5.5.0",
35
+ "remark": "^13.0.0",
36
+ "ts-jest": "^29.2.5",
37
+ "typescript": "^4.4.2",
38
+ "unified": "^9.0.0"
39
+ }
40
+ }
@@ -0,0 +1,155 @@
1
+ import dedent from 'dedent';
2
+ import mockFs from 'mock-fs';
3
+ import remark from 'remark';
4
+ import unified from 'unified';
5
+ import vfile, { VFile } from 'vfile';
6
+
7
+ import plugin from '../index';
8
+
9
+ const PAGE = '/repo/content/en-us/foo/guides/page.md';
10
+
11
+ const run = (md: string, p = PAGE): VFile =>
12
+ remark()
13
+ .use(plugin as unified.Attacher)
14
+ .processSync(vfile({ path: p, contents: md }));
15
+
16
+ describe('sfdocs-lint:liquid-frontmatter', () => {
17
+ afterEach(() => {
18
+ mockFs.restore();
19
+ });
20
+
21
+ test('no messages when liquid key is absent', () => {
22
+ const md = dedent`
23
+ ---
24
+ title: Hello
25
+ ---
26
+
27
+ Some content.
28
+ `;
29
+ expect(run(md).messages).toHaveLength(0);
30
+ });
31
+
32
+ test('no messages for valid liquid frontmatter', () => {
33
+ const md = dedent`
34
+ ---
35
+ liquid:
36
+ enabled: true
37
+ ---
38
+
39
+ Content.
40
+ `;
41
+ expect(run(md).messages).toHaveLength(0);
42
+ });
43
+
44
+ test('flags liquid.enabled when not boolean', () => {
45
+ const md = dedent`
46
+ ---
47
+ liquid:
48
+ enabled: "yes"
49
+ ---
50
+
51
+ Content.
52
+ `;
53
+ const messages = run(md).messages;
54
+ expect(messages.length).toBeGreaterThanOrEqual(1);
55
+ expect(messages[0].message).toMatch(/boolean/i);
56
+ });
57
+
58
+ test('flags missing enabled property', () => {
59
+ const md = dedent`
60
+ ---
61
+ liquid:
62
+ data: extra.yaml
63
+ ---
64
+
65
+ Content.
66
+ `;
67
+ const messages = run(md).messages;
68
+ expect(messages.length).toBeGreaterThanOrEqual(1);
69
+ expect(messages[0].message).toMatch(/enabled/i);
70
+ });
71
+
72
+ test('flags unknown properties', () => {
73
+ const md = dedent`
74
+ ---
75
+ liquid:
76
+ enabled: true
77
+ debug: true
78
+ ---
79
+
80
+ Content.
81
+ `;
82
+ const messages = run(md).messages;
83
+ expect(messages.length).toBeGreaterThanOrEqual(1);
84
+ expect(messages[0].message).toMatch(/Unknown property/i);
85
+ });
86
+
87
+ test('flags non-yaml data extension', () => {
88
+ const md = dedent`
89
+ ---
90
+ liquid:
91
+ enabled: true
92
+ data: data.json
93
+ ---
94
+
95
+ Content.
96
+ `;
97
+ const messages = run(md).messages;
98
+ expect(messages.length).toBeGreaterThanOrEqual(1);
99
+ expect(messages[0].message).toMatch(/\.yml or \.yaml/i);
100
+ });
101
+
102
+ test('validates data file exists', () => {
103
+ mockFs({
104
+ '/repo/content/en-us/foo/guides/page.md': '',
105
+ });
106
+ const md = dedent`
107
+ ---
108
+ liquid:
109
+ enabled: true
110
+ data: missing.yaml
111
+ ---
112
+
113
+ Content.
114
+ `;
115
+ const messages = run(md).messages;
116
+ expect(messages.length).toBeGreaterThanOrEqual(1);
117
+ expect(messages[0].message).toMatch(/not found/i);
118
+ });
119
+
120
+ test('validates data file is valid YAML', () => {
121
+ mockFs({
122
+ '/repo/content/en-us/foo/guides/page.md': '',
123
+ '/repo/content/en-us/foo/guides/bad.yaml': '{ invalid yaml [[[',
124
+ });
125
+ const md = dedent`
126
+ ---
127
+ liquid:
128
+ enabled: true
129
+ data: bad.yaml
130
+ ---
131
+
132
+ Content.
133
+ `;
134
+ const messages = run(md).messages;
135
+ expect(messages.length).toBeGreaterThanOrEqual(1);
136
+ expect(messages[0].message).toMatch(/not valid YAML/i);
137
+ });
138
+
139
+ test('passes with valid data file', () => {
140
+ mockFs({
141
+ '/repo/content/en-us/foo/guides/page.md': '',
142
+ '/repo/content/en-us/foo/guides/extra.yaml': 'key: value\n',
143
+ });
144
+ const md = dedent`
145
+ ---
146
+ liquid:
147
+ enabled: true
148
+ data: extra.yaml
149
+ ---
150
+
151
+ Content.
152
+ `;
153
+ expect(run(md).messages).toHaveLength(0);
154
+ });
155
+ });
package/src/index.ts ADDED
@@ -0,0 +1,150 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import grayMatter from 'gray-matter';
4
+ import yaml from 'js-yaml';
5
+ import Ajv from 'ajv';
6
+ import AjvErrors from 'ajv-errors';
7
+ import YAMLSourceMap from 'yaml-source-map';
8
+ import yamlLib from 'yaml';
9
+ import VMessage, { VFileMessage } from 'vfile-message';
10
+ import rule from 'unified-lint-rule';
11
+ import { VFile } from 'vfile';
12
+
13
+ const SOURCE = 'sfdocs-liquid-lint:liquid-frontmatter';
14
+
15
+ const liquidFrontmatterSchema = {
16
+ type: 'object',
17
+ properties: {
18
+ liquid: {
19
+ type: 'object',
20
+ additionalProperties: false,
21
+ required: ['enabled'],
22
+ properties: {
23
+ enabled: { type: 'boolean' },
24
+ data: { type: 'string', pattern: '\\.(ya?ml)$' },
25
+ },
26
+ errorMessage: {
27
+ type: "'liquid' must be an object.",
28
+ required: {
29
+ enabled:
30
+ "'enabled' property is required in 'liquid' frontmatter.",
31
+ },
32
+ additionalProperties:
33
+ "Unknown property in 'liquid'. Allowed properties: enabled, data.",
34
+ properties: {
35
+ enabled: "'liquid.enabled' must be a boolean (true or false).",
36
+ data: "'liquid.data' must be a string ending in .yml or .yaml.",
37
+ },
38
+ },
39
+ },
40
+ },
41
+ };
42
+
43
+ const ajv = new Ajv({ allErrors: true });
44
+ AjvErrors(ajv);
45
+ const validateSchema = ajv.compile(liquidFrontmatterSchema);
46
+
47
+ function checkDataFile(file: VFile, dataValue: string): void {
48
+ if (!file.path) return;
49
+
50
+ const trimmed = dataValue.trim();
51
+ if (!trimmed) {
52
+ file.message(`'liquid.data' must not be empty or whitespace.`);
53
+ return;
54
+ }
55
+
56
+ const resolved = path.resolve(path.dirname(file.path), trimmed);
57
+
58
+ if (!fs.existsSync(resolved)) {
59
+ file.message(`Liquid data file not found: ${resolved}`);
60
+ return;
61
+ }
62
+
63
+ try {
64
+ const contents = fs.readFileSync(resolved, 'utf8');
65
+ yaml.load(contents);
66
+ } catch (err: any) {
67
+ file.message(
68
+ `Liquid data file is not valid YAML: ${err?.message ?? String(err)}`,
69
+ );
70
+ }
71
+ }
72
+
73
+ function checkLiquidFrontmatter(_tree: unknown, file: VFile): void {
74
+ if (!file.path) return;
75
+ const raw = String(file.contents ?? '');
76
+ if (!raw) return;
77
+
78
+ let frontMatterData: Record<string, any>;
79
+ try {
80
+ const { data } = grayMatter(raw, {});
81
+ frontMatterData = data;
82
+ } catch {
83
+ return;
84
+ }
85
+
86
+ if (!frontMatterData?.liquid) return;
87
+
88
+ if (!validateSchema(frontMatterData)) {
89
+ if (validateSchema.errors && validateSchema.errors.length > 0) {
90
+ const frontMatterMatch = raw.match(/---\n([\s\S]+?)\n---/);
91
+ if (!frontMatterMatch) return;
92
+
93
+ const frontMatterYaml = frontMatterMatch[1];
94
+ const frontMatterStartLine = 2;
95
+
96
+ let sourceMap: any;
97
+ let document: any;
98
+ try {
99
+ sourceMap = new YAMLSourceMap();
100
+ document = sourceMap.index(
101
+ yamlLib.parseDocument(frontMatterYaml, {
102
+ keepCstNodes: true,
103
+ }),
104
+ );
105
+ } catch {
106
+ validateSchema.errors.forEach((error) => {
107
+ const errorMessage: VFileMessage = new VMessage(
108
+ error.message || 'Invalid liquid frontmatter.',
109
+ { line: frontMatterStartLine, column: 1 },
110
+ SOURCE,
111
+ );
112
+ errorMessage.fatal = true;
113
+ file.messages.push(errorMessage);
114
+ });
115
+ return;
116
+ }
117
+
118
+ validateSchema.errors.forEach((error) => {
119
+ const schemaPath = (error.dataPath || error.instancePath || '')
120
+ .split('/')
121
+ .filter((e) => String(e).trim());
122
+ const fileCounter = sourceMap.lookup(schemaPath, document);
123
+ const line =
124
+ fileCounter && fileCounter.start
125
+ ? fileCounter.start.line + frontMatterStartLine - 1
126
+ : frontMatterStartLine;
127
+ const column =
128
+ fileCounter && fileCounter.start
129
+ ? fileCounter.start.col
130
+ : 1;
131
+
132
+ const errorMessage: VFileMessage = new VMessage(
133
+ error.message || 'Invalid liquid frontmatter.',
134
+ { line, column },
135
+ SOURCE,
136
+ );
137
+ errorMessage.fatal = true;
138
+ file.messages.push(errorMessage);
139
+ });
140
+ }
141
+ return;
142
+ }
143
+
144
+ const liquid = frontMatterData.liquid as Record<string, unknown>;
145
+ if (liquid && typeof liquid === 'object' && typeof liquid.data === 'string') {
146
+ checkDataFile(file, liquid.data);
147
+ }
148
+ }
149
+
150
+ export = rule(SOURCE, checkLiquidFrontmatter);
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.settings.json",
3
+ "moduleResolution": "node",
4
+ "compilerOptions": {
5
+ "rootDir": "src",
6
+ "outDir": "dist"
7
+ }
8
+ }
@@ -0,0 +1 @@
1
+ {"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/gray-matter/gray-matter.d.ts","../../node_modules/@types/js-yaml/index.d.ts","../../node_modules/ajv/dist/compile/codegen/code.d.ts","../../node_modules/ajv/dist/compile/codegen/scope.d.ts","../../node_modules/ajv/dist/compile/codegen/index.d.ts","../../node_modules/ajv/dist/compile/rules.d.ts","../../node_modules/ajv/dist/compile/subschema.d.ts","../../node_modules/ajv/dist/compile/context.d.ts","../../node_modules/ajv/dist/compile/validate/datatype.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalitems.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/contains.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/dependencies.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/propertynames.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/additionalproperties.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/not.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/anyof.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/oneof.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/if.d.ts","../../node_modules/ajv/dist/vocabularies/applicator/index.d.ts","../../node_modules/ajv/dist/vocabularies/validation/limitnumber.d.ts","../../node_modules/ajv/dist/vocabularies/validation/multipleof.d.ts","../../node_modules/ajv/dist/vocabularies/validation/pattern.d.ts","../../node_modules/ajv/dist/vocabularies/validation/required.d.ts","../../node_modules/ajv/dist/vocabularies/validation/uniqueitems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/const.d.ts","../../node_modules/ajv/dist/vocabularies/validation/enum.d.ts","../../node_modules/ajv/dist/vocabularies/validation/index.d.ts","../../node_modules/ajv/dist/vocabularies/format/format.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedproperties.d.ts","../../node_modules/ajv/dist/vocabularies/unevaluated/unevaluateditems.d.ts","../../node_modules/ajv/dist/vocabularies/validation/dependentrequired.d.ts","../../node_modules/ajv/dist/vocabularies/errors.d.ts","../../node_modules/ajv/dist/types/json-schema.d.ts","../../node_modules/ajv/dist/types/jtd-schema.d.ts","../../node_modules/ajv/dist/compile/error_classes.d.ts","../../node_modules/ajv/dist/core.d.ts","../../node_modules/uri-js/dist/es5/uri.all.d.ts","../../node_modules/ajv/dist/compile/resolve.d.ts","../../node_modules/ajv/dist/compile/index.d.ts","../../node_modules/ajv/dist/types/index.d.ts","../../node_modules/ajv/dist/ajv.d.ts","../../node_modules/ajv-errors/dist/index.d.ts","../../node_modules/yaml/types.d.ts","../../node_modules/yaml/util.d.ts","../../node_modules/yaml/parse-cst.d.ts","../../node_modules/yaml/index.d.ts","../../node_modules/@types/unist/index.d.ts","../../node_modules/vfile-message/types/index.d.ts","../../node_modules/vfile/types/index.d.ts","./src/index.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostic_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/util/types.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/globals.global.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/ts3.6/base.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/base.d.ts","./node_modules/@types/node/index.d.ts","../../node_modules/@babel/types/lib/index.d.ts","../../node_modules/@types/babel__generator/index.d.ts","../../node_modules/@babel/parser/typings/babel-parser.d.ts","../../node_modules/@types/babel__template/index.d.ts","../../node_modules/@types/babel__traverse/index.d.ts","../../node_modules/@types/babel__core/index.d.ts","../../node_modules/keyv/src/index.d.ts","../../node_modules/@types/http-cache-semantics/index.d.ts","../../node_modules/@types/responselike/index.d.ts","../../node_modules/@types/cacheable-request/index.d.ts","../../node_modules/@types/dedent/index.d.ts","../../node_modules/@types/graceful-fs/index.d.ts","../../node_modules/@types/istanbul-lib-coverage/index.d.ts","../../node_modules/@types/istanbul-lib-report/index.d.ts","../../node_modules/@types/istanbul-reports/index.d.ts","../../node_modules/@types/jest/node_modules/jest-diff/build/cleanupsemantic.d.ts","../../node_modules/@types/jest/node_modules/jest-diff/build/types.d.ts","../../node_modules/@types/jest/node_modules/jest-diff/build/difflines.d.ts","../../node_modules/@types/jest/node_modules/jest-diff/build/printdiffs.d.ts","../../node_modules/@types/jest/node_modules/jest-diff/build/index.d.ts","../../node_modules/@types/jest/node_modules/pretty-format/build/types.d.ts","../../node_modules/@types/jest/node_modules/pretty-format/build/index.d.ts","../../node_modules/@types/jest/index.d.ts","../../node_modules/@types/jest/ts3.2/index.d.ts","../../node_modules/@types/json-schema/index.d.ts","../../node_modules/@types/jsonpath-plus/index.d.ts","../../node_modules/@types/keyv/index.d.ts","../../node_modules/@types/mdast/index.d.ts","../../node_modules/@types/minimatch/index.d.ts","../../node_modules/@types/minimist/index.d.ts","../../node_modules/@types/mock-fs/lib/item.d.ts","../../node_modules/@types/mock-fs/lib/file.d.ts","../../node_modules/@types/mock-fs/lib/directory.d.ts","../../node_modules/@types/mock-fs/lib/symlink.d.ts","../../node_modules/@types/mock-fs/lib/filesystem.d.ts","../../node_modules/@types/mock-fs/index.d.ts","../../node_modules/@types/normalize-package-data/index.d.ts","../../node_modules/@types/prettier/index.d.ts","../../node_modules/@types/stack-utils/index.d.ts","../../node_modules/@types/yargs-parser/index.d.ts","../../node_modules/@types/yargs/index.d.ts"],"fileInfos":[{"version":"8730f4bf322026ff5229336391a18bcaa1f94d4f82416c8b2f3954e2ccaae2ba","affectsGlobalScope":true},"dc47c4fa66b9b9890cf076304de2a9c5201e94b740cffdf09f87296d877d71f6","7a387c58583dfca701b6c85e0adaf43fb17d590fb16d5b2dc0a2fbd89f35c467","8a12173c586e95f4433e0c6dc446bc88346be73ffe9ca6eec7aa63c8f3dca7f9","5f4e733ced4e129482ae2186aae29fde948ab7182844c3a5a51dd346182c7b06","4b421cbfb3a38a27c279dec1e9112c3d1da296f77a1a85ddadf7e7a425d45d18",{"version":"adb996790133eb33b33aadb9c09f15c2c575e71fb57a62de8bf74dbf59ec7dfb","affectsGlobalScope":true},{"version":"8cc8c5a3bac513368b0157f3d8b31cfdcfe78b56d3724f30f80ed9715e404af8","affectsGlobalScope":true},{"version":"cdccba9a388c2ee3fd6ad4018c640a471a6c060e96f1232062223063b0a5ac6a","affectsGlobalScope":true},{"version":"c5c05907c02476e4bde6b7e76a79ffcd948aedd14b6a8f56e4674221b0417398","affectsGlobalScope":true},{"version":"5f406584aef28a331c36523df688ca3650288d14f39c5d2e555c95f0d2ff8f6f","affectsGlobalScope":true},{"version":"22f230e544b35349cfb3bd9110b6ef37b41c6d6c43c3314a31bd0d9652fcec72","affectsGlobalScope":true},{"version":"7ea0b55f6b315cf9ac2ad622b0a7813315bb6e97bf4bb3fbf8f8affbca7dc695","affectsGlobalScope":true},{"version":"3013574108c36fd3aaca79764002b3717da09725a36a6fc02eac386593110f93","affectsGlobalScope":true},{"version":"eb26de841c52236d8222f87e9e6a235332e0788af8c87a71e9e210314300410a","affectsGlobalScope":true},{"version":"3be5a1453daa63e031d266bf342f3943603873d890ab8b9ada95e22389389006","affectsGlobalScope":true},{"version":"17bb1fc99591b00515502d264fa55dc8370c45c5298f4a5c2083557dccba5a2a","affectsGlobalScope":true},{"version":"7ce9f0bde3307ca1f944119f6365f2d776d281a393b576a18a2f2893a2d75c98","affectsGlobalScope":true},{"version":"6a6b173e739a6a99629a8594bfb294cc7329bfb7b227f12e1f7c11bc163b8577","affectsGlobalScope":true},{"version":"81cac4cbc92c0c839c70f8ffb94eb61e2d32dc1c3cf6d95844ca099463cf37ea","affectsGlobalScope":true},{"version":"b0124885ef82641903d232172577f2ceb5d3e60aed4da1153bab4221e1f6dd4e","affectsGlobalScope":true},{"version":"0eb85d6c590b0d577919a79e0084fa1744c1beba6fd0d4e951432fa1ede5510a","affectsGlobalScope":true},{"version":"da233fc1c8a377ba9e0bed690a73c290d843c2c3d23a7bd7ec5cd3d7d73ba1e0","affectsGlobalScope":true},{"version":"d154ea5bb7f7f9001ed9153e876b2d5b8f5c2bb9ec02b3ae0d239ec769f1f2ae","affectsGlobalScope":true},{"version":"bb2d3fb05a1d2ffbca947cc7cbc95d23e1d053d6595391bd325deb265a18d36c","affectsGlobalScope":true},{"version":"c80df75850fea5caa2afe43b9949338ce4e2de086f91713e9af1a06f973872b8","affectsGlobalScope":true},{"version":"9d57b2b5d15838ed094aa9ff1299eecef40b190722eb619bac4616657a05f951","affectsGlobalScope":true},{"version":"6c51b5dd26a2c31dbf37f00cfc32b2aa6a92e19c995aefb5b97a3a64f1ac99de","affectsGlobalScope":true},{"version":"6e7997ef61de3132e4d4b2250e75343f487903ddf5370e7ce33cf1b9db9a63ed","affectsGlobalScope":true},{"version":"2ad234885a4240522efccd77de6c7d99eecf9b4de0914adb9a35c0c22433f993","affectsGlobalScope":true},{"version":"5e5e095c4470c8bab227dbbc61374878ecead104c74ab9960d3adcccfee23205","affectsGlobalScope":true},{"version":"09aa50414b80c023553090e2f53827f007a301bc34b0495bfb2c3c08ab9ad1eb","affectsGlobalScope":true},{"version":"2768ef564cfc0689a1b76106c421a2909bdff0acbe87da010785adab80efdd5c","affectsGlobalScope":true},{"version":"52d1bb7ab7a3306fd0375c8bff560feed26ed676a5b0457fa8027b563aecb9a4","affectsGlobalScope":true},"a52c5f687d788d283ea1fa38bdc2fabe0eac863135a7dfe175ec52b309f61892","7a1dd1e9c8bf5e23129495b10718b280340c7500570e0cfe5cffcdee51e13e48","2274b0f0e4f20a1af3309985337bd8a7f45610145db3c37485ea8697c0778eda","60bb0e47502bf8716d1230288b4e6387c1d34cded12752ab5338108e2e662e67","b250a278297e209148e3ee53c5f27b773a351618b0a0c5b8fe0397d2fbd08576","b3ae4ded82f27cabba780b9af9647f6e08c9a4cabe8fbb7a0cca69c7add9ef4b","b57d661f8123e266307b11fbf08ec29363f84f482622f99e42cf3fdf94059255","726416fd6b5f6d16c91fe5f2dee9ac722bceddd8f8e5d0fc9c3399c7c2efd9b1","1a23b521db8d7ec9e2b96c6fbd4c7e96d12f408b1e03661b3b9f7da7291103e6","1c68c3020dfada02f9e9671c7c13fb7adea15118f3acc2d21f02a7b3c632482c","ae0951e44973e928fe2e999b11960493835d094b16adac0b085a79cff181bcb9","9e8575c515e21e1b51ab7eb78cfd763ec857cfd7b4f985a4f394f9ea8c0ac36d","1609ad4d488c356ee91eba7d7aa87cc6fb59bc8ac05c1a8f08665285ba3b71ad","8add088f72326098d68d622ddb024c00ae56a912383efe96b03f0481db88f7c9","dd17fe6332567b8f13e33dd3ff8926553cdcea2ad32d4350ce0063a2addaa764","4091d56a4622480549350b8811ec64c7826cd41a70ce5d9c1cc20384bb144049","353c0125b9e50c2a71e18394d46be5ccb37161cc0f0e7c69216aa6932c8cdafb","9c5d5f167e86b6ddf7142559a17d13fd39c34e868ae947c40381db866eed6609","6539823527c9349664b239204197757434e287e9ef7c2c29afaad10a79f3348a","aae698ceead4edad0695b9ea87e43f274e698bdb302c8cb5fd2cab4dc496ccf0","51631e9a0c041e12479ab01f5801d8a237327d19e9ee37d5f1f66be912631425","c9d5d8adb1455f49182751ce885745dcc5f9697e9c260388bc3ae9d1860d5d10","f64289e3fa8d5719eaf5ba1bb02dd32dbbf7c603dda75c16770a6bc6e9c6b6d9","b1aa0e2e3511a8d10990f35866405c64c9e576258ef99eeb9ebafed980fd7506","2d255a5287f2fb5295688cb25bd18e1cd59866179f795f3f1fd6b71b7f0edf8f","43c1dbb78d5277a5fdd8fddce8b257f84ffa2b4253f58b95c04a310710d19e97","6c669d7e080344c1574aa276a89e57c3b9f0e97fab96a09427e7dfb19ca261bf","b71ac126853867d8e64c910f47d46d05c5ea797987d2604f63d401507dc43b6d","9a37238558d28b7ee06d08599e92eab30b90704541cc85e6448009d6d55fffa9","120b14d66a061910309ff97e7b06b5c6c09444218178b80b687a92af4d22d5dc","3de958065e3a44cbe0bfa667813bc59c63e63c9ce522af8dc1b64714910fa9ba","4dbd5a4e8c71e60af9af1d38d1ac5f6eedef3591afb556ed164f169061706f15","5db5754073f92ef99fef159a3415a733db507af67126b287daa51553cb9107d2","ac162509239b1a48ab6aa39a3fc34dd7d8cde209c59188f699b3ef78964165e0","44fa175d725f678ed47ee3cbaf2fcdf688559e672352ac24c721dd9ceef7d7c1","9556b6427e049169448398e1e59fb393e4de91852abda84dd569d0e7b038e641","9f3c5498245c38c9016a369795ec5ef1768d09db63643c8dba9656e5ab294825","8f35095ce6914b0e95d563adae6f2546dddd8f85c4034d9050530076d860b5b8","893edbff0dcaf7c4ef650c24cfcf87e6ad63d3e0457f7524d5706f8599e7bac3","06f6c325a4cec7589a46fb8c335b4da840b125bf20d514411fead13478b008b9","a3b6fafae3db815903c6ee13b8c77a43a89fba98fabf263a254f015b388cf190","320c48aadd4ca9697fc3017cf5ef768c880792ff12369bd6ee2ad771b394d6ac","c3a8e97bce8330542633139409885c529c46ff9bcf8fda0dc28a7c8fdda41e24","4d99772cffbb09646a934867ca42d77337dc3cfd591b648b78fc0b6e09e2d88d","b10413a27f0fa373997ebf631da8af501d6b36bdfe627475b3ec5ef98e9bc80d","b3280c01b5c948bb27e60a94076b4ed23e34db4044d687ef628a5831c09c9811","6d09838b65c3c780513878793fc394ae29b8595d9e4729246d14ce69abc71140","eb09cf44043f7d6e0208dca6f0555207015e91fff5ff77b9c21d63672f7d68d5","bbf6f246061b92bb84241897eebfcdb9ce28444ab6acbc32c425388dd27c1011",{"version":"fde90111c3efcdf14e2554a45c762fe5eee8eb06f80857428d8aee58ea5b7f7f","signature":"5e9d9d2e7b23697c2870a91d308db582f4cf6c6f6113cec425f7ff190a24f120"},"c7bdc99177a2a94d25fb13722adaaf5b3291bf70b4d1b27584ba189dd3889ba3",{"version":"d1c92b66c4105659fcad4eb76a1481f7311033e117d0678a1ec545e8ddb8d4c6","affectsGlobalScope":true},"e23424b97418eca3226fd24de079f1203eb70360622e4e093af2aff14d4be6ec","dee93c07b4df5e26010dc9ec4cdf4d6e4076bb4474d2a8371529217c8b2740a4","ed40f2f184db052dc8df62d1f199823c8bbccc487c0a2a7c54eeea0badcf4378","04eaa93bd75f937f9184dcb95a7983800c5770cf8ddd8ac0f3734dc02f5b20ef",{"version":"c8155caf28fc7b0a564156a5df28ad8a844a3bd32d331d148d8f3ce88025c870","affectsGlobalScope":true},"45ac321f2e15d268fd74a90ddaa6467dcaaff2c5b13f95b4b85831520fb7a491","dfc747ab8dd5f623055a4c26fd35e8cceca869fd3f1cf09701c941ca3679665a","c9f5f2920ff61d7158417b8440d5181ddc34a3dfef811a5677dd8a9fb91471e9","5cc0a492da3602510b8f5ed1852b1e0390002780d8758fbc8c0cd023ca7085f8","ec7dafafe751a5121f8f1c80201ebe7e7238c47e6329280a73c4d1ca4bb7fa28","64debeb10e4b7ae4ec9e89bfb4e04c6101ab98c3cc806d14e5488607cfec2753",{"version":"2866a528b2708aa272ec3eaafd3c980abb23aec1ef831cfc5eb2186b98c37ce5","affectsGlobalScope":true},{"version":"a5782d6cea81fe43d2db7ed41e789458c933ab3ab60602f7b5b14c4da3370496","affectsGlobalScope":true},"f258ba66915f0196ec344bc53afe1888240bbcc855ebd151b6cc072275533319","6194335ee3353f7226ba31f31d6301d0c6be87228419c0a08976ccd9d4f1213e","3ac12a54cfaa84683506db8d4cf779135a271d9f0ec18930cf53e61fbeea0c5d","cf3d3b087d1a8a3355eec47d206162c75e912315b9b5c1cd49fda93e948fb80a","36f316c066c4a72dd6f19fec49a074f935744fc9ccbe75c87ebc07fb2feb9062","42176966283d3835c34278b9b5c0f470d484c0c0c6a55c20a2c916a1ce69b6e8","0cff7901aedfe78e314f7d44088f07e2afa1b6e4f0473a4169b8456ca2fb245d","ec70fd6f8a9a83f850dab2960a6789e93d5b034b354a16814cad5daabf62a360","e2236264a811ed1d09a2487a433e8f5216ae62378cf233954ae220cf886f6717","3ec1e108d587a5661ec790db607f482605ba9f3830e118ce578e3ffa3c42e22b","100b3bb9d39d2b1b5340f1bf45a52e94ef1692b45232b4ba00fac5c3cc56d331",{"version":"04fe7e7d8008887943260af1fde2bfd4877e0dc57bf634e0f0b2f3d1794dfd11","affectsGlobalScope":true},"7f77304372efe3c9967e5f9ea2061f1b4bf41dc3cda3c83cdd676f2e5af6b7e6","992c6f6be16c0a1d2eec13ece33adeea2c747ba27fcd078353a8f4bb5b4fea58","2597718d91e306949d89e285bf34c44192014ef541c3bd7cbb825c022749e974","a6b0abdb67d63ebe964ba5fee31bc3daf10c12eecd46b24d778426010c04c67e","ac4801ebc2355ba32329070123b1cd15891bf71b41dcaf9e75b4744832126a59","fd2298fba0640e7295e7bd545e2dfbfcccbb00c27019e501c87965a02bbdebf6","4fd3c4debadce3e9ab9dec3eb45f7f5e2e3d4ad65cf975a6d938d883cfb25a50","71ddd49185b68f27bfac127ef5d22cb2672c278e53e5370d9020ef50ca9c377d","b1ea7a6eaa7608e0e0529aebd323b526a79c6c05a4e519ae5c779675004dcdf1","9fcb033a6208485d8f3fadde31eb5cbcaf99149cff3e40c0dc53ebc6d0dff4e9","7df562288f949945cf69c21cd912100c2afedeeb7cdb219085f7f4b46cb7dde4","9d16690485ff1eb4f6fc57aebe237728fd8e03130c460919da3a35f4d9bd97f5","dcc6910d95a3625fd2b0487fda055988e46ab46c357a1b3618c27b4a8dd739c9","f4149f1aa299474c7040a35fe8f8ac2ad078cc1b190415adc1fff3ed52d490ea","3730099ed008776216268a97771de31753ef71e0a7d0ec650f588cba2a06ce44","8d649dbc429d7139a1d9a14ea2bf8af1dc089e0a879447539587463d4b6c248c","60c9e27816ec8ac8df7240598bb086e95b47edfb454c5cbf4003c812e0ed6e39","e361aecf17fc4034b4c122a1564471cdcd22ef3a51407803cb5a5fc020c04d02","4926467de88a92a4fc9971d8c6f21b91eca1c0e7fc2a46cc4638ab9440c73875",{"version":"2708349d5a11a5c2e5f3a0765259ebe7ee00cdcc8161cb9990cb4910328442a1","affectsGlobalScope":true},"fc0ae4a8ad3c762b96f9d2c3700cb879a373458cb0bf3175478e3b4f85f7ef2f","fabbec378e1ddd86fcf2662e716c2b8318acedb664ee3a4cba6f9e8ee8269cf1","b3593bd345ebea5e4d0a894c03251a3774b34df3d6db57075c18e089a599ba76","e61a21e9418f279bc480394a94d1581b2dee73747adcbdef999b6737e34d721b","efd55e8ca79171bf26c0d0e30221cb8ee1f5a31dd0c791ec4b2e886f42bab124","c2c2a861a338244d7dd700d0c52a78916b4bb75b98fc8ca5e7c501899fc03796","b6d03c9cfe2cf0ba4c673c209fcd7c46c815b2619fd2aad59fc4229aaef2ed43","adb467429462e3891de5bb4a82a4189b92005d61c7f9367c089baf03997c104e","670a76db379b27c8ff42f1ba927828a22862e2ab0b0908e38b671f0e912cc5ed","13b77ab19ef7aadd86a1e54f2f08ea23a6d74e102909e3c00d31f231ed040f62","069bebfee29864e3955378107e243508b163e77ab10de6a5ee03ae06939f0bb9","42baf4ca38c38deaf411ea73f37bc39ff56c6e5c761a968b64ac1b25c92b5cd8","d7dbe0ad36bdca8a6ecf143422a48e72cc8927bab7b23a1a2485c2f78a7022c6","8718fa41d7cf4aa91de4e8f164c90f88e0bf343aa92a1b9b725a9c675c64e16b","f992cd6cc0bcbaa4e6c810468c90f2d8595f8c6c3cf050c806397d3de8585562","3189093b3543e545bcf0e6d387d60c5cfe5a224b104d15b1639c0c4db9ecf012","afe73051ff6a03a9565cbd8ebb0e956ee3df5e913ad5c1ded64218aabfa3dcb5","035a5df183489c2e22f3cf59fc1ed2b043d27f357eecc0eb8d8e840059d44245","a4809f4d92317535e6b22b01019437030077a76fec1d93b9881c9ed4738fcc54","5f53fa0bd22096d2a78533f94e02c899143b8f0f9891a46965294ee8b91a9434","e222104af6cb9415238ad358488b74d76eceeff238c1268ec6e85655b05341da","69da61a7b5093dac77fa3bec8be95dcf9a74c95a0e9161edb98bb24e30e439d2","eba230221317c985ab1953ccc3edc517f248b37db4fef7875cb2c8d08aff7be7","b83e796810e475da3564c6515bc0ae9577070596a33d89299b7d99f94ecfd921","b4439890c168d646357928431100daac5cbdee1d345a34e6bf6eca9f3abe22bc","5d72971a459517c44c1379dab9ed248e87a61ba0a1e0f25c9d67e1e640cd9a09","02d734976af36f4273d930bea88b3e62adf6b078cf120c1c63d49aa8d8427c5c",{"version":"f624e578325b8c58e55b30c998b1f4c3ec1b61a9fa66373da4250c89b7880d44","affectsGlobalScope":true},{"version":"d3002f620eab4bf6476c9da5c0efb2041d46f7df8b3032a5631bd206abef2c75","affectsGlobalScope":true},"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","9bd81cfc874a2d896326e6d9e7a6963677389a8269b1d032663083b253e21162","fec943fdb3275eb6e006b35e04a8e2e99e9adf3f4b969ddf15315ac7575a93e4","202f8582ee3cd89e06c4a17d8aabb925ff8550370559c771d1cc3ec3934071c2","8841e2aa774b89bd23302dede20663306dc1b9902431ac64b24be8b8d0e3f649","fbca5ffaebf282ec3cdac47b0d1d4a138a8b0bb32105251a38acb235087d3318","b95f2a78de34a873c6dd76dc538b7a5fec77da6a0e0e7efc7aa58f58ddfce270","4b50f58fcf29daaeab0c583da58ee9731a4d5c003f99fd833d91ad99f19a82c3","6692416887d66b903aea54b32163d34318300772cd2b8c7c36f972937a62de74","3e640a0056177a4ccfb819d81b21c9ed0ac0e77d8b7bf580894a3392298a890b","b75cb207f8dfade4120ba3554c5781005c9de85723c76588befd47693342ca50","693c4c9acf5e1c56e30130a90e07bd05122e6194d69018b0b20c6581c1324e0a","22293bd6fa12747929f8dfca3ec1684a3fe08638aa18023dd286ab337e88a592","d88a5e779faf033be3d52142a04fbe1cb96009868e3bbdd296b2bc6c59e06c0e","ab82804a14454734010dcdcd43f564ff7b0389bee4c5692eec76ff5b30d4cf66","bae8d023ef6b23df7da26f51cea44321f95817c190342a36882e93b80d07a960","ae271d475b632ce7b03fea6d9cf6da72439e57a109672671cbc79f54e1386938"],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"experimentalDecorators":true,"module":1,"noUnusedLocals":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":false,"target":6},"fileIdsList":[[137],[137,138,139,140,141],[137,139],[99,102,124,136,143,144,145],[100,136],[149],[150],[156,158],[152,153],[152,153,154,155],[157],[159],[99,136],[81],[168,169,170,171],[167],[136,167],[167,168,169,170],[102,116,136],[176],[75],[39,40,42,66,67,70,73,74],[37,38],[37],[39,40,41,73,74],[74],[39,40,70,72,74],[71,74,75],[39,40,73,74],[39,40,42,66,67,68,69,73,74],[39,40,42,70,73],[42,74],[44,45,46,47,48,49,50,51,52,74],[43,53,61,62,63,64,65],[46,74],[54,55,56,57,58,59,60,74],[99],[81,82],[77,78,79],[78],[78,79,80],[77,79,80],[134],[133,134],[88,93],[99,100,107,116],[89,99,107],[125],[93,100,108],[116,121],[96,99,107],[97],[96],[99,101,116,124],[99,100,116],[107,116,124],[99,100,102,107,116,121,124],[102,116,121,124],[135],[124],[96,99,116],[109],[87],[123],[114,125,128],[99,117],[116],[119],[93,107],[85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132],[107],[113],[126],[88,93,99,101,110,116,124,128],[35,36,75,76,80,82,83,100,109]],"referencedMap":[[139,1],[142,2],[138,1],[140,3],[141,1],[146,4],[148,5],[150,6],[151,7],[159,8],[154,9],[156,10],[155,9],[158,11],[160,12],[163,13],[164,14],[172,15],[169,16],[168,17],[171,18],[170,16],[145,19],[177,20],[76,21],[75,22],[39,23],[38,24],[42,25],[69,26],[73,27],[72,28],[40,26],[41,29],[43,29],[70,30],[74,31],[44,26],[48,26],[50,26],[45,26],[46,32],[52,26],[53,33],[49,26],[51,26],[47,26],[66,34],[62,26],[64,26],[63,26],[59,26],[65,35],[60,26],[61,36],[54,26],[55,26],[56,26],[57,26],[58,26],[143,37],[82,14],[83,38],[80,39],[79,40],[77,41],[78,42],[85,43],[135,44],[88,45],[89,46],[90,47],[91,48],[92,49],[93,50],[94,51],[96,52],[97,53],[98,37],[99,37],[100,54],[101,55],[102,56],[103,57],[104,58],[136,59],[105,37],[106,60],[107,61],[109,62],[110,63],[111,64],[114,37],[115,65],[116,66],[117,67],[119,37],[120,68],[121,69],[133,70],[123,71],[124,72],[125,73],[127,67],[129,74],[130,67],[84,75]],"exportedModulesMap":[[139,1],[142,2],[138,1],[140,3],[141,1],[146,4],[148,5],[150,6],[151,7],[159,8],[154,9],[156,10],[155,9],[158,11],[160,12],[163,13],[164,14],[172,15],[169,16],[168,17],[171,18],[170,16],[145,19],[177,20],[76,21],[75,22],[39,23],[38,24],[42,25],[69,26],[73,27],[72,28],[40,26],[41,29],[43,29],[70,30],[74,31],[44,26],[48,26],[50,26],[45,26],[46,32],[52,26],[53,33],[49,26],[51,26],[47,26],[66,34],[62,26],[64,26],[63,26],[59,26],[65,35],[60,26],[61,36],[54,26],[55,26],[56,26],[57,26],[58,26],[143,37],[82,14],[83,38],[80,39],[79,40],[77,41],[78,42],[85,43],[135,44],[88,45],[89,46],[90,47],[91,48],[92,49],[93,50],[94,51],[96,52],[97,53],[98,37],[99,37],[100,54],[101,55],[102,56],[103,57],[104,58],[136,59],[105,37],[106,60],[107,61],[109,62],[110,63],[111,64],[114,37],[115,65],[116,66],[117,67],[119,37],[120,68],[121,69],[133,70],[123,71],[124,72],[125,73],[127,67],[129,74],[130,67]],"semanticDiagnosticsPerFile":[139,137,142,138,140,141,146,147,148,144,149,150,151,159,152,154,156,155,153,158,157,160,36,161,162,163,164,165,166,172,169,168,171,167,170,173,174,145,175,81,176,177,76,75,37,39,38,42,69,73,72,40,41,43,70,74,67,68,44,48,50,45,46,52,53,49,51,47,66,62,64,63,59,65,60,61,54,55,56,57,58,35,143,8,7,2,9,10,11,12,13,14,15,16,3,4,20,17,18,19,21,22,23,5,24,25,26,27,6,31,28,29,30,32,33,1,34,71,82,83,80,79,77,78,134,85,87,135,88,89,90,91,92,93,94,95,96,97,98,99,100,101,86,131,102,103,104,136,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,133,123,124,125,126,127,128,132,129,130,84],"latestChangedDtsFile":"./dist/index.d.ts"},"version":"4.9.5"}