@appland/scanner 1.33.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/LICENSE.txt +25 -0
- package/README.md +122 -0
- package/built/algorithms/dataStructures/graph/Graph.js +155 -0
- package/built/algorithms/dataStructures/graph/Graph.js.map +1 -0
- package/built/algorithms/dataStructures/graph/GraphEdge.js +27 -0
- package/built/algorithms/dataStructures/graph/GraphEdge.js.map +1 -0
- package/built/algorithms/dataStructures/graph/GraphVertex.js +79 -0
- package/built/algorithms/dataStructures/graph/GraphVertex.js.map +1 -0
- package/built/algorithms/dataStructures/linked-list/LinkedList.js +134 -0
- package/built/algorithms/dataStructures/linked-list/LinkedList.js.map +1 -0
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js +16 -0
- package/built/algorithms/dataStructures/linked-list/LinkedListNode.js.map +1 -0
- package/built/algorithms/graph/depth-first-search/index.js +49 -0
- package/built/algorithms/graph/depth-first-search/index.js.map +1 -0
- package/built/algorithms/graph/detect-cycle/index.js +77 -0
- package/built/algorithms/graph/detect-cycle/index.js.map +1 -0
- package/built/algorithms/utils/Comparator.js +35 -0
- package/built/algorithms/utils/Comparator.js.map +1 -0
- package/built/analyzer/recordSecrets.js +17 -0
- package/built/analyzer/recordSecrets.js.map +1 -0
- package/built/analyzer/secretsRegexes.js +13 -0
- package/built/analyzer/secretsRegexes.js.map +1 -0
- package/built/analyzer/secretsRegexesData.json +51 -0
- package/built/check.js +47 -0
- package/built/check.js.map +1 -0
- package/built/checkInstance.js +69 -0
- package/built/checkInstance.js.map +1 -0
- package/built/cli/ci/command.js +183 -0
- package/built/cli/ci/command.js.map +1 -0
- package/built/cli/ci/options.js +3 -0
- package/built/cli/ci/options.js.map +1 -0
- package/built/cli/exitCode.js +11 -0
- package/built/cli/exitCode.js.map +1 -0
- package/built/cli/progressReporter.js +16 -0
- package/built/cli/progressReporter.js.map +1 -0
- package/built/cli/resolveAppId.js +83 -0
- package/built/cli/resolveAppId.js.map +1 -0
- package/built/cli/scan/command.js +174 -0
- package/built/cli/scan/command.js.map +1 -0
- package/built/cli/scan/options.js +3 -0
- package/built/cli/scan/options.js.map +1 -0
- package/built/cli/scan/scanner.js +154 -0
- package/built/cli/scan/scanner.js.map +1 -0
- package/built/cli/scan.js +103 -0
- package/built/cli/scan.js.map +1 -0
- package/built/cli/scanArgs.js +26 -0
- package/built/cli/scanArgs.js.map +1 -0
- package/built/cli/scanOptions.js +3 -0
- package/built/cli/scanOptions.js.map +1 -0
- package/built/cli/upload/command.js +95 -0
- package/built/cli/upload/command.js.map +1 -0
- package/built/cli/upload/options.js +3 -0
- package/built/cli/upload/options.js.map +1 -0
- package/built/cli/validateFile.js +66 -0
- package/built/cli/validateFile.js.map +1 -0
- package/built/cli.js +32 -0
- package/built/cli.js.map +1 -0
- package/built/configuration/configurationProvider.js +169 -0
- package/built/configuration/configurationProvider.js.map +1 -0
- package/built/configuration/schema/match-pattern-config.json +32 -0
- package/built/configuration/schema/options.json +193 -0
- package/built/configuration/types/checkConfig.js +3 -0
- package/built/configuration/types/checkConfig.js.map +1 -0
- package/built/configuration/types/configuration.js +3 -0
- package/built/configuration/types/configuration.js.map +1 -0
- package/built/configuration/types/matchEventConfig.js +3 -0
- package/built/configuration/types/matchEventConfig.js.map +1 -0
- package/built/configuration/types/matchPatternConfig.js +3 -0
- package/built/configuration/types/matchPatternConfig.js.map +1 -0
- package/built/database/index.js +259 -0
- package/built/database/index.js.map +1 -0
- package/built/database/visit.js +80 -0
- package/built/database/visit.js.map +1 -0
- package/built/errors.js +35 -0
- package/built/errors.js.map +1 -0
- package/built/findings.js +15 -0
- package/built/findings.js.map +1 -0
- package/built/integration/appland/fetchStatus.js +51 -0
- package/built/integration/appland/fetchStatus.js.map +1 -0
- package/built/integration/appland/upload.js +193 -0
- package/built/integration/appland/upload.js.map +1 -0
- package/built/integration/github/commitStatus.js +19 -0
- package/built/integration/github/commitStatus.js.map +1 -0
- package/built/integration/vars.js +68 -0
- package/built/integration/vars.js.map +1 -0
- package/built/openapi/index.js +100 -0
- package/built/openapi/index.js.map +1 -0
- package/built/openapi/method.js +120 -0
- package/built/openapi/method.js.map +1 -0
- package/built/openapi/model.js +49 -0
- package/built/openapi/model.js.map +1 -0
- package/built/openapi/path.js +36 -0
- package/built/openapi/path.js.map +1 -0
- package/built/openapi/provider.js +133 -0
- package/built/openapi/provider.js.map +1 -0
- package/built/openapi/response.js +59 -0
- package/built/openapi/response.js.map +1 -0
- package/built/openapi/rpcRequest.js +130 -0
- package/built/openapi/rpcRequest.js.map +1 -0
- package/built/openapi/schema.js +42 -0
- package/built/openapi/schema.js.map +1 -0
- package/built/openapi/securitySchemes.js +32 -0
- package/built/openapi/securitySchemes.js.map +1 -0
- package/built/openapi/statusCodes.js +68 -0
- package/built/openapi/statusCodes.js.map +1 -0
- package/built/openapi/util.js +91 -0
- package/built/openapi/util.js.map +1 -0
- package/built/report/appMapMetadata.js +2 -0
- package/built/report/appMapMetadata.js.map +1 -0
- package/built/report/findingSummary.js +3 -0
- package/built/report/findingSummary.js.map +1 -0
- package/built/report/findingsReport.js +37 -0
- package/built/report/findingsReport.js.map +1 -0
- package/built/report/scanResults.js +103 -0
- package/built/report/scanResults.js.map +1 -0
- package/built/report/scanSummary.js +3 -0
- package/built/report/scanSummary.js.map +1 -0
- package/built/report/summaryReport.js +70 -0
- package/built/report/summaryReport.js.map +1 -0
- package/built/ruleChecker.js +260 -0
- package/built/ruleChecker.js.map +1 -0
- package/built/rules/authzBeforeAuthn.js +82 -0
- package/built/rules/authzBeforeAuthn.js.map +1 -0
- package/built/rules/circularDependency.js +227 -0
- package/built/rules/circularDependency.js.map +1 -0
- package/built/rules/http500.js +18 -0
- package/built/rules/http500.js.map +1 -0
- package/built/rules/illegalPackageDependency.js +38 -0
- package/built/rules/illegalPackageDependency.js.map +1 -0
- package/built/rules/incompatibleHttpClientRequest.js +96 -0
- package/built/rules/incompatibleHttpClientRequest.js.map +1 -0
- package/built/rules/insecureCompare.js +59 -0
- package/built/rules/insecureCompare.js.map +1 -0
- package/built/rules/jobNotCancelled.js +72 -0
- package/built/rules/jobNotCancelled.js.map +1 -0
- package/built/rules/lib/hasParameterOrReceiver.js +11 -0
- package/built/rules/lib/hasParameterOrReceiver.js.map +1 -0
- package/built/rules/lib/matchEvent.js +32 -0
- package/built/rules/lib/matchEvent.js.map +1 -0
- package/built/rules/lib/matchPattern.js +28 -0
- package/built/rules/lib/matchPattern.js.map +1 -0
- package/built/rules/lib/rpcWithoutProtection.js +40 -0
- package/built/rules/lib/rpcWithoutProtection.js.map +1 -0
- package/built/rules/missingAuthentication.js +65 -0
- package/built/rules/missingAuthentication.js.map +1 -0
- package/built/rules/missingContentType.js +27 -0
- package/built/rules/missingContentType.js.map +1 -0
- package/built/rules/nPlusOneQuery.js +84 -0
- package/built/rules/nPlusOneQuery.js.map +1 -0
- package/built/rules/queryFromInvalidPackage.js +37 -0
- package/built/rules/queryFromInvalidPackage.js.map +1 -0
- package/built/rules/queryFromView.js +29 -0
- package/built/rules/queryFromView.js.map +1 -0
- package/built/rules/rpcWithoutCircuitBreaker.js +97 -0
- package/built/rules/rpcWithoutCircuitBreaker.js.map +1 -0
- package/built/rules/saveWithoutValidation.js +27 -0
- package/built/rules/saveWithoutValidation.js.map +1 -0
- package/built/rules/secretInLog.js +76 -0
- package/built/rules/secretInLog.js.map +1 -0
- package/built/rules/slowFunctionCall.js +37 -0
- package/built/rules/slowFunctionCall.js.map +1 -0
- package/built/rules/slowHttpServerRequest.js +24 -0
- package/built/rules/slowHttpServerRequest.js.map +1 -0
- package/built/rules/slowQuery.js +23 -0
- package/built/rules/slowQuery.js.map +1 -0
- package/built/rules/tooManyJoins.js +77 -0
- package/built/rules/tooManyJoins.js.map +1 -0
- package/built/rules/tooManyUpdates.js +143 -0
- package/built/rules/tooManyUpdates.js.map +1 -0
- package/built/rules/unbatchedMaterializedQuery.js +65 -0
- package/built/rules/unbatchedMaterializedQuery.js.map +1 -0
- package/built/rules/updateInGetRequest.js +66 -0
- package/built/rules/updateInGetRequest.js.map +1 -0
- package/built/rules/util.js +102 -0
- package/built/rules/util.js.map +1 -0
- package/built/sampleConfig/bike_index.yml +10 -0
- package/built/sampleConfig/default.yml +19 -0
- package/built/sampleConfig/railsSampleApp6thEd.yml +29 -0
- package/built/sampleConfig/solidus.yml +31 -0
- package/built/scope/commandScope.js +156 -0
- package/built/scope/commandScope.js.map +1 -0
- package/built/scope/httpClientRequestScope.js +105 -0
- package/built/scope/httpClientRequestScope.js.map +1 -0
- package/built/scope/httpServerRequestScope.js +105 -0
- package/built/scope/httpServerRequestScope.js.map +1 -0
- package/built/scope/rootScope.js +105 -0
- package/built/scope/rootScope.js.map +1 -0
- package/built/scope/scopeImpl.js +88 -0
- package/built/scope/scopeImpl.js.map +1 -0
- package/built/scope/scopeIterator.js +21 -0
- package/built/scope/scopeIterator.js.map +1 -0
- package/built/scope/sqlTransactionScope.js +175 -0
- package/built/scope/sqlTransactionScope.js.map +1 -0
- package/built/wellKnownLabels.js +9 -0
- package/built/wellKnownLabels.js.map +1 -0
- package/package.json +89 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
The Software is provided to you by the Licensor under the License, as defined below, subject to the following condition.
|
|
2
|
+
|
|
3
|
+
Without limiting other conditions in the License, the grant of rights under the License will not include,
|
|
4
|
+
and the License does not grant to you, the right to Sell the Software.
|
|
5
|
+
|
|
6
|
+
For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you under the License to provide to third parties,
|
|
7
|
+
for a fee or other consideration (including without limitation fees for hosting or consulting/ support services related to the Software),
|
|
8
|
+
a product or service whose value derives, entirely or substantially, from the functionality of the Software.
|
|
9
|
+
Any license notice or attribution required by the License must also include this Commons Clause License Condition notice.
|
|
10
|
+
|
|
11
|
+
Software: @appland/scanner
|
|
12
|
+
|
|
13
|
+
License: MIT License
|
|
14
|
+
|
|
15
|
+
Copyright 2022, AppLand Inc
|
|
16
|
+
|
|
17
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
|
18
|
+
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
19
|
+
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
25
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# AppMap Scanner
|
|
2
|
+
|
|
3
|
+
Code scanning, linting, assertions and alerts.
|
|
4
|
+
|
|
5
|
+
Provides consistent ways to filter (include and exclude) the AppMap events and property values.
|
|
6
|
+
|
|
7
|
+
# Rule configuration
|
|
8
|
+
|
|
9
|
+
## Event filters
|
|
10
|
+
|
|
11
|
+
Two standard event filters are provided that can be used with every rule: `include` and `exclude`.
|
|
12
|
+
These filters are applied to an event, and make a determination about whether or not that event
|
|
13
|
+
should be checked by the rule.
|
|
14
|
+
|
|
15
|
+
An event filter can be applied in one of two ways:
|
|
16
|
+
|
|
17
|
+
- `scope` the entire scope - for example, `http_server_request`, `command`.
|
|
18
|
+
- `event` an individual event within a scope. When `enumerateScope` is true for a rule, the event
|
|
19
|
+
filters are applied automatically by the scanner framework. When `enumerateScope` is false, the
|
|
20
|
+
rule code must apply the filter itself.
|
|
21
|
+
|
|
22
|
+
The event filter consists of a property name and a test. The framework fetches the property value
|
|
23
|
+
from the event, and then applies the test. The test can be one of three types:
|
|
24
|
+
|
|
25
|
+
- `equal` - value string matches the filter condition exactly.
|
|
26
|
+
- `include` - value string includes the filter condition.
|
|
27
|
+
- `match` - value string matches the filter condition regexp.
|
|
28
|
+
|
|
29
|
+
Here's an example of a rule configured with a custom `include` event filter. The event filter
|
|
30
|
+
prevents the rule from being applied to SQL queries that include the fragment
|
|
31
|
+
`FROM "pg_class" INNER JOIN "pg_attribute"` (because these queries are fetching ORM metadata, not
|
|
32
|
+
application code).
|
|
33
|
+
|
|
34
|
+
```yaml
|
|
35
|
+
- id: tooManyJoins
|
|
36
|
+
exclude:
|
|
37
|
+
- event:
|
|
38
|
+
property: query
|
|
39
|
+
test:
|
|
40
|
+
include: FROM "pg_class" INNER JOIN "pg_attribute"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Pattern filters
|
|
44
|
+
|
|
45
|
+
A second type of filter is pattern filter. Pattern filters are provided by rules that need, or
|
|
46
|
+
benefit from, specific configuration.
|
|
47
|
+
|
|
48
|
+
Like Event filters, a pattern filter uses `equal`, `include`, or `match`. The data to which the
|
|
49
|
+
pattern filter is applied depends on the particulars of the rule. For example, this pattern filter
|
|
50
|
+
finds slow function calls within a specific package:
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
- id: slowFunctionCall
|
|
54
|
+
properties:
|
|
55
|
+
functions:
|
|
56
|
+
- match: ^app/models
|
|
57
|
+
timeAllowed: 0.25
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Schema validation
|
|
61
|
+
|
|
62
|
+
The configuration YAML is validated against the rule schema before the scan is run. Any errors in
|
|
63
|
+
the configuration are reported, and must be fixed before the scan can continue. Consult the
|
|
64
|
+
documentation for each rule to see it's pattern filters and other configurable properties.
|
|
65
|
+
|
|
66
|
+
## Development
|
|
67
|
+
|
|
68
|
+
We use `yarn` for package management. Run `yarn` to install dependencies and `yarn build` to emit
|
|
69
|
+
JavaScript. To run without first emitting JavaScript to the filesystem, use `yarn start`.
|
|
70
|
+
|
|
71
|
+
## Installation
|
|
72
|
+
|
|
73
|
+
Install like any other Node.js package, using `yarn` or `npm`:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
yarn add --dev @appland/scanner
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Then, you may find it convenient to add some scripts to your `package.json`:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
"scripts": {
|
|
83
|
+
"scan": "npx @appland/scanner scan --appmap-dir tmp/appmap",
|
|
84
|
+
"scan-ci": "npx @appland/scanner ci --appmap-dir tmp/appmap",
|
|
85
|
+
},
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Note** `tmp/appmap` is the standard AppMap location for some AppMap agents, but not all. Consult
|
|
89
|
+
your agent documentation and settings to configure the `--appmap-dir`.
|
|
90
|
+
|
|
91
|
+
## Scan locally
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
yarn run scan
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Findings will be printed to the console, and saved to `appland-findings.json`.
|
|
98
|
+
|
|
99
|
+
## CI integration
|
|
100
|
+
|
|
101
|
+
When using Appmap Scanner in CI you can post findings summary as a commit status and/or a PR comment
|
|
102
|
+
(currently only GitHub is supported). In order to allow access to your repo you need to create a
|
|
103
|
+
[personal token](https://github.com/settings/tokens/new) with following privileges and add it as a
|
|
104
|
+
`GH_TOKEN` env variable to your CI:
|
|
105
|
+
|
|
106
|
+
- `repo` for posting PR comments
|
|
107
|
+
- `repo:status` for posting commit statuses
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
yarn run scan-ci
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Development
|
|
114
|
+
|
|
115
|
+
### Using a local branch of `@appland/models`
|
|
116
|
+
|
|
117
|
+
Use `yarn link` to create a symlink to a local version of `@appland/models`. Make sure the models
|
|
118
|
+
package is built according to the instructions in its own README.
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
$ yarn link ../appmap-js/packages/models
|
|
122
|
+
```
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var Graph = /** @class */ (function () {
|
|
4
|
+
/**
|
|
5
|
+
* @param {boolean} isDirected
|
|
6
|
+
*/
|
|
7
|
+
function Graph(isDirected) {
|
|
8
|
+
if (isDirected === void 0) { isDirected = false; }
|
|
9
|
+
this.vertices = {};
|
|
10
|
+
this.edges = {};
|
|
11
|
+
this.vertices = {};
|
|
12
|
+
this.edges = {};
|
|
13
|
+
this.isDirected = isDirected;
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(Graph.prototype, "vertexCount", {
|
|
16
|
+
get: function () {
|
|
17
|
+
return Object.keys(this.vertices).length;
|
|
18
|
+
},
|
|
19
|
+
enumerable: false,
|
|
20
|
+
configurable: true
|
|
21
|
+
});
|
|
22
|
+
Graph.prototype.addVertex = function (newVertex) {
|
|
23
|
+
this.vertices[newVertex.getKey()] = newVertex;
|
|
24
|
+
return this;
|
|
25
|
+
};
|
|
26
|
+
Graph.prototype.getVertexByKey = function (vertexKey) {
|
|
27
|
+
return this.vertices[vertexKey];
|
|
28
|
+
};
|
|
29
|
+
Graph.prototype.getNeighbors = function (vertex) {
|
|
30
|
+
return vertex.getNeighbors();
|
|
31
|
+
};
|
|
32
|
+
Graph.prototype.getAllVertices = function () {
|
|
33
|
+
return Object.values(this.vertices);
|
|
34
|
+
};
|
|
35
|
+
Graph.prototype.getAllEdges = function () {
|
|
36
|
+
return Object.values(this.edges);
|
|
37
|
+
};
|
|
38
|
+
Graph.prototype.addEdge = function (edge) {
|
|
39
|
+
// Try to find and end start vertices.
|
|
40
|
+
var startVertex = this.getVertexByKey(edge.startVertex.getKey());
|
|
41
|
+
var endVertex = this.getVertexByKey(edge.endVertex.getKey());
|
|
42
|
+
// Insert start vertex if it wasn't inserted.
|
|
43
|
+
if (!startVertex) {
|
|
44
|
+
this.addVertex(edge.startVertex);
|
|
45
|
+
startVertex = this.getVertexByKey(edge.startVertex.getKey());
|
|
46
|
+
}
|
|
47
|
+
// Insert end vertex if it wasn't inserted.
|
|
48
|
+
if (!endVertex) {
|
|
49
|
+
this.addVertex(edge.endVertex);
|
|
50
|
+
endVertex = this.getVertexByKey(edge.endVertex.getKey());
|
|
51
|
+
}
|
|
52
|
+
// Check if edge has been already added.
|
|
53
|
+
if (this.edges[edge.getKey()]) {
|
|
54
|
+
throw new Error('Edge has already been added before');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.edges[edge.getKey()] = edge;
|
|
58
|
+
}
|
|
59
|
+
// Add edge to the vertices.
|
|
60
|
+
if (this.isDirected) {
|
|
61
|
+
// If graph IS directed then add the edge only to start vertex.
|
|
62
|
+
startVertex.addEdge(edge);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// If graph ISN'T directed then add the edge to both vertices.
|
|
66
|
+
startVertex.addEdge(edge);
|
|
67
|
+
endVertex.addEdge(edge);
|
|
68
|
+
}
|
|
69
|
+
return this;
|
|
70
|
+
};
|
|
71
|
+
Graph.prototype.deleteEdge = function (edge) {
|
|
72
|
+
// Delete edge from the list of edges.
|
|
73
|
+
if (this.edges[edge.getKey()]) {
|
|
74
|
+
delete this.edges[edge.getKey()];
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
throw new Error('Edge not found in graph');
|
|
78
|
+
}
|
|
79
|
+
// Try to find and end start vertices and delete edge from them.
|
|
80
|
+
var startVertex = this.getVertexByKey(edge.startVertex.getKey());
|
|
81
|
+
var endVertex = this.getVertexByKey(edge.endVertex.getKey());
|
|
82
|
+
if (startVertex) {
|
|
83
|
+
startVertex.deleteEdge(edge);
|
|
84
|
+
}
|
|
85
|
+
if (endVertex) {
|
|
86
|
+
endVertex.deleteEdge(edge);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
Graph.prototype.findEdge = function (startVertex, endVertex) {
|
|
90
|
+
var vertex = this.getVertexByKey(startVertex.getKey());
|
|
91
|
+
if (!vertex) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return vertex.findEdge(endVertex);
|
|
95
|
+
};
|
|
96
|
+
Graph.prototype.findVertexByKey = function (vertexKey) {
|
|
97
|
+
if (this.vertices[vertexKey]) {
|
|
98
|
+
return this.vertices[vertexKey];
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
};
|
|
102
|
+
Graph.prototype.getWeight = function () {
|
|
103
|
+
return this.getAllEdges().reduce(function (weight, graphEdge) {
|
|
104
|
+
return weight + graphEdge.weight;
|
|
105
|
+
}, 0);
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Reverse all the edges in directed graph.
|
|
109
|
+
*/
|
|
110
|
+
Graph.prototype.reverse = function () {
|
|
111
|
+
var _this = this;
|
|
112
|
+
this.getAllEdges().forEach(function (edge) {
|
|
113
|
+
// Delete straight edge from graph and from vertices.
|
|
114
|
+
_this.deleteEdge(edge);
|
|
115
|
+
// Reverse the edge.
|
|
116
|
+
edge.reverse();
|
|
117
|
+
// Add reversed edge back to the graph and its vertices.
|
|
118
|
+
_this.addEdge(edge);
|
|
119
|
+
});
|
|
120
|
+
return this;
|
|
121
|
+
};
|
|
122
|
+
Graph.prototype.getVerticesIndices = function () {
|
|
123
|
+
var verticesIndices = {};
|
|
124
|
+
this.getAllVertices().forEach(function (vertex, index) {
|
|
125
|
+
verticesIndices[vertex.getKey()] = index;
|
|
126
|
+
});
|
|
127
|
+
return verticesIndices;
|
|
128
|
+
};
|
|
129
|
+
Graph.prototype.getAdjacencyMatrix = function () {
|
|
130
|
+
var _this = this;
|
|
131
|
+
var vertices = this.getAllVertices();
|
|
132
|
+
var verticesIndices = this.getVerticesIndices();
|
|
133
|
+
// Init matrix with infinities meaning that there is no ways of
|
|
134
|
+
// getting from one vertex to another yet.
|
|
135
|
+
var adjacencyMatrix = Array(vertices.length)
|
|
136
|
+
.fill(null)
|
|
137
|
+
.map(function () {
|
|
138
|
+
return Array(vertices.length).fill(Infinity);
|
|
139
|
+
});
|
|
140
|
+
// Fill the columns.
|
|
141
|
+
vertices.forEach(function (vertex, vertexIndex) {
|
|
142
|
+
vertex.getNeighbors().forEach(function (neighbor) {
|
|
143
|
+
var neighborIndex = verticesIndices[neighbor.getKey()];
|
|
144
|
+
adjacencyMatrix[vertexIndex][neighborIndex] = _this.findEdge(vertex, neighbor).weight;
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
return adjacencyMatrix;
|
|
148
|
+
};
|
|
149
|
+
Graph.prototype.toString = function () {
|
|
150
|
+
return Object.keys(this.vertices).toString();
|
|
151
|
+
};
|
|
152
|
+
return Graph;
|
|
153
|
+
}());
|
|
154
|
+
exports.default = Graph;
|
|
155
|
+
//# sourceMappingURL=Graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Graph.js","sourceRoot":"","sources":["../../../../src/algorithms/dataStructures/graph/Graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var GraphEdge = /** @class */ (function () {
|
|
4
|
+
function GraphEdge(startVertex, endVertex, weight) {
|
|
5
|
+
if (weight === void 0) { weight = 0; }
|
|
6
|
+
this.startVertex = startVertex;
|
|
7
|
+
this.endVertex = endVertex;
|
|
8
|
+
this.weight = weight;
|
|
9
|
+
}
|
|
10
|
+
GraphEdge.prototype.getKey = function () {
|
|
11
|
+
var startVertexKey = this.startVertex.getKey();
|
|
12
|
+
var endVertexKey = this.endVertex.getKey();
|
|
13
|
+
return startVertexKey + " - " + endVertexKey;
|
|
14
|
+
};
|
|
15
|
+
GraphEdge.prototype.reverse = function () {
|
|
16
|
+
var tmp = this.startVertex;
|
|
17
|
+
this.startVertex = this.endVertex;
|
|
18
|
+
this.endVertex = tmp;
|
|
19
|
+
return this;
|
|
20
|
+
};
|
|
21
|
+
GraphEdge.prototype.toString = function () {
|
|
22
|
+
return this.getKey();
|
|
23
|
+
};
|
|
24
|
+
return GraphEdge;
|
|
25
|
+
}());
|
|
26
|
+
exports.default = GraphEdge;
|
|
27
|
+
//# sourceMappingURL=GraphEdge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphEdge.js","sourceRoot":"","sources":["../../../../src/algorithms/dataStructures/graph/GraphEdge.ts"],"names":[],"mappings":";;AAEA;IAKE,mBAAY,WAAwB,EAAE,SAAsB,EAAE,MAAU;QAAV,uBAAA,EAAA,UAAU;QACtE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,0BAAM,GAAN;QACE,IAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;QACjD,IAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QAE7C,OAAU,cAAc,WAAM,YAAc,CAAC;IAC/C,CAAC;IAED,2BAAO,GAAP;QACE,IAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;QAErB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4BAAQ,GAAR;QACE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;IACH,gBAAC;AAAD,CAAC,AA7BD,IA6BC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
var LinkedList_1 = __importDefault(require("../linked-list/LinkedList"));
|
|
7
|
+
var GraphVertex = /** @class */ (function () {
|
|
8
|
+
/**
|
|
9
|
+
* @param {*} value
|
|
10
|
+
*/
|
|
11
|
+
function GraphVertex(value) {
|
|
12
|
+
if (value === '') {
|
|
13
|
+
throw new Error('Graph vertex must have a non-empty value');
|
|
14
|
+
}
|
|
15
|
+
var edgeComparator = function (edgeA, edgeB) {
|
|
16
|
+
if (edgeA.getKey() === edgeB.getKey()) {
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
return edgeA.getKey() < edgeB.getKey() ? -1 : 1;
|
|
20
|
+
};
|
|
21
|
+
// Normally you would store string value like vertex name.
|
|
22
|
+
// But generally it may be any object as well
|
|
23
|
+
this.value = value;
|
|
24
|
+
this.edges = new LinkedList_1.default(edgeComparator);
|
|
25
|
+
}
|
|
26
|
+
GraphVertex.prototype.addEdge = function (edge) {
|
|
27
|
+
this.edges.append(edge);
|
|
28
|
+
return this;
|
|
29
|
+
};
|
|
30
|
+
GraphVertex.prototype.deleteEdge = function (edge) {
|
|
31
|
+
this.edges.delete(edge);
|
|
32
|
+
};
|
|
33
|
+
GraphVertex.prototype.getNeighbors = function () {
|
|
34
|
+
var _this = this;
|
|
35
|
+
var edges = this.edges.toArray();
|
|
36
|
+
var neighborsConverter = function (node) {
|
|
37
|
+
return node.value.startVertex === _this ? node.value.endVertex : node.value.startVertex;
|
|
38
|
+
};
|
|
39
|
+
// Return either start or end vertex.
|
|
40
|
+
// For undirected graphs it is possible that current vertex will be the end one.
|
|
41
|
+
return edges.map(neighborsConverter);
|
|
42
|
+
};
|
|
43
|
+
GraphVertex.prototype.getEdges = function () {
|
|
44
|
+
return this.edges.toArray().map(function (linkedListNode) { return linkedListNode.value; });
|
|
45
|
+
};
|
|
46
|
+
GraphVertex.prototype.getDegree = function () {
|
|
47
|
+
return this.edges.toArray().length;
|
|
48
|
+
};
|
|
49
|
+
GraphVertex.prototype.hasEdge = function (requiredEdge) {
|
|
50
|
+
var edgeNode = this.edges.find(undefined, function (edge) { return edge === requiredEdge; });
|
|
51
|
+
return !!edgeNode;
|
|
52
|
+
};
|
|
53
|
+
GraphVertex.prototype.hasNeighbor = function (vertex) {
|
|
54
|
+
var vertexNode = this.edges.find(undefined, function (edge) { return edge.startVertex === vertex || edge.endVertex === vertex; });
|
|
55
|
+
return !!vertexNode;
|
|
56
|
+
};
|
|
57
|
+
GraphVertex.prototype.findEdge = function (vertex) {
|
|
58
|
+
var edgeFinder = function (edge) {
|
|
59
|
+
return edge.startVertex === vertex || edge.endVertex === vertex;
|
|
60
|
+
};
|
|
61
|
+
var edge = this.edges.find(undefined, edgeFinder);
|
|
62
|
+
return edge ? edge.value : null;
|
|
63
|
+
};
|
|
64
|
+
GraphVertex.prototype.getKey = function () {
|
|
65
|
+
return this.value;
|
|
66
|
+
};
|
|
67
|
+
GraphVertex.prototype.deleteAllEdges = function () {
|
|
68
|
+
var _this = this;
|
|
69
|
+
this.getEdges().forEach(function (edge) { return _this.deleteEdge(edge); });
|
|
70
|
+
return this;
|
|
71
|
+
};
|
|
72
|
+
GraphVertex.prototype.toString = function (callback) {
|
|
73
|
+
if (callback === void 0) { callback = undefined; }
|
|
74
|
+
return callback ? callback(this.value) : "" + this.value;
|
|
75
|
+
};
|
|
76
|
+
return GraphVertex;
|
|
77
|
+
}());
|
|
78
|
+
exports.default = GraphVertex;
|
|
79
|
+
//# sourceMappingURL=GraphVertex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GraphVertex.js","sourceRoot":"","sources":["../../../../src/algorithms/dataStructures/graph/GraphVertex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
var LinkedListNode_1 = __importDefault(require("./LinkedListNode"));
|
|
7
|
+
var Comparator_1 = __importDefault(require("../../utils/Comparator"));
|
|
8
|
+
var LinkedList = /** @class */ (function () {
|
|
9
|
+
function LinkedList(comparatorFunction) {
|
|
10
|
+
this.head = null;
|
|
11
|
+
this.tail = null;
|
|
12
|
+
this.compare = new Comparator_1.default(comparatorFunction);
|
|
13
|
+
}
|
|
14
|
+
LinkedList.prototype.prepend = function (value) {
|
|
15
|
+
// Make new node to be a head.
|
|
16
|
+
this.head = new LinkedListNode_1.default(value, this.head);
|
|
17
|
+
return this;
|
|
18
|
+
};
|
|
19
|
+
LinkedList.prototype.append = function (value) {
|
|
20
|
+
var newNode = new LinkedListNode_1.default(value);
|
|
21
|
+
// If there is no head yet let's make new node a head.
|
|
22
|
+
if (!this.head) {
|
|
23
|
+
this.head = newNode;
|
|
24
|
+
this.tail = newNode;
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
// Attach new node to the end of linked list.
|
|
28
|
+
this.tail.next = newNode;
|
|
29
|
+
this.tail = newNode;
|
|
30
|
+
return this;
|
|
31
|
+
};
|
|
32
|
+
LinkedList.prototype.delete = function (value) {
|
|
33
|
+
if (!this.head) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
var deletedNode = null;
|
|
37
|
+
// If the head must be deleted then make 2nd node to be a head.
|
|
38
|
+
while (this.head && this.compare.equal(this.head.value, value)) {
|
|
39
|
+
deletedNode = this.head;
|
|
40
|
+
this.head = this.head.next;
|
|
41
|
+
}
|
|
42
|
+
var currentNode = this.head;
|
|
43
|
+
if (currentNode !== null) {
|
|
44
|
+
// If next node must be deleted then make next node to be a next next one.
|
|
45
|
+
while (currentNode.next) {
|
|
46
|
+
if (this.compare.equal(currentNode.next.value, value)) {
|
|
47
|
+
deletedNode = currentNode.next;
|
|
48
|
+
currentNode.next = currentNode.next.next;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
currentNode = currentNode.next;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check if tail must be deleted.
|
|
56
|
+
if (this.compare.equal(this.tail.value, value)) {
|
|
57
|
+
this.tail = currentNode;
|
|
58
|
+
}
|
|
59
|
+
return deletedNode;
|
|
60
|
+
};
|
|
61
|
+
LinkedList.prototype.find = function (value, callback) {
|
|
62
|
+
if (value === void 0) { value = undefined; }
|
|
63
|
+
if (callback === void 0) { callback = undefined; }
|
|
64
|
+
if (!this.head) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
var currentNode = this.head;
|
|
68
|
+
while (currentNode) {
|
|
69
|
+
// If callback is specified then try to find node by callback.
|
|
70
|
+
if (callback && callback(currentNode.value)) {
|
|
71
|
+
return currentNode;
|
|
72
|
+
}
|
|
73
|
+
// If value is specified then try to compare by value..
|
|
74
|
+
if (value !== undefined && this.compare.equal(currentNode.value, value)) {
|
|
75
|
+
return currentNode;
|
|
76
|
+
}
|
|
77
|
+
currentNode = currentNode.next;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
};
|
|
81
|
+
LinkedList.prototype.deleteTail = function () {
|
|
82
|
+
if (this.head === this.tail) {
|
|
83
|
+
var deletedTail_1 = this.tail;
|
|
84
|
+
this.head = null;
|
|
85
|
+
this.tail = null;
|
|
86
|
+
return deletedTail_1;
|
|
87
|
+
}
|
|
88
|
+
var deletedTail = this.tail;
|
|
89
|
+
// Rewind to the last node and delete "next" link for the node before the last one.
|
|
90
|
+
var currentNode = this.head;
|
|
91
|
+
while (currentNode.next) {
|
|
92
|
+
if (!currentNode.next.next) {
|
|
93
|
+
currentNode.next = null;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
currentNode = currentNode.next;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.tail = currentNode;
|
|
100
|
+
return deletedTail;
|
|
101
|
+
};
|
|
102
|
+
LinkedList.prototype.deleteHead = function () {
|
|
103
|
+
if (!this.head) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
var deletedHead = this.head;
|
|
107
|
+
if (this.head.next) {
|
|
108
|
+
this.head = this.head.next;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.head = null;
|
|
112
|
+
this.tail = null;
|
|
113
|
+
}
|
|
114
|
+
return deletedHead;
|
|
115
|
+
};
|
|
116
|
+
LinkedList.prototype.toArray = function () {
|
|
117
|
+
var nodes = [];
|
|
118
|
+
var currentNode = this.head;
|
|
119
|
+
while (currentNode) {
|
|
120
|
+
nodes.push(currentNode);
|
|
121
|
+
currentNode = currentNode.next;
|
|
122
|
+
}
|
|
123
|
+
return nodes;
|
|
124
|
+
};
|
|
125
|
+
LinkedList.prototype.toString = function (callback) {
|
|
126
|
+
if (callback === void 0) { callback = undefined; }
|
|
127
|
+
return this.toArray()
|
|
128
|
+
.map(function (node) { return node.toString(callback); })
|
|
129
|
+
.toString();
|
|
130
|
+
};
|
|
131
|
+
return LinkedList;
|
|
132
|
+
}());
|
|
133
|
+
exports.default = LinkedList;
|
|
134
|
+
//# sourceMappingURL=LinkedList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkedList.js","sourceRoot":"","sources":["../../../../src/algorithms/dataStructures/linked-list/LinkedList.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var LinkedListNode = /** @class */ (function () {
|
|
4
|
+
function LinkedListNode(value, next) {
|
|
5
|
+
if (next === void 0) { next = null; }
|
|
6
|
+
this.value = value;
|
|
7
|
+
this.next = next;
|
|
8
|
+
}
|
|
9
|
+
LinkedListNode.prototype.toString = function (callback) {
|
|
10
|
+
if (callback === void 0) { callback = undefined; }
|
|
11
|
+
return callback ? callback(this.value) : "" + this.value;
|
|
12
|
+
};
|
|
13
|
+
return LinkedListNode;
|
|
14
|
+
}());
|
|
15
|
+
exports.default = LinkedListNode;
|
|
16
|
+
//# sourceMappingURL=LinkedListNode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LinkedListNode.js","sourceRoot":"","sources":["../../../../src/algorithms/dataStructures/linked-list/LinkedListNode.ts"],"names":[],"mappings":";;AAAA;IAIE,wBAAY,KAAQ,EAAE,IAAqC;QAArC,qBAAA,EAAA,WAAqC;QACzD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,iCAAQ,GAAR,UAAS,QAAwD;QAAxD,yBAAA,EAAA,oBAAwD;QAC/D,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAG,IAAI,CAAC,KAAO,CAAC;IAC3D,CAAC;IACH,qBAAC;AAAD,CAAC,AAZD,IAYC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.depthFirstSearch = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* @param {Callbacks} [callbacks]
|
|
6
|
+
* @returns {Callbacks}
|
|
7
|
+
*/
|
|
8
|
+
function initCallbacks(callbacks) {
|
|
9
|
+
var initiatedCallback = Object.assign({}, callbacks);
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
11
|
+
var stubCallback = function () { };
|
|
12
|
+
var allowTraversalCallback = (function () {
|
|
13
|
+
var seen = {};
|
|
14
|
+
return function (_previousVertex, _currentVertex, nextVertex) {
|
|
15
|
+
if (!seen[nextVertex.getKey()]) {
|
|
16
|
+
seen[nextVertex.getKey()] = true;
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
};
|
|
21
|
+
})();
|
|
22
|
+
initiatedCallback.allowTraversal = callbacks.allowTraversal || allowTraversalCallback;
|
|
23
|
+
initiatedCallback.enterVertex = callbacks.enterVertex || stubCallback;
|
|
24
|
+
initiatedCallback.leaveVertex = callbacks.leaveVertex || stubCallback;
|
|
25
|
+
return initiatedCallback;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @param {Graph} graph
|
|
29
|
+
* @param {GraphVertex} currentVertex
|
|
30
|
+
* @param {GraphVertex} previousVertex
|
|
31
|
+
* @param {Callbacks} callbacks
|
|
32
|
+
*/
|
|
33
|
+
function depthFirstSearchRecursive(graph, currentVertex, previousVertex, callbacks) {
|
|
34
|
+
if (!callbacks.enterVertex(currentVertex, previousVertex)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
graph.getNeighbors(currentVertex).forEach(function (nextVertex) {
|
|
38
|
+
if (callbacks.allowTraversal(previousVertex, currentVertex, nextVertex)) {
|
|
39
|
+
depthFirstSearchRecursive(graph, nextVertex, currentVertex, callbacks);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
callbacks.leaveVertex(currentVertex, previousVertex);
|
|
43
|
+
}
|
|
44
|
+
function depthFirstSearch(graph, startVertex, callbacks) {
|
|
45
|
+
var previousVertex = null;
|
|
46
|
+
depthFirstSearchRecursive(graph, startVertex, previousVertex, initCallbacks(callbacks));
|
|
47
|
+
}
|
|
48
|
+
exports.depthFirstSearch = depthFirstSearch;
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/algorithms/graph/depth-first-search/index.ts"],"names":[],"mappings":";;;AAGA;;;GAGG;AACH,SAAS,aAAa,CAAC,SAAoB;IACzC,IAAM,iBAAiB,GAAc,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAElE,gEAAgE;IAChE,IAAM,YAAY,GAAG,cAAO,CAAC,CAAC;IAE9B,IAAM,sBAAsB,GAAG,CAAC;QAC9B,IAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,OAAO,UAAC,eAA4B,EAAE,cAA2B,EAAE,UAAuB;YACxF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE;gBAC9B,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;gBACjC,OAAO,IAAI,CAAC;aACb;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;IACJ,CAAC,CAAC,EAAE,CAAC;IAEL,iBAAiB,CAAC,cAAc,GAAG,SAAS,CAAC,cAAc,IAAI,sBAAsB,CAAC;IACtF,iBAAiB,CAAC,WAAW,GAAG,SAAS,CAAC,WAAW,IAAI,YAAY,CAAC;IACtE,iBAAiB,CAAC,WAAW,GAAG,SAAS,CAAC,WAAW,IAAI,YAAY,CAAC;IAEtE,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAChC,KAAY,EACZ,aAA0B,EAC1B,cAAkC,EAClC,SAAoB;IAEpB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE;QACzD,OAAO;KACR;IAED,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,UAAC,UAAuB;QAChE,IAAI,SAAS,CAAC,cAAc,CAAC,cAAc,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE;YACvE,yBAAyB,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;SACxE;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;AACvD,CAAC;AAgBD,SAAgB,gBAAgB,CAC9B,KAAY,EACZ,WAAwB,EACxB,SAAoB;IAEpB,IAAM,cAAc,GAAG,IAAI,CAAC;IAC5B,yBAAyB,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;AAC1F,CAAC;AAPD,4CAOC"}
|