@testgorilla/tgo-typing-test 0.0.1
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/.eslintrc.json +45 -0
- package/README.md +95 -0
- package/jest.config.ts +21 -0
- package/ng-package.json +15 -0
- package/package.json +20 -0
- package/project.json +36 -0
- package/src/assets/typing-test-languages/english.json +207 -0
- package/src/assets/typing-test-languages/english_punctuation.json +18 -0
- package/src/assets/typing-test-languages/quotes/english_version_1.json +35291 -0
- package/src/assets/typing-test-languages/quotes/english_version_2.json +720 -0
- package/src/assets/typing-test-languages/quotes/filtered_sources.json +79 -0
- package/src/index.ts +2 -0
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.html +30 -0
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.spec.ts +250 -0
- package/src/lib/components/tgo-typing-replay-input/tgo-typing-replay-input.component.ts +48 -0
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.html +72 -0
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.spec.ts +699 -0
- package/src/lib/components/tgo-typing-test/tgo-typing-test.component.ts +294 -0
- package/src/lib/helpers/config.ts +28 -0
- package/src/lib/helpers/constants/default-config.ts +103 -0
- package/src/lib/helpers/controllers/input-controller.ts +710 -0
- package/src/lib/helpers/controllers/quotes-controller.ts +183 -0
- package/src/lib/helpers/observables/banner-event.ts +18 -0
- package/src/lib/helpers/observables/config-event.ts +31 -0
- package/src/lib/helpers/observables/timer-event.ts +18 -0
- package/src/lib/helpers/states/active-page.ts +9 -0
- package/src/lib/helpers/states/composition.ts +29 -0
- package/src/lib/helpers/states/page-transition.ts +9 -0
- package/src/lib/helpers/states/slow-timer.ts +16 -0
- package/src/lib/helpers/states/test-active.ts +9 -0
- package/src/lib/helpers/states/time.ts +13 -0
- package/src/lib/helpers/test/caps-warning.ts +50 -0
- package/src/lib/helpers/test/caret.ts +92 -0
- package/src/lib/helpers/test/custom-text.ts +73 -0
- package/src/lib/helpers/test/english-punctuation.ts +38 -0
- package/src/lib/helpers/test/focus.ts +39 -0
- package/src/lib/helpers/test/manual-restart-tracker.ts +13 -0
- package/src/lib/helpers/test/out-of-focus.ts +19 -0
- package/src/lib/helpers/test/replay.ts +265 -0
- package/src/lib/helpers/test/test-input.ts +320 -0
- package/src/lib/helpers/test/test-logic.ts +1039 -0
- package/src/lib/helpers/test/test-state.ts +17 -0
- package/src/lib/helpers/test/test-stats.ts +442 -0
- package/src/lib/helpers/test/test-timer.ts +209 -0
- package/src/lib/helpers/test/test-ui.ts +370 -0
- package/src/lib/helpers/test/test-words.ts +72 -0
- package/src/lib/helpers/test/timer-progress.ts +16 -0
- package/src/lib/helpers/test/tts.ts +42 -0
- package/src/lib/helpers/test/weak-spot.ts +74 -0
- package/src/lib/helpers/test/wordset.ts +109 -0
- package/src/lib/styles/animations.scss +101 -0
- package/src/lib/styles/caret.scss +108 -0
- package/src/lib/styles/core.scss +498 -0
- package/src/lib/styles/index.scss +19 -0
- package/src/lib/styles/inputs.scss +290 -0
- package/src/lib/styles/popups.scss +1311 -0
- package/src/lib/styles/test.scss +1008 -0
- package/src/lib/styles/z_media-queries.scss +848 -0
- package/src/lib/types/types.d.ts +731 -0
- package/src/lib/utils/misc.ts +776 -0
- package/src/test-setup.ts +1 -0
- package/tsconfig.json +16 -0
- package/tsconfig.lib.json +14 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +11 -0
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["../../.eslintrc.json"],
|
|
3
|
+
"ignorePatterns": ["!**/*"],
|
|
4
|
+
"overrides": [
|
|
5
|
+
{
|
|
6
|
+
"files": ["*.ts"],
|
|
7
|
+
"extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
|
|
8
|
+
"rules": {
|
|
9
|
+
"@angular-eslint/directive-selector": [
|
|
10
|
+
"error",
|
|
11
|
+
{
|
|
12
|
+
"type": "attribute",
|
|
13
|
+
"prefix": "tgo",
|
|
14
|
+
"style": "camelCase"
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"@angular-eslint/component-selector": [
|
|
18
|
+
"error",
|
|
19
|
+
{
|
|
20
|
+
"type": "element",
|
|
21
|
+
"prefix": "tgo",
|
|
22
|
+
"style": "kebab-case"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"files": ["*.html"],
|
|
29
|
+
"extends": ["plugin:@nx/angular-template"],
|
|
30
|
+
"rules": {}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"files": ["*.json"],
|
|
34
|
+
"parser": "jsonc-eslint-parser",
|
|
35
|
+
"rules": {
|
|
36
|
+
"@nx/dependency-checks": [
|
|
37
|
+
"error",
|
|
38
|
+
{
|
|
39
|
+
"ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"]
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @testgorilla/tgo-typing-test
|
|
2
|
+
|
|
3
|
+
Typing Test component for TestGorilla assessments.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @testgorilla/tgo-typing-test
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { TgoTypingTestComponent } from '@testgorilla/tgo-typing-test';
|
|
15
|
+
|
|
16
|
+
@Component({
|
|
17
|
+
imports: [TgoTypingTestComponent],
|
|
18
|
+
template: `
|
|
19
|
+
<tgo-typing-test
|
|
20
|
+
[time]="time!"
|
|
21
|
+
[showMiniTimerAndLiveWpm]="false"
|
|
22
|
+
[punctuation]="_typingTestMode?.punctuation!"
|
|
23
|
+
[numbers]="_typingTestMode?.numbers!"
|
|
24
|
+
[customTGQuotes]="_typingTestMode?.sentences!"
|
|
25
|
+
[funbox]="_typingTestMode?.funbox!"
|
|
26
|
+
[restartTest]="false"
|
|
27
|
+
[testVersion]="(test$ | async)?.test_version ?? 1"
|
|
28
|
+
[testExpiration$]="testExpiration$"
|
|
29
|
+
(replayExport)="updateTypingSnapshots($event)"
|
|
30
|
+
(resultEvent)="updateTypingTest($event)"
|
|
31
|
+
(errorEvent)="handleError($event)"
|
|
32
|
+
>
|
|
33
|
+
</tgo-typing-test>
|
|
34
|
+
`,
|
|
35
|
+
})
|
|
36
|
+
export class MyComponent {}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
### Inputs
|
|
42
|
+
|
|
43
|
+
| Name | Type | Required | Default | Description |
|
|
44
|
+
| ----------------------- | ----------------- | -------- | ------- | ------------------------------------------------ |
|
|
45
|
+
| time | number | No | 180 | Test duration in seconds |
|
|
46
|
+
| showMiniTimerAndLiveWpm | boolean | No | true | Show mini timer and live WPM display |
|
|
47
|
+
| punctuation | boolean | No | false | Include punctuation in test |
|
|
48
|
+
| numbers | boolean | No | false | Include numbers in test |
|
|
49
|
+
| customTGQuotes | boolean | No | false | Use custom TestGorilla quotes/sentences |
|
|
50
|
+
| funbox | string | No | 'none' | Funbox mode for visual effects |
|
|
51
|
+
| restartTest | boolean | No | false | Trigger to restart the test |
|
|
52
|
+
| testVersion | number | No | 1 | Test version for sentence variations |
|
|
53
|
+
| testExpiration$ | Observable\<void\>| No | - | Observable to trigger test expiration externally |
|
|
54
|
+
|
|
55
|
+
### Outputs
|
|
56
|
+
|
|
57
|
+
| Name | Type | Description |
|
|
58
|
+
| ------------ | --------------------- | ---------------------------------------- |
|
|
59
|
+
| resultEvent | EventEmitter\<any\> | Emits test results when test completes |
|
|
60
|
+
| replayExport | EventEmitter\<any\> | Emits replay data for test playback |
|
|
61
|
+
| errorEvent | EventEmitter\<string\>| Emits error messages (e.g., network errors)|
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## TgoTypingReplayInputComponent
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { TgoTypingReplayInputComponent } from '@testgorilla/tgo-typing-test';
|
|
69
|
+
|
|
70
|
+
@Component({
|
|
71
|
+
imports: [TgoTypingReplayInputComponent],
|
|
72
|
+
template: `
|
|
73
|
+
<tgo-typing-replay-input
|
|
74
|
+
[replayExport]="replayData"
|
|
75
|
+
[funbox]="funbox"
|
|
76
|
+
class="funbox"
|
|
77
|
+
data-testid="candidate.typing-report.replay-input"
|
|
78
|
+
></tgo-typing-replay-input>
|
|
79
|
+
`,
|
|
80
|
+
})
|
|
81
|
+
export class MyComponent {}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## API
|
|
85
|
+
|
|
86
|
+
### Inputs
|
|
87
|
+
|
|
88
|
+
| Name | Type | Required | Default | Description |
|
|
89
|
+
| ----------- | ------ | -------- | ------- | -------------------------------------------- |
|
|
90
|
+
| replayExport| any | Yes | - | Replay data exported from TgoTypingTestComponent|
|
|
91
|
+
| funbox | string | No | 'none' | Funbox mode for visual effects (must match original test)|
|
|
92
|
+
|
|
93
|
+
### Outputs
|
|
94
|
+
|
|
95
|
+
This component has no outputs. It automatically plays the replay after initialization.
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
displayName: 'tgo-typing-test',
|
|
3
|
+
preset: '../../jest.preset.js',
|
|
4
|
+
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
|
5
|
+
coverageDirectory: '../../coverage/packages/tgo-typing-test',
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.(ts|mjs|js|html)$': [
|
|
8
|
+
'jest-preset-angular',
|
|
9
|
+
{
|
|
10
|
+
tsconfig: '<rootDir>/tsconfig.spec.json',
|
|
11
|
+
stringifyContentPathRegex: '\\.(html|svg)$',
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
},
|
|
15
|
+
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
|
16
|
+
snapshotSerializers: [
|
|
17
|
+
'jest-preset-angular/build/serializers/no-ng-attributes',
|
|
18
|
+
'jest-preset-angular/build/serializers/ng-snapshot',
|
|
19
|
+
'jest-preset-angular/build/serializers/html-comment',
|
|
20
|
+
],
|
|
21
|
+
};
|
package/ng-package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
|
3
|
+
"dest": "../../dist/packages/tgo-typing-test",
|
|
4
|
+
"assets": [
|
|
5
|
+
{
|
|
6
|
+
"glob": "**/*",
|
|
7
|
+
"input": "./src/assets",
|
|
8
|
+
"output": "./assets"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"lib": {
|
|
12
|
+
"entryFile": "./src/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"allowedNonPeerDependencies": []
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@testgorilla/tgo-typing-test",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "~18.2.13",
|
|
6
|
+
"@angular/core": "~18.2.13",
|
|
7
|
+
"@angular/animations": "~18.2.13",
|
|
8
|
+
"jest-preset-angular": "~14.2.4",
|
|
9
|
+
"rxjs": "~7.8.1"
|
|
10
|
+
},
|
|
11
|
+
"typings": "src/lib/types",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"license": "PROPRIETARY",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "restricted",
|
|
16
|
+
"registry": "https://registry.npmjs.org/"
|
|
17
|
+
},
|
|
18
|
+
"displayName": "Typing Test",
|
|
19
|
+
"description": "Typing Test component"
|
|
20
|
+
}
|
package/project.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tgo-typing-test",
|
|
3
|
+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
4
|
+
"sourceRoot": "packages/tgo-typing-test/src",
|
|
5
|
+
"prefix": "tgo",
|
|
6
|
+
"projectType": "library",
|
|
7
|
+
"tags": [],
|
|
8
|
+
"targets": {
|
|
9
|
+
"build": {
|
|
10
|
+
"executor": "@nx/angular:package",
|
|
11
|
+
"outputs": ["{workspaceRoot}/dist/{projectRoot}"],
|
|
12
|
+
"options": {
|
|
13
|
+
"project": "packages/tgo-typing-test/ng-package.json"
|
|
14
|
+
},
|
|
15
|
+
"configurations": {
|
|
16
|
+
"production": {
|
|
17
|
+
"tsConfig": "packages/tgo-typing-test/tsconfig.lib.prod.json"
|
|
18
|
+
},
|
|
19
|
+
"development": {
|
|
20
|
+
"tsConfig": "packages/tgo-typing-test/tsconfig.lib.json"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"defaultConfiguration": "production"
|
|
24
|
+
},
|
|
25
|
+
"test": {
|
|
26
|
+
"executor": "@nx/jest:jest",
|
|
27
|
+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
|
28
|
+
"options": {
|
|
29
|
+
"jestConfig": "packages/tgo-typing-test/jest.config.ts"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"lint": {
|
|
33
|
+
"executor": "@nx/eslint:lint"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "english",
|
|
3
|
+
"leftToRight": true,
|
|
4
|
+
"noLazyMode": true,
|
|
5
|
+
"words": [
|
|
6
|
+
"the",
|
|
7
|
+
"be",
|
|
8
|
+
"of",
|
|
9
|
+
"and",
|
|
10
|
+
"a",
|
|
11
|
+
"to",
|
|
12
|
+
"in",
|
|
13
|
+
"he",
|
|
14
|
+
"have",
|
|
15
|
+
"it",
|
|
16
|
+
"that",
|
|
17
|
+
"for",
|
|
18
|
+
"they",
|
|
19
|
+
"I",
|
|
20
|
+
"with",
|
|
21
|
+
"as",
|
|
22
|
+
"not",
|
|
23
|
+
"on",
|
|
24
|
+
"she",
|
|
25
|
+
"at",
|
|
26
|
+
"by",
|
|
27
|
+
"this",
|
|
28
|
+
"we",
|
|
29
|
+
"you",
|
|
30
|
+
"do",
|
|
31
|
+
"but",
|
|
32
|
+
"from",
|
|
33
|
+
"or",
|
|
34
|
+
"which",
|
|
35
|
+
"one",
|
|
36
|
+
"would",
|
|
37
|
+
"all",
|
|
38
|
+
"will",
|
|
39
|
+
"there",
|
|
40
|
+
"say",
|
|
41
|
+
"who",
|
|
42
|
+
"make",
|
|
43
|
+
"when",
|
|
44
|
+
"can",
|
|
45
|
+
"more",
|
|
46
|
+
"if",
|
|
47
|
+
"no",
|
|
48
|
+
"man",
|
|
49
|
+
"out",
|
|
50
|
+
"other",
|
|
51
|
+
"so",
|
|
52
|
+
"what",
|
|
53
|
+
"time",
|
|
54
|
+
"up",
|
|
55
|
+
"go",
|
|
56
|
+
"about",
|
|
57
|
+
"than",
|
|
58
|
+
"into",
|
|
59
|
+
"could",
|
|
60
|
+
"state",
|
|
61
|
+
"only",
|
|
62
|
+
"new",
|
|
63
|
+
"year",
|
|
64
|
+
"some",
|
|
65
|
+
"take",
|
|
66
|
+
"come",
|
|
67
|
+
"these",
|
|
68
|
+
"know",
|
|
69
|
+
"see",
|
|
70
|
+
"use",
|
|
71
|
+
"get",
|
|
72
|
+
"like",
|
|
73
|
+
"then",
|
|
74
|
+
"first",
|
|
75
|
+
"any",
|
|
76
|
+
"work",
|
|
77
|
+
"now",
|
|
78
|
+
"may",
|
|
79
|
+
"such",
|
|
80
|
+
"give",
|
|
81
|
+
"over",
|
|
82
|
+
"think",
|
|
83
|
+
"most",
|
|
84
|
+
"even",
|
|
85
|
+
"find",
|
|
86
|
+
"day",
|
|
87
|
+
"also",
|
|
88
|
+
"after",
|
|
89
|
+
"way",
|
|
90
|
+
"many",
|
|
91
|
+
"must",
|
|
92
|
+
"look",
|
|
93
|
+
"before",
|
|
94
|
+
"great",
|
|
95
|
+
"back",
|
|
96
|
+
"through",
|
|
97
|
+
"long",
|
|
98
|
+
"where",
|
|
99
|
+
"much",
|
|
100
|
+
"should",
|
|
101
|
+
"well",
|
|
102
|
+
"people",
|
|
103
|
+
"down",
|
|
104
|
+
"own",
|
|
105
|
+
"just",
|
|
106
|
+
"because",
|
|
107
|
+
"good",
|
|
108
|
+
"each",
|
|
109
|
+
"those",
|
|
110
|
+
"feel",
|
|
111
|
+
"seem",
|
|
112
|
+
"how",
|
|
113
|
+
"high",
|
|
114
|
+
"too",
|
|
115
|
+
"place",
|
|
116
|
+
"little",
|
|
117
|
+
"world",
|
|
118
|
+
"very",
|
|
119
|
+
"still",
|
|
120
|
+
"nation",
|
|
121
|
+
"hand",
|
|
122
|
+
"old",
|
|
123
|
+
"life",
|
|
124
|
+
"tell",
|
|
125
|
+
"write",
|
|
126
|
+
"become",
|
|
127
|
+
"here",
|
|
128
|
+
"show",
|
|
129
|
+
"house",
|
|
130
|
+
"both",
|
|
131
|
+
"between",
|
|
132
|
+
"need",
|
|
133
|
+
"mean",
|
|
134
|
+
"call",
|
|
135
|
+
"develop",
|
|
136
|
+
"under",
|
|
137
|
+
"last",
|
|
138
|
+
"right",
|
|
139
|
+
"move",
|
|
140
|
+
"thing",
|
|
141
|
+
"general",
|
|
142
|
+
"school",
|
|
143
|
+
"never",
|
|
144
|
+
"same",
|
|
145
|
+
"another",
|
|
146
|
+
"begin",
|
|
147
|
+
"while",
|
|
148
|
+
"number",
|
|
149
|
+
"part",
|
|
150
|
+
"turn",
|
|
151
|
+
"real",
|
|
152
|
+
"leave",
|
|
153
|
+
"might",
|
|
154
|
+
"want",
|
|
155
|
+
"point",
|
|
156
|
+
"form",
|
|
157
|
+
"off",
|
|
158
|
+
"child",
|
|
159
|
+
"few",
|
|
160
|
+
"small",
|
|
161
|
+
"since",
|
|
162
|
+
"against",
|
|
163
|
+
"ask",
|
|
164
|
+
"late",
|
|
165
|
+
"home",
|
|
166
|
+
"interest",
|
|
167
|
+
"large",
|
|
168
|
+
"person",
|
|
169
|
+
"end",
|
|
170
|
+
"open",
|
|
171
|
+
"public",
|
|
172
|
+
"follow",
|
|
173
|
+
"during",
|
|
174
|
+
"present",
|
|
175
|
+
"without",
|
|
176
|
+
"again",
|
|
177
|
+
"hold",
|
|
178
|
+
"govern",
|
|
179
|
+
"around",
|
|
180
|
+
"possible",
|
|
181
|
+
"head",
|
|
182
|
+
"consider",
|
|
183
|
+
"word",
|
|
184
|
+
"program",
|
|
185
|
+
"problem",
|
|
186
|
+
"however",
|
|
187
|
+
"lead",
|
|
188
|
+
"system",
|
|
189
|
+
"set",
|
|
190
|
+
"order",
|
|
191
|
+
"eye",
|
|
192
|
+
"plan",
|
|
193
|
+
"run",
|
|
194
|
+
"keep",
|
|
195
|
+
"face",
|
|
196
|
+
"fact",
|
|
197
|
+
"group",
|
|
198
|
+
"play",
|
|
199
|
+
"stand",
|
|
200
|
+
"increase",
|
|
201
|
+
"early",
|
|
202
|
+
"course",
|
|
203
|
+
"change",
|
|
204
|
+
"help",
|
|
205
|
+
"line"
|
|
206
|
+
]
|
|
207
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[
|
|
2
|
+
["are", "aren't"],
|
|
3
|
+
["can", "can't"],
|
|
4
|
+
["could", "couldn't"],
|
|
5
|
+
["did", "didn't"],
|
|
6
|
+
["does", "doesn't"],
|
|
7
|
+
["do", "don't"],
|
|
8
|
+
["had", "hadn't"],
|
|
9
|
+
["has", "hasn't"],
|
|
10
|
+
["have", "haven't"],
|
|
11
|
+
["is", "isn't"],
|
|
12
|
+
["must", "mustn't"],
|
|
13
|
+
["should", "shouldn't"],
|
|
14
|
+
["was", "wasn't"],
|
|
15
|
+
["were", "weren't"],
|
|
16
|
+
["will", "won't"],
|
|
17
|
+
["would", "wouldn't"]
|
|
18
|
+
]
|