string-match-left-right 7.1.0 → 8.0.3
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/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,36 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 8.0.3 (2021-11-02)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- bump TS and separate ESLint plugins away from this monorepo ([b1ebce1](https://github.com/codsen/codsen/commit/b1ebce1637d8c41c2d848fc24b0ba4058865bd5d))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- migrate to ES Modules ([c579dff](https://github.com/codsen/codsen/commit/c579dff3b23205e383035ca10ddcec671e35d0fe))
|
|
15
|
+
|
|
16
|
+
### BREAKING CHANGES
|
|
17
|
+
|
|
18
|
+
- programs now are in ES Modules and won't work with Common JS require()
|
|
19
|
+
|
|
20
|
+
## 8.0.1 (2021-09-13)
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
- bump TS and separate ESLint plugins away from this monorepo ([2e07d42](https://github.com/codsen/codsen/commit/2e07d424222b6ffedf5fb45c83ad453627ec2904))
|
|
25
|
+
|
|
26
|
+
## 8.0.0 (2021-09-09)
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
- migrate to ES Modules ([8c9d95d](https://github.com/codsen/codsen/commit/8c9d95d5dea0b769c2f070397141918a4893d575))
|
|
31
|
+
|
|
32
|
+
### BREAKING CHANGES
|
|
33
|
+
|
|
34
|
+
- programs now are in ES Modules and won't work with Common JS require()
|
|
35
|
+
|
|
6
36
|
## 7.1.0 (2021-05-24)
|
|
7
37
|
|
|
8
38
|
### Features
|
package/README.md
CHANGED
|
@@ -26,10 +26,14 @@
|
|
|
26
26
|
|
|
27
27
|
## Install
|
|
28
28
|
|
|
29
|
+
This package is ESM only: Node 12+ is needed to use it and it must be imported instead of required:
|
|
30
|
+
|
|
29
31
|
```bash
|
|
30
32
|
npm i string-match-left-right
|
|
31
33
|
```
|
|
32
34
|
|
|
35
|
+
If you need a legacy version which works with `require`, use version 7.1.0
|
|
36
|
+
|
|
33
37
|
## Quick Take
|
|
34
38
|
|
|
35
39
|
```js
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name string-match-left-right
|
|
3
3
|
* @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
|
|
4
|
-
* @version
|
|
4
|
+
* @version 8.0.3
|
|
5
5
|
* @author Roy Revelt, Codsen Ltd
|
|
6
6
|
* @license MIT
|
|
7
7
|
* {@link https://codsen.com/os/string-match-left-right/}
|
|
@@ -207,52 +207,52 @@ function main(mode, str, position, originalWhatToMatch, originalOpts) {
|
|
|
207
207
|
Array.isArray(whatToMatch) && !whatToMatch.length ||
|
|
208
208
|
Array.isArray(whatToMatch) && whatToMatch.length === 1 && isStr(whatToMatch[0]) && !whatToMatch[0].trim()
|
|
209
209
|
) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
} else if (mode.startsWith("matchRight")) {
|
|
225
|
-
for (let y = startingPosition; y < str.length; y++) {
|
|
226
|
-
const currentChar = str[y];
|
|
227
|
-
if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(currentChar))) {
|
|
228
|
-
firstCharOutsideIndex = y;
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
210
|
+
if (typeof opts.cb === "function") {
|
|
211
|
+
let firstCharOutsideIndex;
|
|
212
|
+
let startingPosition = position;
|
|
213
|
+
if (mode === "matchLeftIncl" || mode === "matchRight") {
|
|
214
|
+
startingPosition += 1;
|
|
215
|
+
}
|
|
216
|
+
if (mode[5] === "L") {
|
|
217
|
+
for (let y = startingPosition; y--;) {
|
|
218
|
+
const currentChar = str[y];
|
|
219
|
+
if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar !== undefined && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || currentChar !== undefined && !opts.trimCharsBeforeMatching.includes(currentChar))) {
|
|
220
|
+
firstCharOutsideIndex = y;
|
|
221
|
+
break;
|
|
231
222
|
}
|
|
232
223
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
|
|
241
|
-
}
|
|
242
|
-
if (mode[5] === "L") {
|
|
243
|
-
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
244
|
-
}
|
|
245
|
-
if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
|
|
246
|
-
theRemainderOfTheString = str.slice(firstCharOutsideIndex);
|
|
224
|
+
} else if (mode.startsWith("matchRight")) {
|
|
225
|
+
for (let y = startingPosition; y < str.length; y++) {
|
|
226
|
+
const currentChar = str[y];
|
|
227
|
+
if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(currentChar))) {
|
|
228
|
+
firstCharOutsideIndex = y;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
247
231
|
}
|
|
232
|
+
}
|
|
233
|
+
if (firstCharOutsideIndex === undefined) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
const wholeCharacterOutside = str[firstCharOutsideIndex];
|
|
237
|
+
const indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
|
|
238
|
+
let theRemainderOfTheString = "";
|
|
239
|
+
if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
|
|
240
|
+
theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
|
|
241
|
+
}
|
|
242
|
+
if (mode[5] === "L") {
|
|
248
243
|
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
249
244
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
extraNote = " More so, the whole options object, the fourth input argument, is missing!";
|
|
245
|
+
if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
|
|
246
|
+
theRemainderOfTheString = str.slice(firstCharOutsideIndex);
|
|
253
247
|
}
|
|
254
|
-
|
|
248
|
+
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
255
249
|
}
|
|
250
|
+
let extraNote = "";
|
|
251
|
+
if (!originalOpts) {
|
|
252
|
+
extraNote = " More so, the whole options object, the fourth input argument, is missing!";
|
|
253
|
+
}
|
|
254
|
+
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_08] the third argument, "whatToMatch", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key "cb" is not set!${extraNote}`);
|
|
255
|
+
}
|
|
256
256
|
for (let i = 0, len = whatToMatch.length; i < len; i++) {
|
|
257
257
|
special = typeof whatToMatch[i] === "function";
|
|
258
258
|
const whatToMatchVal = whatToMatch[i];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name string-match-left-right
|
|
3
3
|
* @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
|
|
4
|
-
* @version
|
|
4
|
+
* @version 8.0.3
|
|
5
5
|
* @author Roy Revelt, Codsen Ltd
|
|
6
6
|
* @license MIT
|
|
7
7
|
* {@link https://codsen.com/os/string-match-left-right/}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
/**
|
|
12
12
|
* @name arrayiffy-if-string
|
|
13
13
|
* @fileoverview Put non-empty strings into arrays, turn empty-ones into empty arrays. Bypass everything else.
|
|
14
|
-
* @version
|
|
14
|
+
* @version 4.0.3
|
|
15
15
|
* @author Roy Revelt, Codsen Ltd
|
|
16
16
|
* @license MIT
|
|
17
17
|
* {@link https://codsen.com/os/arrayiffy-if-string/}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "string-match-left-right",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.3",
|
|
4
4
|
"description": "Match substrings on the left or right of a given index, ignoring whitespace",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"left",
|
|
@@ -24,17 +24,21 @@
|
|
|
24
24
|
"email": "roy@codsen.com",
|
|
25
25
|
"url": "https://codsen.com"
|
|
26
26
|
},
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": {
|
|
29
|
+
"script": "./dist/string-match-left-right.umd.js",
|
|
30
|
+
"default": "./dist/string-match-left-right.esm.js"
|
|
31
|
+
},
|
|
30
32
|
"types": "types/index.d.ts",
|
|
31
33
|
"scripts": {
|
|
32
34
|
"build": "rollup -c",
|
|
33
|
-
"esbuild": "node '../../scripts/esbuild.js'",
|
|
34
|
-
"esbuild_dev": "cross-env MODE=dev node '../../scripts/esbuild.js'",
|
|
35
35
|
"ci_test": "npm run build && npm run format && tap --no-only --reporter=silent --output-file=testStats.md && npm run clean_cov",
|
|
36
|
+
"clean_cov": "../../scripts/leaveCoverageTotalOnly.js",
|
|
37
|
+
"clean_types": "../../scripts/cleanTypes.js",
|
|
36
38
|
"dev": "rollup -c --dev",
|
|
37
39
|
"devunittest": "npm run dev && tap --only -R 'base'",
|
|
40
|
+
"esbuild": "node '../../scripts/esbuild.js'",
|
|
41
|
+
"esbuild_dev": "cross-env MODE=dev node '../../scripts/esbuild.js'",
|
|
38
42
|
"format": "npm run lect && npm run prettier && npm run lint",
|
|
39
43
|
"lect": "lect",
|
|
40
44
|
"lint": "../../node_modules/eslint/bin/eslint.js . --ext .js --ext .ts --fix --config \"../../.eslintrc.json\" --quiet",
|
|
@@ -42,22 +46,22 @@
|
|
|
42
46
|
"prettier": "../../node_modules/prettier/bin-prettier.js '*.{js,css,scss,vue,md,ts}' --write --loglevel silent",
|
|
43
47
|
"republish": "npm publish || :",
|
|
44
48
|
"tap": "tap",
|
|
45
|
-
"tsc": "tsc",
|
|
46
49
|
"pretest": "npm run build",
|
|
47
50
|
"test": "npm run lint && npm run unittest && npm run test:examples && npm run clean_cov && npm run format",
|
|
48
51
|
"test:examples": "../../scripts/test-examples.js && npm run lect && npm run prettier",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"clean_types": "../../scripts/cleanTypes.js"
|
|
52
|
+
"tsc": "tsc",
|
|
53
|
+
"unittest": "tap --no-only --output-file=testStats.md --reporter=terse && tsc -p tsconfig.json --noEmit && npm run clean_cov && npm run perf"
|
|
52
54
|
},
|
|
53
55
|
"tap": {
|
|
56
|
+
"check-coverage": false,
|
|
54
57
|
"coverage-report": [
|
|
55
58
|
"json-summary",
|
|
56
59
|
"text"
|
|
57
60
|
],
|
|
58
|
-
"
|
|
59
|
-
"--
|
|
60
|
-
"--
|
|
61
|
+
"node-arg": [
|
|
62
|
+
"--no-warnings",
|
|
63
|
+
"--experimental-loader",
|
|
64
|
+
"@istanbuljs/esm-loader-hook"
|
|
61
65
|
],
|
|
62
66
|
"timeout": 0
|
|
63
67
|
},
|
|
@@ -75,46 +79,50 @@
|
|
|
75
79
|
}
|
|
76
80
|
},
|
|
77
81
|
"dependencies": {
|
|
78
|
-
"@babel/runtime": "^7.
|
|
79
|
-
"arrayiffy-if-string": "^
|
|
82
|
+
"@babel/runtime": "^7.16.0",
|
|
83
|
+
"arrayiffy-if-string": "^4.0.3",
|
|
80
84
|
"lodash.isplainobject": "^4.0.6",
|
|
81
|
-
"string-character-is-astral-surrogate": "^
|
|
85
|
+
"string-character-is-astral-surrogate": "^2.0.3"
|
|
82
86
|
},
|
|
83
87
|
"devDependencies": {
|
|
84
|
-
"@babel/cli": "^7.
|
|
85
|
-
"@babel/core": "^7.
|
|
86
|
-
"@babel/node": "^7.
|
|
87
|
-
"@babel/plugin-external-helpers": "^7.
|
|
88
|
-
"@babel/plugin-proposal-class-properties": "^7.
|
|
89
|
-
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.
|
|
90
|
-
"@babel/plugin-proposal-object-rest-spread": "^7.
|
|
91
|
-
"@babel/plugin-proposal-optional-chaining": "^7.
|
|
92
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
93
|
-
"@babel/preset-env": "^7.
|
|
94
|
-
"@babel/preset-typescript": "^7.
|
|
95
|
-
"@babel/register": "^7.
|
|
88
|
+
"@babel/cli": "^7.16.0",
|
|
89
|
+
"@babel/core": "^7.16.0",
|
|
90
|
+
"@babel/node": "^7.16.0",
|
|
91
|
+
"@babel/plugin-external-helpers": "^7.16.0",
|
|
92
|
+
"@babel/plugin-proposal-class-properties": "^7.16.0",
|
|
93
|
+
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0",
|
|
94
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.16.0",
|
|
95
|
+
"@babel/plugin-proposal-optional-chaining": "^7.16.0",
|
|
96
|
+
"@babel/plugin-transform-runtime": "^7.16.0",
|
|
97
|
+
"@babel/preset-env": "^7.16.0",
|
|
98
|
+
"@babel/preset-typescript": "^7.16.0",
|
|
99
|
+
"@babel/register": "^7.16.0",
|
|
100
|
+
"@istanbuljs/esm-loader-hook": "^0.1.2",
|
|
96
101
|
"@rollup/plugin-babel": "^5.3.0",
|
|
97
|
-
"@rollup/plugin-commonjs": "^
|
|
98
|
-
"@rollup/plugin-node-resolve": "^13.0.
|
|
99
|
-
"@rollup/plugin-strip": "^2.0
|
|
100
|
-
"@rollup/plugin-typescript": "^8.
|
|
102
|
+
"@rollup/plugin-commonjs": "^21.0.1",
|
|
103
|
+
"@rollup/plugin-node-resolve": "^13.0.6",
|
|
104
|
+
"@rollup/plugin-strip": "^2.1.0",
|
|
105
|
+
"@rollup/plugin-typescript": "^8.3.0",
|
|
101
106
|
"@types/lodash.isplainobject": "^4.0.6",
|
|
102
|
-
"@types/node": "^
|
|
103
|
-
"@types/tap": "^15.0.
|
|
104
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
105
|
-
"@typescript-eslint/parser": "^
|
|
106
|
-
"core-js": "^3.
|
|
107
|
+
"@types/node": "^16.11.6",
|
|
108
|
+
"@types/tap": "^15.0.5",
|
|
109
|
+
"@typescript-eslint/eslint-plugin": "^5.2.0",
|
|
110
|
+
"@typescript-eslint/parser": "^5.2.0",
|
|
111
|
+
"core-js": "^3.19.0",
|
|
107
112
|
"cross-env": "^7.0.3",
|
|
108
|
-
"eslint": "^
|
|
109
|
-
"lect": "^0.
|
|
110
|
-
"rollup": "^2.
|
|
113
|
+
"eslint": "^8.1.0",
|
|
114
|
+
"lect": "^0.18.3",
|
|
115
|
+
"rollup": "^2.59.0",
|
|
111
116
|
"rollup-plugin-ascii": "^0.0.3",
|
|
112
117
|
"rollup-plugin-banner": "^0.2.1",
|
|
113
118
|
"rollup-plugin-cleanup": "^3.2.1",
|
|
114
|
-
"rollup-plugin-dts": "^
|
|
119
|
+
"rollup-plugin-dts": "^4.0.0",
|
|
115
120
|
"rollup-plugin-terser": "^7.0.2",
|
|
116
|
-
"tap": "^
|
|
117
|
-
"tslib": "^2.
|
|
118
|
-
"typescript": "^4.
|
|
121
|
+
"tap": "^15.0.10",
|
|
122
|
+
"tslib": "^2.3.1",
|
|
123
|
+
"typescript": "^4.4.4"
|
|
124
|
+
},
|
|
125
|
+
"engines": {
|
|
126
|
+
"node": ">=12"
|
|
119
127
|
}
|
|
120
128
|
}
|
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @name string-match-left-right
|
|
3
|
-
* @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
|
|
4
|
-
* @version 7.1.0
|
|
5
|
-
* @author Roy Revelt, Codsen Ltd
|
|
6
|
-
* @license MIT
|
|
7
|
-
* {@link https://codsen.com/os/string-match-left-right/}
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
'use strict';
|
|
11
|
-
|
|
12
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
13
|
-
|
|
14
|
-
var _objectSpread = require('@babel/runtime/helpers/objectSpread2');
|
|
15
|
-
var _typeof = require('@babel/runtime/helpers/typeof');
|
|
16
|
-
var arrayiffyIfString = require('arrayiffy-if-string');
|
|
17
|
-
|
|
18
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
19
|
-
|
|
20
|
-
var _objectSpread__default = /*#__PURE__*/_interopDefaultLegacy(_objectSpread);
|
|
21
|
-
var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
|
|
22
|
-
|
|
23
|
-
function isObj(something) {
|
|
24
|
-
return something && _typeof__default['default'](something) === "object" && !Array.isArray(something);
|
|
25
|
-
}
|
|
26
|
-
function isStr(something) {
|
|
27
|
-
return typeof something === "string";
|
|
28
|
-
}
|
|
29
|
-
var defaults = {
|
|
30
|
-
cb: undefined,
|
|
31
|
-
i: false,
|
|
32
|
-
trimBeforeMatching: false,
|
|
33
|
-
trimCharsBeforeMatching: [],
|
|
34
|
-
maxMismatches: 0,
|
|
35
|
-
firstMustMatch: false,
|
|
36
|
-
lastMustMatch: false,
|
|
37
|
-
hungry: false
|
|
38
|
-
};
|
|
39
|
-
var defaultGetNextIdx = function defaultGetNextIdx(index) {
|
|
40
|
-
return index + 1;
|
|
41
|
-
};
|
|
42
|
-
function march(str, position, whatToMatchVal, originalOpts) {
|
|
43
|
-
var special = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
44
|
-
var getNextIdx = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : defaultGetNextIdx;
|
|
45
|
-
var whatToMatchValVal = typeof whatToMatchVal === "function" ? whatToMatchVal() : whatToMatchVal;
|
|
46
|
-
if (+position < 0 && special && whatToMatchValVal === "EOL") {
|
|
47
|
-
return whatToMatchValVal;
|
|
48
|
-
}
|
|
49
|
-
var opts = _objectSpread__default['default'](_objectSpread__default['default']({}, defaults), originalOpts);
|
|
50
|
-
if (position >= str.length && !special) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
var charsToCheckCount = special ? 1 : whatToMatchVal.length;
|
|
54
|
-
var charsMatchedTotal = 0;
|
|
55
|
-
var patienceReducedBeforeFirstMatch = false;
|
|
56
|
-
var lastWasMismatched = false;
|
|
57
|
-
var atLeastSomethingWasMatched = false;
|
|
58
|
-
var patience = opts.maxMismatches;
|
|
59
|
-
var i = position;
|
|
60
|
-
var somethingFound = false;
|
|
61
|
-
var firstCharacterMatched = false;
|
|
62
|
-
var lastCharacterMatched = false;
|
|
63
|
-
function whitespaceInFrontOfFirstChar() {
|
|
64
|
-
return (
|
|
65
|
-
charsMatchedTotal === 1 &&
|
|
66
|
-
patience < opts.maxMismatches - 1
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
while (str[i]) {
|
|
70
|
-
var nextIdx = getNextIdx(i);
|
|
71
|
-
if (opts.trimBeforeMatching && str[i].trim() === "") {
|
|
72
|
-
if (!str[nextIdx] && special && whatToMatchVal === "EOL") {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
i = getNextIdx(i);
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (opts && !opts.i && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.includes(str[i]) || opts && opts.i && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.map(function (val) {
|
|
79
|
-
return val.toLowerCase();
|
|
80
|
-
}).includes(str[i].toLowerCase())) {
|
|
81
|
-
if (special && whatToMatchVal === "EOL" && !str[nextIdx]) {
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
|
-
i = getNextIdx(i);
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
var charToCompareAgainst = nextIdx > i ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount] : whatToMatchVal[charsToCheckCount - 1];
|
|
88
|
-
if (!opts.i && str[i] === charToCompareAgainst || opts.i && str[i].toLowerCase() === charToCompareAgainst.toLowerCase()) {
|
|
89
|
-
if (!somethingFound) {
|
|
90
|
-
somethingFound = true;
|
|
91
|
-
}
|
|
92
|
-
if (!atLeastSomethingWasMatched) {
|
|
93
|
-
atLeastSomethingWasMatched = true;
|
|
94
|
-
}
|
|
95
|
-
if (charsToCheckCount === whatToMatchVal.length) {
|
|
96
|
-
firstCharacterMatched = true;
|
|
97
|
-
if (patience !== opts.maxMismatches) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
} else if (charsToCheckCount === 1) {
|
|
101
|
-
lastCharacterMatched = true;
|
|
102
|
-
}
|
|
103
|
-
charsToCheckCount -= 1;
|
|
104
|
-
charsMatchedTotal++;
|
|
105
|
-
if (whitespaceInFrontOfFirstChar()) {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
if (!charsToCheckCount) {
|
|
109
|
-
return (
|
|
110
|
-
charsMatchedTotal !== whatToMatchVal.length ||
|
|
111
|
-
patience === opts.maxMismatches ||
|
|
112
|
-
!patienceReducedBeforeFirstMatch ? i : false
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
} else {
|
|
116
|
-
if (!patienceReducedBeforeFirstMatch && !charsMatchedTotal) {
|
|
117
|
-
patienceReducedBeforeFirstMatch = true;
|
|
118
|
-
}
|
|
119
|
-
if (opts.maxMismatches && patience && i) {
|
|
120
|
-
patience -= 1;
|
|
121
|
-
for (var y = 0; y <= patience; y++) {
|
|
122
|
-
var nextCharToCompareAgainst = nextIdx > i ? whatToMatchVal[whatToMatchVal.length - charsToCheckCount + 1 + y] : whatToMatchVal[charsToCheckCount - 2 - y];
|
|
123
|
-
var nextCharInSource = str[getNextIdx(i)];
|
|
124
|
-
if (nextCharToCompareAgainst && (!opts.i && str[i] === nextCharToCompareAgainst || opts.i && str[i].toLowerCase() === nextCharToCompareAgainst.toLowerCase()) && (
|
|
125
|
-
!opts.firstMustMatch || charsToCheckCount !== whatToMatchVal.length)) {
|
|
126
|
-
charsMatchedTotal++;
|
|
127
|
-
if (whitespaceInFrontOfFirstChar()) {
|
|
128
|
-
return false;
|
|
129
|
-
}
|
|
130
|
-
charsToCheckCount -= 2;
|
|
131
|
-
somethingFound = true;
|
|
132
|
-
break;
|
|
133
|
-
} else if (nextCharInSource && nextCharToCompareAgainst && (!opts.i && nextCharInSource === nextCharToCompareAgainst || opts.i && nextCharInSource.toLowerCase() === nextCharToCompareAgainst.toLowerCase()) && (
|
|
134
|
-
!opts.firstMustMatch || charsToCheckCount !== whatToMatchVal.length)) {
|
|
135
|
-
if (!charsMatchedTotal && !opts.hungry) {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
charsToCheckCount -= 1;
|
|
139
|
-
somethingFound = true;
|
|
140
|
-
break;
|
|
141
|
-
} else if (nextCharToCompareAgainst === undefined && patience >= 0 && somethingFound && (!opts.firstMustMatch || firstCharacterMatched) && (!opts.lastMustMatch || lastCharacterMatched)) {
|
|
142
|
-
return i;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (!somethingFound) {
|
|
146
|
-
lastWasMismatched = i;
|
|
147
|
-
}
|
|
148
|
-
} else if (i === 0 && charsToCheckCount === 1 && !opts.lastMustMatch && atLeastSomethingWasMatched) {
|
|
149
|
-
return 0;
|
|
150
|
-
} else {
|
|
151
|
-
return false;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (lastWasMismatched !== false && lastWasMismatched !== i) {
|
|
155
|
-
lastWasMismatched = false;
|
|
156
|
-
}
|
|
157
|
-
if (charsToCheckCount < 1) {
|
|
158
|
-
return i;
|
|
159
|
-
}
|
|
160
|
-
i = getNextIdx(i);
|
|
161
|
-
}
|
|
162
|
-
if (charsToCheckCount > 0) {
|
|
163
|
-
if (special && whatToMatchValVal === "EOL") {
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
if (opts && opts.maxMismatches >= charsToCheckCount && atLeastSomethingWasMatched) {
|
|
167
|
-
return lastWasMismatched || 0;
|
|
168
|
-
}
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function main(mode, str, position, originalWhatToMatch, originalOpts) {
|
|
173
|
-
if (isObj(originalOpts) && Object.prototype.hasOwnProperty.call(originalOpts, "trimBeforeMatching") && typeof originalOpts.trimBeforeMatching !== "boolean") {
|
|
174
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_09] opts.trimBeforeMatching should be boolean!").concat(Array.isArray(originalOpts.trimBeforeMatching) ? " Did you mean to use opts.trimCharsBeforeMatching?" : ""));
|
|
175
|
-
}
|
|
176
|
-
var opts = _objectSpread__default['default'](_objectSpread__default['default']({}, defaults), originalOpts);
|
|
177
|
-
if (typeof opts.trimCharsBeforeMatching === "string") {
|
|
178
|
-
opts.trimCharsBeforeMatching = arrayiffyIfString.arrayiffy(opts.trimCharsBeforeMatching);
|
|
179
|
-
}
|
|
180
|
-
opts.trimCharsBeforeMatching = opts.trimCharsBeforeMatching.map(function (el) {
|
|
181
|
-
return isStr(el) ? el : String(el);
|
|
182
|
-
});
|
|
183
|
-
if (!isStr(str)) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
if (!str.length) {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
if (!Number.isInteger(position) || position < 0) {
|
|
190
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_03] the second argument should be a natural number. Currently it's of a type: ").concat(_typeof__default['default'](position), ", equal to:\n").concat(JSON.stringify(position, null, 4)));
|
|
191
|
-
}
|
|
192
|
-
var whatToMatch;
|
|
193
|
-
var special;
|
|
194
|
-
if (isStr(originalWhatToMatch)) {
|
|
195
|
-
whatToMatch = [originalWhatToMatch];
|
|
196
|
-
} else if (Array.isArray(originalWhatToMatch)) {
|
|
197
|
-
whatToMatch = originalWhatToMatch;
|
|
198
|
-
} else if (!originalWhatToMatch) {
|
|
199
|
-
whatToMatch = originalWhatToMatch;
|
|
200
|
-
} else if (typeof originalWhatToMatch === "function") {
|
|
201
|
-
whatToMatch = [];
|
|
202
|
-
whatToMatch.push(originalWhatToMatch);
|
|
203
|
-
} else {
|
|
204
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_05] the third argument, whatToMatch, is neither string nor array of strings! It's ").concat(_typeof__default['default'](originalWhatToMatch), ", equal to:\n").concat(JSON.stringify(originalWhatToMatch, null, 4)));
|
|
205
|
-
}
|
|
206
|
-
if (originalOpts && !isObj(originalOpts)) {
|
|
207
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_06] the fourth argument, options object, should be a plain object. Currently it's of a type \"").concat(_typeof__default['default'](originalOpts), "\", and equal to:\n").concat(JSON.stringify(originalOpts, null, 4)));
|
|
208
|
-
}
|
|
209
|
-
var culpritsIndex = 0;
|
|
210
|
-
var culpritsVal = "";
|
|
211
|
-
if (opts && opts.trimCharsBeforeMatching && opts.trimCharsBeforeMatching.some(function (el, i) {
|
|
212
|
-
if (el.length > 1) {
|
|
213
|
-
culpritsIndex = i;
|
|
214
|
-
culpritsVal = el;
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
return false;
|
|
218
|
-
})) {
|
|
219
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_07] the fourth argument, options object contains trimCharsBeforeMatching. It was meant to list the single characters but one of the entries at index ").concat(culpritsIndex, " is longer than 1 character, ").concat(culpritsVal.length, " (equals to ").concat(culpritsVal, "). Please split it into separate characters and put into array as separate elements."));
|
|
220
|
-
}
|
|
221
|
-
if (!whatToMatch || !Array.isArray(whatToMatch) ||
|
|
222
|
-
Array.isArray(whatToMatch) && !whatToMatch.length ||
|
|
223
|
-
Array.isArray(whatToMatch) && whatToMatch.length === 1 && isStr(whatToMatch[0]) && !whatToMatch[0].trim()
|
|
224
|
-
) {
|
|
225
|
-
if (typeof opts.cb === "function") {
|
|
226
|
-
var firstCharOutsideIndex;
|
|
227
|
-
var startingPosition = position;
|
|
228
|
-
if (mode === "matchLeftIncl" || mode === "matchRight") {
|
|
229
|
-
startingPosition += 1;
|
|
230
|
-
}
|
|
231
|
-
if (mode[5] === "L") {
|
|
232
|
-
for (var y = startingPosition; y--;) {
|
|
233
|
-
var currentChar = str[y];
|
|
234
|
-
if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && currentChar !== undefined && currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || currentChar !== undefined && !opts.trimCharsBeforeMatching.includes(currentChar))) {
|
|
235
|
-
firstCharOutsideIndex = y;
|
|
236
|
-
break;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
} else if (mode.startsWith("matchRight")) {
|
|
240
|
-
for (var _y = startingPosition; _y < str.length; _y++) {
|
|
241
|
-
var _currentChar = str[_y];
|
|
242
|
-
if ((!opts.trimBeforeMatching || opts.trimBeforeMatching && _currentChar.trim()) && (!opts.trimCharsBeforeMatching || !opts.trimCharsBeforeMatching.length || !opts.trimCharsBeforeMatching.includes(_currentChar))) {
|
|
243
|
-
firstCharOutsideIndex = _y;
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (firstCharOutsideIndex === undefined) {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
var wholeCharacterOutside = str[firstCharOutsideIndex];
|
|
252
|
-
var indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
|
|
253
|
-
var theRemainderOfTheString = "";
|
|
254
|
-
if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
|
|
255
|
-
theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
|
|
256
|
-
}
|
|
257
|
-
if (mode[5] === "L") {
|
|
258
|
-
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
259
|
-
}
|
|
260
|
-
if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
|
|
261
|
-
theRemainderOfTheString = str.slice(firstCharOutsideIndex);
|
|
262
|
-
}
|
|
263
|
-
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
264
|
-
}
|
|
265
|
-
var extraNote = "";
|
|
266
|
-
if (!originalOpts) {
|
|
267
|
-
extraNote = " More so, the whole options object, the fourth input argument, is missing!";
|
|
268
|
-
}
|
|
269
|
-
throw new Error("string-match-left-right/".concat(mode, "(): [THROW_ID_08] the third argument, \"whatToMatch\", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key \"cb\" is not set!").concat(extraNote));
|
|
270
|
-
}
|
|
271
|
-
for (var i = 0, len = whatToMatch.length; i < len; i++) {
|
|
272
|
-
special = typeof whatToMatch[i] === "function";
|
|
273
|
-
var whatToMatchVal = whatToMatch[i];
|
|
274
|
-
var fullCharacterInFront = void 0;
|
|
275
|
-
var indexOfTheCharacterInFront = void 0;
|
|
276
|
-
var restOfStringInFront = "";
|
|
277
|
-
var _startingPosition = position;
|
|
278
|
-
if (mode === "matchRight") {
|
|
279
|
-
_startingPosition += 1;
|
|
280
|
-
} else if (mode === "matchLeft") {
|
|
281
|
-
_startingPosition -= 1;
|
|
282
|
-
}
|
|
283
|
-
var found = march(str, _startingPosition, whatToMatchVal, opts, special, function (i2) {
|
|
284
|
-
return mode[5] === "L" ? i2 - 1 : i2 + 1;
|
|
285
|
-
});
|
|
286
|
-
if (found && special && typeof whatToMatchVal === "function" && whatToMatchVal() === "EOL") {
|
|
287
|
-
return whatToMatchVal() && (opts.cb ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront) : true) ? whatToMatchVal() : false;
|
|
288
|
-
}
|
|
289
|
-
if (Number.isInteger(found)) {
|
|
290
|
-
indexOfTheCharacterInFront = mode.startsWith("matchLeft") ? found - 1 : found + 1;
|
|
291
|
-
if (mode[5] === "L") {
|
|
292
|
-
restOfStringInFront = str.slice(0, found);
|
|
293
|
-
} else {
|
|
294
|
-
restOfStringInFront = str.slice(indexOfTheCharacterInFront);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (indexOfTheCharacterInFront < 0) {
|
|
298
|
-
indexOfTheCharacterInFront = undefined;
|
|
299
|
-
}
|
|
300
|
-
if (str[indexOfTheCharacterInFront]) {
|
|
301
|
-
fullCharacterInFront = str[indexOfTheCharacterInFront];
|
|
302
|
-
}
|
|
303
|
-
if (Number.isInteger(found) && (opts.cb ? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront) : true)) {
|
|
304
|
-
return whatToMatchVal;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return false;
|
|
308
|
-
}
|
|
309
|
-
function matchLeftIncl(str, position, whatToMatch, opts) {
|
|
310
|
-
return main("matchLeftIncl", str, position, whatToMatch, opts);
|
|
311
|
-
}
|
|
312
|
-
function matchLeft(str, position, whatToMatch, opts) {
|
|
313
|
-
return main("matchLeft", str, position, whatToMatch, opts);
|
|
314
|
-
}
|
|
315
|
-
function matchRightIncl(str, position, whatToMatch, opts) {
|
|
316
|
-
return main("matchRightIncl", str, position, whatToMatch, opts);
|
|
317
|
-
}
|
|
318
|
-
function matchRight(str, position, whatToMatch, opts) {
|
|
319
|
-
return main("matchRight", str, position, whatToMatch, opts);
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
exports.matchLeft = matchLeft;
|
|
323
|
-
exports.matchLeftIncl = matchLeftIncl;
|
|
324
|
-
exports.matchRight = matchRight;
|
|
325
|
-
exports.matchRightIncl = matchRightIncl;
|
|
@@ -1,558 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @name string-match-left-right
|
|
3
|
-
* @fileoverview Match substrings on the left or right of a given index, ignoring whitespace
|
|
4
|
-
* @version 7.1.0
|
|
5
|
-
* @author Roy Revelt, Codsen Ltd
|
|
6
|
-
* @license MIT
|
|
7
|
-
* {@link https://codsen.com/os/string-match-left-right/}
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
(function (global, factory) {
|
|
11
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
12
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
13
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.stringMatchLeftRight = {}));
|
|
14
|
-
}(this, (function (exports) { 'use strict';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @name arrayiffy-if-string
|
|
18
|
-
* @fileoverview Put non-empty strings into arrays, turn empty-ones into empty arrays. Bypass everything else.
|
|
19
|
-
* @version 3.14.0
|
|
20
|
-
* @author Roy Revelt, Codsen Ltd
|
|
21
|
-
* @license MIT
|
|
22
|
-
* {@link https://codsen.com/os/arrayiffy-if-string/}
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
function arrayiffy(something) {
|
|
26
|
-
if (typeof something === "string") {
|
|
27
|
-
if (something.length) {
|
|
28
|
-
return [something];
|
|
29
|
-
}
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
32
|
-
return something;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/* eslint no-plusplus:0 */
|
|
36
|
-
function isObj(something) {
|
|
37
|
-
return (something && typeof something === "object" && !Array.isArray(something));
|
|
38
|
-
}
|
|
39
|
-
function isStr(something) {
|
|
40
|
-
return typeof something === "string";
|
|
41
|
-
}
|
|
42
|
-
const defaults = {
|
|
43
|
-
cb: undefined,
|
|
44
|
-
i: false,
|
|
45
|
-
trimBeforeMatching: false,
|
|
46
|
-
trimCharsBeforeMatching: [],
|
|
47
|
-
maxMismatches: 0,
|
|
48
|
-
firstMustMatch: false,
|
|
49
|
-
lastMustMatch: false,
|
|
50
|
-
hungry: false,
|
|
51
|
-
};
|
|
52
|
-
const defaultGetNextIdx = (index) => index + 1;
|
|
53
|
-
// eslint-disable-next-line consistent-return
|
|
54
|
-
function march(str, position, whatToMatchVal, originalOpts, special = false, getNextIdx = defaultGetNextIdx) {
|
|
55
|
-
const whatToMatchValVal = typeof whatToMatchVal === "function" ? whatToMatchVal() : whatToMatchVal;
|
|
56
|
-
// early ending case if matching EOL being at 0-th index:
|
|
57
|
-
if (+position < 0 && special && whatToMatchValVal === "EOL") {
|
|
58
|
-
return whatToMatchValVal;
|
|
59
|
-
}
|
|
60
|
-
const opts = { ...defaults, ...originalOpts };
|
|
61
|
-
if (position >= str.length && !special) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
// The "charsToCheckCount" varies, it decreases with skipped characters,
|
|
65
|
-
// as long as "maxMismatches" allows. It's not the count of how many
|
|
66
|
-
// characters de-facto have been matched from the source.
|
|
67
|
-
let charsToCheckCount = special ? 1 : whatToMatchVal.length;
|
|
68
|
-
// this is the counter of real characters matched. It is not reduced
|
|
69
|
-
// from the holes in matched. For example, if source is "abc" and
|
|
70
|
-
// maxMismatches=1 and we have "ac", result of the match will be true,
|
|
71
|
-
// the following var will be equal to 2, meaning we matched two
|
|
72
|
-
// characters:
|
|
73
|
-
let charsMatchedTotal = 0;
|
|
74
|
-
// used to catch frontal false positives, where too-eager matching
|
|
75
|
-
// depletes the mismatches allowance before precisely matching the exact
|
|
76
|
-
// string that follows, yielding too early false-positive start
|
|
77
|
-
let patienceReducedBeforeFirstMatch = false;
|
|
78
|
-
let lastWasMismatched = false; // value is "false" or index of where it was activated
|
|
79
|
-
// if no character was ever matched, even through if opts.maxMismatches
|
|
80
|
-
// would otherwise allow to skip characters, this will act as a last
|
|
81
|
-
// insurance - at least one character must have been matched to yield a
|
|
82
|
-
// positive result!
|
|
83
|
-
let atLeastSomethingWasMatched = false;
|
|
84
|
-
let patience = opts.maxMismatches;
|
|
85
|
-
let i = position;
|
|
86
|
-
// internal-use flag, not the same as "atLeastSomethingWasMatched":
|
|
87
|
-
let somethingFound = false;
|
|
88
|
-
// these two drive opts.firstMustMatch and opts.lastMustMatch:
|
|
89
|
-
let firstCharacterMatched = false;
|
|
90
|
-
let lastCharacterMatched = false;
|
|
91
|
-
// bail early if there's whitespace in front, imagine:
|
|
92
|
-
// abc important}
|
|
93
|
-
// ^
|
|
94
|
-
// start, match ["!important"], matchRightIncl()
|
|
95
|
-
//
|
|
96
|
-
// in case above, "c" consumed 1 patience, let's say 1 is left,
|
|
97
|
-
// we stumble upon "i" where "!" is missing. "c" is false start.
|
|
98
|
-
function whitespaceInFrontOfFirstChar() {
|
|
99
|
-
return (
|
|
100
|
-
// it's a first letter match
|
|
101
|
-
charsMatchedTotal === 1 &&
|
|
102
|
-
// and character in front exists
|
|
103
|
-
// str[i - 1] &&
|
|
104
|
-
// and it's whitespace
|
|
105
|
-
// !str[i - 1].trim() &&
|
|
106
|
-
// some patience has been consumed already
|
|
107
|
-
patience < opts.maxMismatches - 1);
|
|
108
|
-
}
|
|
109
|
-
while (str[i]) {
|
|
110
|
-
const nextIdx = getNextIdx(i);
|
|
111
|
-
if (opts.trimBeforeMatching && str[i].trim() === "") {
|
|
112
|
-
if (!str[nextIdx] && special && whatToMatchVal === "EOL") {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
i = getNextIdx(i);
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
if ((opts &&
|
|
119
|
-
!opts.i &&
|
|
120
|
-
opts.trimCharsBeforeMatching &&
|
|
121
|
-
opts.trimCharsBeforeMatching.includes(str[i])) ||
|
|
122
|
-
(opts &&
|
|
123
|
-
opts.i &&
|
|
124
|
-
opts.trimCharsBeforeMatching &&
|
|
125
|
-
opts.trimCharsBeforeMatching
|
|
126
|
-
.map((val) => val.toLowerCase())
|
|
127
|
-
.includes(str[i].toLowerCase()))) {
|
|
128
|
-
if (special && whatToMatchVal === "EOL" && !str[nextIdx]) {
|
|
129
|
-
// return true because we reached the zero'th index, exactly what we're looking for
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
i = getNextIdx(i);
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
const charToCompareAgainst = nextIdx > i
|
|
136
|
-
? whatToMatchVal[whatToMatchVal.length - charsToCheckCount]
|
|
137
|
-
: whatToMatchVal[charsToCheckCount - 1];
|
|
138
|
-
// let's match
|
|
139
|
-
if ((!opts.i && str[i] === charToCompareAgainst) ||
|
|
140
|
-
(opts.i && str[i].toLowerCase() === charToCompareAgainst.toLowerCase())) {
|
|
141
|
-
if (!somethingFound) {
|
|
142
|
-
somethingFound = true;
|
|
143
|
-
}
|
|
144
|
-
if (!atLeastSomethingWasMatched) {
|
|
145
|
-
atLeastSomethingWasMatched = true;
|
|
146
|
-
}
|
|
147
|
-
// if this was the first character from the "to-match" list, flip the flag
|
|
148
|
-
if (charsToCheckCount === whatToMatchVal.length) {
|
|
149
|
-
firstCharacterMatched = true;
|
|
150
|
-
// now, if the first character was matched and yet, patience was
|
|
151
|
-
// reduced already, this means there's a false beginning in front
|
|
152
|
-
if (patience !== opts.maxMismatches) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
else if (charsToCheckCount === 1) {
|
|
157
|
-
lastCharacterMatched = true;
|
|
158
|
-
}
|
|
159
|
-
charsToCheckCount -= 1;
|
|
160
|
-
charsMatchedTotal++;
|
|
161
|
-
// bail early if there's whitespace in front, imagine:
|
|
162
|
-
// abc important}
|
|
163
|
-
// ^
|
|
164
|
-
// start, match ["!important"], matchRightIncl()
|
|
165
|
-
//
|
|
166
|
-
// in case above, "c" consumed 1 patience, let's say 1 is left,
|
|
167
|
-
// we stumble upon "i" where "!" is missing. "c" is false start.
|
|
168
|
-
if (whitespaceInFrontOfFirstChar()) {
|
|
169
|
-
return false;
|
|
170
|
-
}
|
|
171
|
-
if (!charsToCheckCount) {
|
|
172
|
-
return (
|
|
173
|
-
// either it was not a perfect match
|
|
174
|
-
charsMatchedTotal !== whatToMatchVal.length ||
|
|
175
|
-
// or it was, and in that case, no patience was reduced
|
|
176
|
-
// (if a perfect match was found, yet some "patience" was reduced,
|
|
177
|
-
// that means we have false positive characters)
|
|
178
|
-
patience === opts.maxMismatches ||
|
|
179
|
-
// mind you, it can be a case of rogue characters in-between
|
|
180
|
-
// the what was matched, imagine:
|
|
181
|
-
// source: "abxcd", matching ["bc"], maxMismatches=1
|
|
182
|
-
// in above case, charsMatchedTotal === 2 and whatToMatchVal ("bc") === 2
|
|
183
|
-
// - we want to exclude cases of frontal false positives, like:
|
|
184
|
-
// source: "xy abc", match "abc", maxMismatches=2, start at 0
|
|
185
|
-
// ^
|
|
186
|
-
// match form here to the right
|
|
187
|
-
!patienceReducedBeforeFirstMatch
|
|
188
|
-
? i
|
|
189
|
-
: false);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
if (!patienceReducedBeforeFirstMatch && !charsMatchedTotal) {
|
|
194
|
-
patienceReducedBeforeFirstMatch = true;
|
|
195
|
-
}
|
|
196
|
-
if (opts.maxMismatches && patience && i) {
|
|
197
|
-
patience -= 1;
|
|
198
|
-
// the bigger the maxMismatches, the further away we must check for
|
|
199
|
-
// alternative matches
|
|
200
|
-
for (let y = 0; y <= patience; y++) {
|
|
201
|
-
// maybe str[i] will match against next charToCompareAgainst?
|
|
202
|
-
const nextCharToCompareAgainst = nextIdx > i
|
|
203
|
-
? whatToMatchVal[whatToMatchVal.length - charsToCheckCount + 1 + y]
|
|
204
|
-
: whatToMatchVal[charsToCheckCount - 2 - y];
|
|
205
|
-
const nextCharInSource = str[getNextIdx(i)];
|
|
206
|
-
if (nextCharToCompareAgainst &&
|
|
207
|
-
((!opts.i && str[i] === nextCharToCompareAgainst) ||
|
|
208
|
-
(opts.i &&
|
|
209
|
-
str[i].toLowerCase() ===
|
|
210
|
-
nextCharToCompareAgainst.toLowerCase())) &&
|
|
211
|
-
// ensure we're not skipping the first enforced character:
|
|
212
|
-
(!opts.firstMustMatch ||
|
|
213
|
-
charsToCheckCount !== whatToMatchVal.length)) {
|
|
214
|
-
charsMatchedTotal++;
|
|
215
|
-
// bail early if there's whitespace in front, imagine:
|
|
216
|
-
// abc important}
|
|
217
|
-
// ^
|
|
218
|
-
// start, match ["!important"], matchRightIncl()
|
|
219
|
-
//
|
|
220
|
-
// in case above, "c" consumed 1 patience, let's say 1 is left,
|
|
221
|
-
// we stumble upon "i" where "!" is missing. "c" is false start.
|
|
222
|
-
if (whitespaceInFrontOfFirstChar()) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
charsToCheckCount -= 2;
|
|
226
|
-
somethingFound = true;
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
else if (nextCharInSource &&
|
|
230
|
-
nextCharToCompareAgainst &&
|
|
231
|
-
((!opts.i && nextCharInSource === nextCharToCompareAgainst) ||
|
|
232
|
-
(opts.i &&
|
|
233
|
-
nextCharInSource.toLowerCase() ===
|
|
234
|
-
nextCharToCompareAgainst.toLowerCase())) &&
|
|
235
|
-
// ensure we're not skipping the first enforced character:
|
|
236
|
-
(!opts.firstMustMatch ||
|
|
237
|
-
charsToCheckCount !== whatToMatchVal.length)) {
|
|
238
|
-
if (!charsMatchedTotal && !opts.hungry) {
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
charsToCheckCount -= 1;
|
|
242
|
-
somethingFound = true;
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
else if (nextCharToCompareAgainst === undefined &&
|
|
246
|
-
patience >= 0 &&
|
|
247
|
-
somethingFound &&
|
|
248
|
-
(!opts.firstMustMatch || firstCharacterMatched) &&
|
|
249
|
-
(!opts.lastMustMatch || lastCharacterMatched)) {
|
|
250
|
-
// If "nextCharToCompareAgainst" is undefined, this
|
|
251
|
-
// means there are no more characters left to match,
|
|
252
|
-
// this is the last character to be matched.
|
|
253
|
-
// This means, if patience >= 0, this is it,
|
|
254
|
-
// the match is still positive.
|
|
255
|
-
return i;
|
|
256
|
-
}
|
|
257
|
-
// ███████████████████████████████████████
|
|
258
|
-
}
|
|
259
|
-
if (!somethingFound) {
|
|
260
|
-
// if the character was rogue, we mark it:
|
|
261
|
-
lastWasMismatched = i;
|
|
262
|
-
// patience--;
|
|
263
|
-
// console.log(
|
|
264
|
-
// `350 ${`\u001b[${32}m${`SET`}\u001b[${39}m`} ${`\u001b[${33}m${`patience`}\u001b[${39}m`} = ${patience}`
|
|
265
|
-
// );
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else if (i === 0 &&
|
|
269
|
-
charsToCheckCount === 1 &&
|
|
270
|
-
!opts.lastMustMatch &&
|
|
271
|
-
atLeastSomethingWasMatched) {
|
|
272
|
-
return 0;
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
// turn off "lastWasMismatched" if it's on and it hasn't been activated
|
|
279
|
-
// on this current index:
|
|
280
|
-
if (lastWasMismatched !== false && lastWasMismatched !== i) {
|
|
281
|
-
lastWasMismatched = false;
|
|
282
|
-
}
|
|
283
|
-
// if all was matched, happy days
|
|
284
|
-
if (charsToCheckCount < 1) {
|
|
285
|
-
return i;
|
|
286
|
-
}
|
|
287
|
-
// iterate onto the next index, otherwise while would loop infinitely
|
|
288
|
-
i = getNextIdx(i);
|
|
289
|
-
}
|
|
290
|
-
if (charsToCheckCount > 0) {
|
|
291
|
-
if (special && whatToMatchValVal === "EOL") {
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
if (opts &&
|
|
295
|
-
opts.maxMismatches >= charsToCheckCount &&
|
|
296
|
-
atLeastSomethingWasMatched) {
|
|
297
|
-
return lastWasMismatched || 0;
|
|
298
|
-
}
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
//
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
//
|
|
319
|
-
//
|
|
320
|
-
//
|
|
321
|
-
//
|
|
322
|
-
//
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
//
|
|
328
|
-
//
|
|
329
|
-
//
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
//
|
|
335
|
-
//
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
// Real deal
|
|
339
|
-
function main(mode, str, position, originalWhatToMatch, originalOpts) {
|
|
340
|
-
// insurance
|
|
341
|
-
if (isObj(originalOpts) &&
|
|
342
|
-
Object.prototype.hasOwnProperty.call(originalOpts, "trimBeforeMatching") &&
|
|
343
|
-
typeof originalOpts.trimBeforeMatching !== "boolean") {
|
|
344
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_09] opts.trimBeforeMatching should be boolean!${Array.isArray(originalOpts.trimBeforeMatching)
|
|
345
|
-
? ` Did you mean to use opts.trimCharsBeforeMatching?`
|
|
346
|
-
: ""}`);
|
|
347
|
-
}
|
|
348
|
-
const opts = { ...defaults, ...originalOpts };
|
|
349
|
-
if (typeof opts.trimCharsBeforeMatching === "string") {
|
|
350
|
-
// arrayiffy if needed:
|
|
351
|
-
opts.trimCharsBeforeMatching = arrayiffy(opts.trimCharsBeforeMatching);
|
|
352
|
-
}
|
|
353
|
-
// stringify all:
|
|
354
|
-
opts.trimCharsBeforeMatching = opts.trimCharsBeforeMatching.map((el) => (isStr(el) ? el : String(el)));
|
|
355
|
-
if (!isStr(str)) {
|
|
356
|
-
return false;
|
|
357
|
-
}
|
|
358
|
-
if (!str.length) {
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
if (!Number.isInteger(position) || position < 0) {
|
|
362
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_03] the second argument should be a natural number. Currently it's of a type: ${typeof position}, equal to:\n${JSON.stringify(position, null, 4)}`);
|
|
363
|
-
}
|
|
364
|
-
let whatToMatch;
|
|
365
|
-
let special;
|
|
366
|
-
if (isStr(originalWhatToMatch)) {
|
|
367
|
-
whatToMatch = [originalWhatToMatch];
|
|
368
|
-
}
|
|
369
|
-
else if (Array.isArray(originalWhatToMatch)) {
|
|
370
|
-
whatToMatch = originalWhatToMatch;
|
|
371
|
-
}
|
|
372
|
-
else if (!originalWhatToMatch) {
|
|
373
|
-
whatToMatch = originalWhatToMatch;
|
|
374
|
-
}
|
|
375
|
-
else if (typeof originalWhatToMatch === "function") {
|
|
376
|
-
whatToMatch = [];
|
|
377
|
-
whatToMatch.push(originalWhatToMatch);
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_05] the third argument, whatToMatch, is neither string nor array of strings! It's ${typeof originalWhatToMatch}, equal to:\n${JSON.stringify(originalWhatToMatch, null, 4)}`);
|
|
381
|
-
}
|
|
382
|
-
if (originalOpts && !isObj(originalOpts)) {
|
|
383
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_06] the fourth argument, options object, should be a plain object. Currently it's of a type "${typeof originalOpts}", and equal to:\n${JSON.stringify(originalOpts, null, 4)}`);
|
|
384
|
-
}
|
|
385
|
-
let culpritsIndex = 0;
|
|
386
|
-
let culpritsVal = "";
|
|
387
|
-
if (opts &&
|
|
388
|
-
opts.trimCharsBeforeMatching &&
|
|
389
|
-
opts.trimCharsBeforeMatching.some((el, i) => {
|
|
390
|
-
if (el.length > 1) {
|
|
391
|
-
culpritsIndex = i;
|
|
392
|
-
culpritsVal = el;
|
|
393
|
-
return true;
|
|
394
|
-
}
|
|
395
|
-
return false;
|
|
396
|
-
})) {
|
|
397
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_07] the fourth argument, options object contains trimCharsBeforeMatching. It was meant to list the single characters but one of the entries at index ${culpritsIndex} is longer than 1 character, ${culpritsVal.length} (equals to ${culpritsVal}). Please split it into separate characters and put into array as separate elements.`);
|
|
398
|
-
}
|
|
399
|
-
// action
|
|
400
|
-
// CASE 1. If it's driven by callback-only, the 3rd input argument, what to look
|
|
401
|
-
// for - is falsey - empty string within array (or not), OR given null
|
|
402
|
-
if (!whatToMatch ||
|
|
403
|
-
!Array.isArray(whatToMatch) || // 0
|
|
404
|
-
(Array.isArray(whatToMatch) && !whatToMatch.length) || // []
|
|
405
|
-
(Array.isArray(whatToMatch) &&
|
|
406
|
-
whatToMatch.length === 1 &&
|
|
407
|
-
isStr(whatToMatch[0]) &&
|
|
408
|
-
!whatToMatch[0].trim()) // [""]
|
|
409
|
-
) {
|
|
410
|
-
if (typeof opts.cb === "function") {
|
|
411
|
-
let firstCharOutsideIndex;
|
|
412
|
-
// matchLeft() or matchRightIncl() methods start at index "position"
|
|
413
|
-
let startingPosition = position;
|
|
414
|
-
if (mode === "matchLeftIncl" || mode === "matchRight") {
|
|
415
|
-
startingPosition += 1;
|
|
416
|
-
}
|
|
417
|
-
if (mode[5] === "L") {
|
|
418
|
-
for (let y = startingPosition; y--;) {
|
|
419
|
-
// assemble the value of the current character
|
|
420
|
-
const currentChar = str[y];
|
|
421
|
-
// do the actual evaluation, is the current character non-whitespace/non-skiped
|
|
422
|
-
if ((!opts.trimBeforeMatching ||
|
|
423
|
-
(opts.trimBeforeMatching &&
|
|
424
|
-
currentChar !== undefined &&
|
|
425
|
-
currentChar.trim())) &&
|
|
426
|
-
(!opts.trimCharsBeforeMatching ||
|
|
427
|
-
!opts.trimCharsBeforeMatching.length ||
|
|
428
|
-
(currentChar !== undefined &&
|
|
429
|
-
!opts.trimCharsBeforeMatching.includes(currentChar)))) {
|
|
430
|
-
firstCharOutsideIndex = y;
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
else if (mode.startsWith("matchRight")) {
|
|
436
|
-
for (let y = startingPosition; y < str.length; y++) {
|
|
437
|
-
// assemble the value of the current character
|
|
438
|
-
const currentChar = str[y];
|
|
439
|
-
// do the actual evaluation, is the current character non-whitespace/non-skiped
|
|
440
|
-
if ((!opts.trimBeforeMatching ||
|
|
441
|
-
(opts.trimBeforeMatching && currentChar.trim())) &&
|
|
442
|
-
(!opts.trimCharsBeforeMatching ||
|
|
443
|
-
!opts.trimCharsBeforeMatching.length ||
|
|
444
|
-
!opts.trimCharsBeforeMatching.includes(currentChar))) {
|
|
445
|
-
firstCharOutsideIndex = y;
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
if (firstCharOutsideIndex === undefined) {
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
const wholeCharacterOutside = str[firstCharOutsideIndex];
|
|
454
|
-
const indexOfTheCharacterAfter = firstCharOutsideIndex + 1;
|
|
455
|
-
let theRemainderOfTheString = "";
|
|
456
|
-
if (indexOfTheCharacterAfter && indexOfTheCharacterAfter > 0) {
|
|
457
|
-
theRemainderOfTheString = str.slice(0, indexOfTheCharacterAfter);
|
|
458
|
-
}
|
|
459
|
-
if (mode[5] === "L") {
|
|
460
|
-
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
461
|
-
}
|
|
462
|
-
// ELSE matchRight & matchRightIncl
|
|
463
|
-
if (firstCharOutsideIndex && firstCharOutsideIndex > 0) {
|
|
464
|
-
theRemainderOfTheString = str.slice(firstCharOutsideIndex);
|
|
465
|
-
}
|
|
466
|
-
return opts.cb(wholeCharacterOutside, theRemainderOfTheString, firstCharOutsideIndex);
|
|
467
|
-
}
|
|
468
|
-
let extraNote = "";
|
|
469
|
-
if (!originalOpts) {
|
|
470
|
-
extraNote =
|
|
471
|
-
" More so, the whole options object, the fourth input argument, is missing!";
|
|
472
|
-
}
|
|
473
|
-
throw new Error(`string-match-left-right/${mode}(): [THROW_ID_08] the third argument, "whatToMatch", was given as an empty string. This means, you intend to match purely by a callback. The callback was not set though, the opts key "cb" is not set!${extraNote}`);
|
|
474
|
-
}
|
|
475
|
-
// Case 2. Normal operation where callback may or may not be present, but it is
|
|
476
|
-
// only accompanying the matching of what was given in 3rd input argument.
|
|
477
|
-
// Then if 3rd arg's contents were matched, callback is checked and its Boolean
|
|
478
|
-
// result is merged using logical "AND" - meaning both have to be true to yield
|
|
479
|
-
// final result "true".
|
|
480
|
-
for (let i = 0, len = whatToMatch.length; i < len; i++) {
|
|
481
|
-
special = typeof whatToMatch[i] === "function";
|
|
482
|
-
// since input can be function, we need to grab the value explicitly:
|
|
483
|
-
const whatToMatchVal = whatToMatch[i];
|
|
484
|
-
let fullCharacterInFront;
|
|
485
|
-
let indexOfTheCharacterInFront;
|
|
486
|
-
let restOfStringInFront = "";
|
|
487
|
-
let startingPosition = position;
|
|
488
|
-
if (mode === "matchRight") {
|
|
489
|
-
startingPosition += 1;
|
|
490
|
-
}
|
|
491
|
-
else if (mode === "matchLeft") {
|
|
492
|
-
startingPosition -= 1;
|
|
493
|
-
}
|
|
494
|
-
const found = march(str, startingPosition, whatToMatchVal, opts, special, (i2) => (mode[5] === "L" ? i2 - 1 : i2 + 1));
|
|
495
|
-
// if march() returned positive result and it was "special" case,
|
|
496
|
-
// Bob's your uncle, here's the result:
|
|
497
|
-
if (found &&
|
|
498
|
-
special &&
|
|
499
|
-
typeof whatToMatchVal === "function" &&
|
|
500
|
-
whatToMatchVal() === "EOL") {
|
|
501
|
-
return whatToMatchVal() &&
|
|
502
|
-
(opts.cb
|
|
503
|
-
? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront)
|
|
504
|
-
: true)
|
|
505
|
-
? whatToMatchVal()
|
|
506
|
-
: false;
|
|
507
|
-
}
|
|
508
|
-
// now, the "found" is the index of the first character of what was found.
|
|
509
|
-
// we need to calculate the character to the left/right of it:
|
|
510
|
-
if (Number.isInteger(found)) {
|
|
511
|
-
indexOfTheCharacterInFront = mode.startsWith("matchLeft")
|
|
512
|
-
? found - 1
|
|
513
|
-
: found + 1;
|
|
514
|
-
//
|
|
515
|
-
if (mode[5] === "L") {
|
|
516
|
-
restOfStringInFront = str.slice(0, found);
|
|
517
|
-
}
|
|
518
|
-
else {
|
|
519
|
-
restOfStringInFront = str.slice(indexOfTheCharacterInFront);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (indexOfTheCharacterInFront < 0) {
|
|
523
|
-
indexOfTheCharacterInFront = undefined;
|
|
524
|
-
}
|
|
525
|
-
if (str[indexOfTheCharacterInFront]) {
|
|
526
|
-
fullCharacterInFront = str[indexOfTheCharacterInFront];
|
|
527
|
-
}
|
|
528
|
-
if (Number.isInteger(found) &&
|
|
529
|
-
(opts.cb
|
|
530
|
-
? opts.cb(fullCharacterInFront, restOfStringInFront, indexOfTheCharacterInFront)
|
|
531
|
-
: true)) {
|
|
532
|
-
return whatToMatchVal;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
return false;
|
|
536
|
-
}
|
|
537
|
-
// External API functions
|
|
538
|
-
function matchLeftIncl(str, position, whatToMatch, opts) {
|
|
539
|
-
return main("matchLeftIncl", str, position, whatToMatch, opts);
|
|
540
|
-
}
|
|
541
|
-
function matchLeft(str, position, whatToMatch, opts) {
|
|
542
|
-
return main("matchLeft", str, position, whatToMatch, opts);
|
|
543
|
-
}
|
|
544
|
-
function matchRightIncl(str, position, whatToMatch, opts) {
|
|
545
|
-
return main("matchRightIncl", str, position, whatToMatch, opts);
|
|
546
|
-
}
|
|
547
|
-
function matchRight(str, position, whatToMatch, opts) {
|
|
548
|
-
return main("matchRight", str, position, whatToMatch, opts);
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
exports.matchLeft = matchLeft;
|
|
552
|
-
exports.matchLeftIncl = matchLeftIncl;
|
|
553
|
-
exports.matchRight = matchRight;
|
|
554
|
-
exports.matchRightIncl = matchRightIncl;
|
|
555
|
-
|
|
556
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
557
|
-
|
|
558
|
-
})));
|