pickle-jar 1.0.0

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/.eslintignore ADDED
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ dist
3
+ coverage
4
+ src/grammar
package/.eslintrc ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "root": true,
3
+ "parser": "@typescript-eslint/parser",
4
+ "plugins": [
5
+ "@typescript-eslint"
6
+ ],
7
+ "extends": [
8
+ "eslint:recommended",
9
+ "plugin:@typescript-eslint/eslint-recommended",
10
+ "plugin:@typescript-eslint/recommended"
11
+ ]
12
+ }
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/pickle-jar.iml" filepath="$PROJECT_DIR$/.idea/pickle-jar.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$">
5
+ <excludeFolder url="file://$MODULE_DIR$/.tmp" />
6
+ <excludeFolder url="file://$MODULE_DIR$/temp" />
7
+ <excludeFolder url="file://$MODULE_DIR$/tmp" />
8
+ </content>
9
+ <orderEntry type="inheritedJdk" />
10
+ <orderEntry type="sourceFolder" forTests="false" />
11
+ </component>
12
+ </module>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Sebastian Negomireanu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Makefile ADDED
@@ -0,0 +1,43 @@
1
+ .DEFAULT_GOAL := rebuild
2
+ .PHONY: all build rebuild watch clean test test-prod test-watch lint start doc
3
+
4
+ build:
5
+ npx tsc
6
+ npx cpx "src/**/*{.jsx?, .css}" "dist/"
7
+
8
+ rebuild:
9
+ $(MAKE) clean
10
+ $(MAKE) build
11
+
12
+ watch:
13
+ $(MAKE) build
14
+ (trap 'kill 0' SIGINT; npx tsc-watch & npx cpx "src/**/*{.jsx?, .css}" "dist/" --watch)
15
+
16
+ start:
17
+ $(MAKE) build
18
+ (trap 'kill 0' SIGINT; npx tsc-watch & npx cpx "src/**/*{.jsx?,.css}" "dist/" --watch & nodemon -r dotenv/config dist/bin/index.js)
19
+
20
+ clean:
21
+ rm -rfv ./dist
22
+ rm -vf *.tsbuildinfo
23
+
24
+ test:
25
+ npx jest
26
+
27
+ test-prod:
28
+ npx jest --coverage --no-cache
29
+
30
+ test-watch:
31
+ npx jest --watch
32
+
33
+ lint:
34
+ npx eslint '*/**/*.{js,ts,tsx}' --fix
35
+
36
+ grammar:
37
+ . ./grammar.sh
38
+
39
+ all:
40
+ $(MAKE) clean
41
+ $(MAKE) build
42
+ $(MAKE) lint
43
+ $(MAKE) test
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # pickle-jar
2
+ Framework for writing Gherkin features and running them using Jest
3
+
4
+ # Overview
5
+ pickle-jar is an alternative to jest-cucumber and and Cucumber.js that runs on top of jest. `pickle-jar`
6
+ allows defining test scnearios using Gherkin language and translates them into define/it blocks that run using jest.
7
+ Compared to jest-cucumber, the output is more explicit and all steps are reperesented by jest describe blocks.
8
+
9
+ The framework allows defining steps using regular expression matchers. Match groups are automatically passed as parameters
10
+ to the step function.
11
+
12
+ # Why pickle-jar?
13
+ jest-cucumber is a good framework, but it has several limitations:
14
+ * the test steps are not clearly represented (only the scenario)
15
+ * scenario descriptions are not clear, making it hard to figure out the set of parameters that leads to a scenario failure
16
+
17
+ # Getting started
18
+ ## Install pickle-jar:
19
+ ```shell
20
+ npm install pickle-jar --dev
21
+ ```
22
+ The project dependencies must be explicitly installed (they are defined as peer dependencies):
23
+ ```shell
24
+ npm install antlr4 antlr4ts glob --dev
25
+ ```
26
+ ## Create a first feature file
27
+ Create a folder named `<rootDir>/test/features`. This folder will be the base folder for all feature files.
28
+ To keep things tidy, feature files can be also grouped in subfolders.
29
+
30
+ Define a first feature file, called `MyFeature.feature` inside the `<rootDir>/test/features` directory:
31
+ ```gherkin
32
+ Feature: Logging in
33
+
34
+ Scenario: Entering a correct password
35
+ Given I have previously created a password
36
+ When I enter my password correctly
37
+ Then I should be granted access
38
+ ```
39
+
40
+ In order to run the features and their steps, a test runner entry point must be defined:
41
+ ## The test runner entry point
42
+ Create a file named `runner.ts` in the `<rootDir>/test` directory:
43
+
44
+ ```ts
45
+ import {workerData} from "worker_threads";
46
+ import {StepDefinition, testRunner} from "../src";
47
+
48
+ interface World {
49
+ password: string | undefined;
50
+ grantedAccess: boolean;
51
+ }
52
+
53
+ const stepDefinitions: StepDefinition<World>[] = [{
54
+ match: /^Given I have previously created a password$/, step: (world) => {
55
+ world.password = "my password";
56
+ }
57
+ }, {
58
+ match: /^When I enter my password correctly$/, step: (world) => {
59
+ world.grantedAccess = world.password === 'my password';
60
+ }
61
+ }, {
62
+ match: /^I should be granted access$/, step: (world) => {
63
+ expect(world.grantedAccess).toBeTruthy();
64
+ }
65
+ }];
66
+
67
+ const world: World = {
68
+ password: undefined,
69
+ grantedAccess: false
70
+ }
71
+ testRunner<World>(`${__dirname}/features/**/*.feature`, stepDefinitions, world);
72
+ ```
73
+
74
+ The test runner file defines the World object structure. This object is passed to each step and allows sharing values from one step to another.
75
+
76
+ ## Step definitions
77
+ Steps from the feature file are matched using regular expressions. The test runner receives an array of steps.
78
+ Each step has a regular expression and a callback:
79
+ ```ts
80
+ {
81
+ match: /^Given I have previously created a password$/,
82
+ step: (world) => {
83
+ world.password = "my password";
84
+ }
85
+ }
86
+ ```
87
+ The test runner checks the step using the regular expressions. If zero or more than one regular expression
88
+ match the feature step, an error will be thrown. Any regular expression capture groups or doc string in the step definition
89
+ will be passed to the step callback as parameters.
90
+
91
+ For example, the feature and steps define above can be rewritten in a more general way:
92
+
93
+
94
+ ### `MyFeature.feature`:
95
+ ```gherkin
96
+ Feature: Logging in
97
+ Scenario: Test passwords with parameters
98
+ Given I have previously created the 'my password' password
99
+ When I enter correctly the password
100
+ """
101
+ my password
102
+ """
103
+ Then I should be granted access
104
+ ```
105
+ ### `runner.ts` steps:
106
+ ```ts
107
+ import {workerData} from "worker_threads";
108
+ import {StepDefinition, testRunner} from "../src";
109
+
110
+ interface World {
111
+ password: string | undefined;
112
+ grantedAccess: boolean;
113
+ }
114
+
115
+ const stepDefinitions: StepDefinition<World>[] = [{
116
+ match: /^Given I have previously the '([^']+)' password$/, step: (world, password) => {
117
+ world.password = password;
118
+ }
119
+ }, {
120
+ match: /^I enter correctly the password$/, step: (world, expectedPassword) => {
121
+ world.grantedAccess = world.password === expectedPassword;
122
+ }
123
+ }, {
124
+ match: /^I should be granted access$/, step: (world) => {
125
+ expect(world.grantedAccess).toBeTruthy();
126
+ }
127
+ }];
128
+
129
+ const world: World = {
130
+ password: undefined,
131
+ grantedAccess: false
132
+ }
133
+ testRunner<World>(`${__dirname}/features/**/*.feature`, stepDefinitions, world);
134
+ ```
135
+
136
+ ## Running scenario outlines
137
+ Scenario outline steps are defined in the same way as normal scenario steps. The scenario outline is expanded into a test run for
138
+ each row of the examples.
139
+
140
+ ## Jest configuration
141
+ Create a `jest.config.js` file in the project root (or update the existing one) to match the `runner.ts` file:
142
+ ```js
143
+ module.exports = {
144
+ testMatch: [
145
+ '<rootDir>/test/runner.ts'
146
+ ],
147
+ transform: {
148
+ '^.+\\.[tj]s$': ['ts-jest', {
149
+ tsconfig: '<rootDir>/tsconfig.spec.json',
150
+ }]
151
+ },
152
+ moduleFileExtensions: ['ts', 'js', 'html'],
153
+ coverageDirectory: '../coverage/',
154
+ };
155
+ ```
@@ -0,0 +1,82 @@
1
+ token literal names:
2
+ null
3
+ null
4
+ null
5
+ null
6
+ null
7
+ null
8
+ null
9
+ null
10
+ null
11
+ null
12
+ null
13
+ null
14
+ null
15
+ '|'
16
+ null
17
+ null
18
+ null
19
+ null
20
+ null
21
+ null
22
+ null
23
+ null
24
+
25
+ token symbolic names:
26
+ null
27
+ FEATURE
28
+ SCENARIO
29
+ SCENARIO_OUTLINE
30
+ GIVEN
31
+ AND_GIVEN
32
+ WHEN
33
+ AND_WHEN
34
+ THEN
35
+ AND
36
+ BUT
37
+ EXAMPLES
38
+ BACKGROUND
39
+ PIPE
40
+ TAG
41
+ COMMENT
42
+ TEXT_CHARACTER
43
+ WS
44
+ WSS
45
+ DOC_STRING_QUOT
46
+ DOC_STRING_TEXT
47
+ DOC_STRING_WS
48
+
49
+ rule names:
50
+ FEATURE
51
+ SCENARIO
52
+ SCENARIO_OUTLINE
53
+ GIVEN
54
+ AND_GIVEN
55
+ WHEN
56
+ AND_WHEN
57
+ THEN
58
+ AND
59
+ BUT
60
+ EXAMPLES
61
+ BACKGROUND
62
+ PIPE
63
+ TAG
64
+ COMMENT
65
+ TEXT_CHARACTER
66
+ WS
67
+ WSS
68
+ DOC_STRING_QUOT
69
+ DOC_STRING_TEXT
70
+ DOC_STRING_WS
71
+ DOC_STRING_QUOT_2
72
+
73
+ channel names:
74
+ DEFAULT_TOKEN_CHANNEL
75
+ HIDDEN
76
+
77
+ mode names:
78
+ DEFAULT_MODE
79
+ DOC_STRING_MODE
80
+
81
+ atn:
82
+ [4, 0, 21, 301, 6, -1, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 62, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 81, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 116, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 128, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 148, 8, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 158, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 176, 8, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 3, 7, 186, 8, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 3, 8, 194, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 202, 8, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 221, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 244, 8, 11, 1, 12, 1, 12, 1, 13, 1, 13, 4, 13, 250, 8, 13, 11, 13, 12, 13, 251, 1, 14, 1, 14, 5, 14, 256, 8, 14, 10, 14, 12, 14, 259, 9, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 4, 16, 266, 8, 16, 11, 16, 12, 16, 267, 1, 16, 1, 16, 1, 17, 4, 17, 273, 8, 17, 11, 17, 12, 17, 274, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 4, 19, 286, 8, 19, 11, 19, 12, 19, 287, 1, 20, 4, 20, 291, 8, 20, 11, 20, 12, 20, 292, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 0, 0, 22, 2, 1, 4, 2, 6, 3, 8, 4, 10, 5, 12, 6, 14, 7, 16, 8, 18, 9, 20, 10, 22, 11, 24, 12, 26, 13, 28, 14, 30, 15, 32, 16, 34, 17, 36, 18, 38, 19, 40, 20, 42, 21, 44, 0, 2, 0, 1, 5, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 2, 0, 10, 10, 13, 13, 3, 0, 10, 10, 13, 13, 34, 34, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 34, 34, 317, 0, 2, 1, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 12, 1, 0, 0, 0, 0, 14, 1, 0, 0, 0, 0, 16, 1, 0, 0, 0, 0, 18, 1, 0, 0, 0, 0, 20, 1, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 24, 1, 0, 0, 0, 0, 26, 1, 0, 0, 0, 0, 28, 1, 0, 0, 0, 0, 30, 1, 0, 0, 0, 0, 32, 1, 0, 0, 0, 0, 34, 1, 0, 0, 0, 0, 36, 1, 0, 0, 0, 0, 38, 1, 0, 0, 0, 1, 40, 1, 0, 0, 0, 1, 42, 1, 0, 0, 0, 1, 44, 1, 0, 0, 0, 2, 61, 1, 0, 0, 0, 4, 80, 1, 0, 0, 0, 6, 115, 1, 0, 0, 0, 8, 127, 1, 0, 0, 0, 10, 147, 1, 0, 0, 0, 12, 157, 1, 0, 0, 0, 14, 175, 1, 0, 0, 0, 16, 185, 1, 0, 0, 0, 18, 193, 1, 0, 0, 0, 20, 201, 1, 0, 0, 0, 22, 220, 1, 0, 0, 0, 24, 243, 1, 0, 0, 0, 26, 245, 1, 0, 0, 0, 28, 247, 1, 0, 0, 0, 30, 253, 1, 0, 0, 0, 32, 262, 1, 0, 0, 0, 34, 265, 1, 0, 0, 0, 36, 272, 1, 0, 0, 0, 38, 278, 1, 0, 0, 0, 40, 285, 1, 0, 0, 0, 42, 290, 1, 0, 0, 0, 44, 294, 1, 0, 0, 0, 46, 47, 5, 70, 0, 0, 47, 48, 5, 101, 0, 0, 48, 49, 5, 97, 0, 0, 49, 50, 5, 116, 0, 0, 50, 51, 5, 117, 0, 0, 51, 52, 5, 114, 0, 0, 52, 53, 5, 101, 0, 0, 53, 62, 5, 58, 0, 0, 54, 55, 5, 70, 0, 0, 55, 56, 5, 69, 0, 0, 56, 57, 5, 65, 0, 0, 57, 58, 5, 84, 0, 0, 58, 59, 5, 85, 0, 0, 59, 60, 5, 82, 0, 0, 60, 62, 5, 69, 0, 0, 61, 46, 1, 0, 0, 0, 61, 54, 1, 0, 0, 0, 62, 3, 1, 0, 0, 0, 63, 64, 5, 83, 0, 0, 64, 65, 5, 99, 0, 0, 65, 66, 5, 101, 0, 0, 66, 67, 5, 110, 0, 0, 67, 68, 5, 97, 0, 0, 68, 69, 5, 114, 0, 0, 69, 70, 5, 105, 0, 0, 70, 71, 5, 111, 0, 0, 71, 81, 5, 58, 0, 0, 72, 73, 5, 83, 0, 0, 73, 74, 5, 67, 0, 0, 74, 75, 5, 69, 0, 0, 75, 76, 5, 78, 0, 0, 76, 77, 5, 65, 0, 0, 77, 78, 5, 82, 0, 0, 78, 79, 5, 73, 0, 0, 79, 81, 5, 79, 0, 0, 80, 63, 1, 0, 0, 0, 80, 72, 1, 0, 0, 0, 81, 5, 1, 0, 0, 0, 82, 83, 5, 83, 0, 0, 83, 84, 5, 99, 0, 0, 84, 85, 5, 101, 0, 0, 85, 86, 5, 110, 0, 0, 86, 87, 5, 97, 0, 0, 87, 88, 5, 114, 0, 0, 88, 89, 5, 105, 0, 0, 89, 90, 5, 111, 0, 0, 90, 91, 5, 32, 0, 0, 91, 92, 5, 79, 0, 0, 92, 93, 5, 117, 0, 0, 93, 94, 5, 116, 0, 0, 94, 95, 5, 108, 0, 0, 95, 96, 5, 105, 0, 0, 96, 97, 5, 110, 0, 0, 97, 98, 5, 101, 0, 0, 98, 116, 5, 58, 0, 0, 99, 100, 5, 83, 0, 0, 100, 101, 5, 67, 0, 0, 101, 102, 5, 69, 0, 0, 102, 103, 5, 78, 0, 0, 103, 104, 5, 65, 0, 0, 104, 105, 5, 82, 0, 0, 105, 106, 5, 73, 0, 0, 106, 107, 5, 79, 0, 0, 107, 108, 5, 95, 0, 0, 108, 109, 5, 79, 0, 0, 109, 110, 5, 85, 0, 0, 110, 111, 5, 84, 0, 0, 111, 112, 5, 76, 0, 0, 112, 113, 5, 73, 0, 0, 113, 114, 5, 78, 0, 0, 114, 116, 5, 69, 0, 0, 115, 82, 1, 0, 0, 0, 115, 99, 1, 0, 0, 0, 116, 7, 1, 0, 0, 0, 117, 118, 5, 71, 0, 0, 118, 119, 5, 105, 0, 0, 119, 120, 5, 118, 0, 0, 120, 121, 5, 101, 0, 0, 121, 128, 5, 110, 0, 0, 122, 123, 5, 71, 0, 0, 123, 124, 5, 73, 0, 0, 124, 125, 5, 86, 0, 0, 125, 126, 5, 69, 0, 0, 126, 128, 5, 78, 0, 0, 127, 117, 1, 0, 0, 0, 127, 122, 1, 0, 0, 0, 128, 9, 1, 0, 0, 0, 129, 130, 5, 65, 0, 0, 130, 131, 5, 110, 0, 0, 131, 132, 5, 100, 0, 0, 132, 133, 5, 32, 0, 0, 133, 134, 5, 103, 0, 0, 134, 135, 5, 105, 0, 0, 135, 136, 5, 118, 0, 0, 136, 137, 5, 101, 0, 0, 137, 148, 5, 110, 0, 0, 138, 139, 5, 65, 0, 0, 139, 140, 5, 78, 0, 0, 140, 141, 5, 68, 0, 0, 141, 142, 5, 95, 0, 0, 142, 143, 5, 71, 0, 0, 143, 144, 5, 73, 0, 0, 144, 145, 5, 86, 0, 0, 145, 146, 5, 69, 0, 0, 146, 148, 5, 78, 0, 0, 147, 129, 1, 0, 0, 0, 147, 138, 1, 0, 0, 0, 148, 11, 1, 0, 0, 0, 149, 150, 5, 87, 0, 0, 150, 151, 5, 104, 0, 0, 151, 152, 5, 101, 0, 0, 152, 158, 5, 110, 0, 0, 153, 154, 5, 87, 0, 0, 154, 155, 5, 72, 0, 0, 155, 156, 5, 69, 0, 0, 156, 158, 5, 78, 0, 0, 157, 149, 1, 0, 0, 0, 157, 153, 1, 0, 0, 0, 158, 13, 1, 0, 0, 0, 159, 160, 5, 65, 0, 0, 160, 161, 5, 110, 0, 0, 161, 162, 5, 100, 0, 0, 162, 163, 5, 32, 0, 0, 163, 164, 5, 119, 0, 0, 164, 165, 5, 104, 0, 0, 165, 166, 5, 101, 0, 0, 166, 176, 5, 110, 0, 0, 167, 168, 5, 65, 0, 0, 168, 169, 5, 78, 0, 0, 169, 170, 5, 68, 0, 0, 170, 171, 5, 95, 0, 0, 171, 172, 5, 87, 0, 0, 172, 173, 5, 72, 0, 0, 173, 174, 5, 69, 0, 0, 174, 176, 5, 78, 0, 0, 175, 159, 1, 0, 0, 0, 175, 167, 1, 0, 0, 0, 176, 15, 1, 0, 0, 0, 177, 178, 5, 84, 0, 0, 178, 179, 5, 104, 0, 0, 179, 180, 5, 101, 0, 0, 180, 186, 5, 110, 0, 0, 181, 182, 5, 84, 0, 0, 182, 183, 5, 72, 0, 0, 183, 184, 5, 69, 0, 0, 184, 186, 5, 78, 0, 0, 185, 177, 1, 0, 0, 0, 185, 181, 1, 0, 0, 0, 186, 17, 1, 0, 0, 0, 187, 188, 5, 65, 0, 0, 188, 189, 5, 110, 0, 0, 189, 194, 5, 100, 0, 0, 190, 191, 5, 65, 0, 0, 191, 192, 5, 78, 0, 0, 192, 194, 5, 68, 0, 0, 193, 187, 1, 0, 0, 0, 193, 190, 1, 0, 0, 0, 194, 19, 1, 0, 0, 0, 195, 196, 5, 66, 0, 0, 196, 197, 5, 117, 0, 0, 197, 202, 5, 116, 0, 0, 198, 199, 5, 66, 0, 0, 199, 200, 5, 85, 0, 0, 200, 202, 5, 84, 0, 0, 201, 195, 1, 0, 0, 0, 201, 198, 1, 0, 0, 0, 202, 21, 1, 0, 0, 0, 203, 204, 5, 69, 0, 0, 204, 205, 5, 120, 0, 0, 205, 206, 5, 97, 0, 0, 206, 207, 5, 109, 0, 0, 207, 208, 5, 112, 0, 0, 208, 209, 5, 108, 0, 0, 209, 210, 5, 101, 0, 0, 210, 211, 5, 115, 0, 0, 211, 221, 5, 58, 0, 0, 212, 213, 5, 69, 0, 0, 213, 214, 5, 88, 0, 0, 214, 215, 5, 65, 0, 0, 215, 216, 5, 77, 0, 0, 216, 217, 5, 80, 0, 0, 217, 218, 5, 76, 0, 0, 218, 219, 5, 69, 0, 0, 219, 221, 5, 83, 0, 0, 220, 203, 1, 0, 0, 0, 220, 212, 1, 0, 0, 0, 221, 23, 1, 0, 0, 0, 222, 223, 5, 66, 0, 0, 223, 224, 5, 97, 0, 0, 224, 225, 5, 99, 0, 0, 225, 226, 5, 107, 0, 0, 226, 227, 5, 103, 0, 0, 227, 228, 5, 114, 0, 0, 228, 229, 5, 111, 0, 0, 229, 230, 5, 117, 0, 0, 230, 231, 5, 110, 0, 0, 231, 232, 5, 100, 0, 0, 232, 244, 5, 58, 0, 0, 233, 234, 5, 66, 0, 0, 234, 235, 5, 65, 0, 0, 235, 236, 5, 67, 0, 0, 236, 237, 5, 75, 0, 0, 237, 238, 5, 71, 0, 0, 238, 239, 5, 82, 0, 0, 239, 240, 5, 79, 0, 0, 240, 241, 5, 85, 0, 0, 241, 242, 5, 78, 0, 0, 242, 244, 5, 68, 0, 0, 243, 222, 1, 0, 0, 0, 243, 233, 1, 0, 0, 0, 244, 25, 1, 0, 0, 0, 245, 246, 5, 124, 0, 0, 246, 27, 1, 0, 0, 0, 247, 249, 5, 64, 0, 0, 248, 250, 7, 0, 0, 0, 249, 248, 1, 0, 0, 0, 250, 251, 1, 0, 0, 0, 251, 249, 1, 0, 0, 0, 251, 252, 1, 0, 0, 0, 252, 29, 1, 0, 0, 0, 253, 257, 5, 35, 0, 0, 254, 256, 8, 1, 0, 0, 255, 254, 1, 0, 0, 0, 256, 259, 1, 0, 0, 0, 257, 255, 1, 0, 0, 0, 257, 258, 1, 0, 0, 0, 258, 260, 1, 0, 0, 0, 259, 257, 1, 0, 0, 0, 260, 261, 6, 14, 0, 0, 261, 31, 1, 0, 0, 0, 262, 263, 8, 2, 0, 0, 263, 33, 1, 0, 0, 0, 264, 266, 7, 1, 0, 0, 265, 264, 1, 0, 0, 0, 266, 267, 1, 0, 0, 0, 267, 265, 1, 0, 0, 0, 267, 268, 1, 0, 0, 0, 268, 269, 1, 0, 0, 0, 269, 270, 6, 16, 0, 0, 270, 35, 1, 0, 0, 0, 271, 273, 7, 3, 0, 0, 272, 271, 1, 0, 0, 0, 273, 274, 1, 0, 0, 0, 274, 272, 1, 0, 0, 0, 274, 275, 1, 0, 0, 0, 275, 276, 1, 0, 0, 0, 276, 277, 6, 17, 0, 0, 277, 37, 1, 0, 0, 0, 278, 279, 5, 34, 0, 0, 279, 280, 5, 34, 0, 0, 280, 281, 5, 34, 0, 0, 281, 282, 1, 0, 0, 0, 282, 283, 6, 18, 1, 0, 283, 39, 1, 0, 0, 0, 284, 286, 8, 4, 0, 0, 285, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 287, 288, 1, 0, 0, 0, 288, 41, 1, 0, 0, 0, 289, 291, 7, 3, 0, 0, 290, 289, 1, 0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 290, 1, 0, 0, 0, 292, 293, 1, 0, 0, 0, 293, 43, 1, 0, 0, 0, 294, 295, 5, 34, 0, 0, 295, 296, 5, 34, 0, 0, 296, 297, 5, 34, 0, 0, 297, 298, 1, 0, 0, 0, 298, 299, 6, 21, 2, 0, 299, 300, 6, 21, 3, 0, 300, 45, 1, 0, 0, 0, 20, 0, 1, 61, 80, 115, 127, 147, 157, 175, 185, 193, 201, 220, 243, 251, 257, 267, 274, 287, 292, 4, 6, 0, 0, 5, 1, 0, 7, 19, 0, 4, 0, 0]