fcdns 0.5.10 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/cli.js +113 -0
  2. package/lib/cli.js.map +1 -0
  3. package/lib/dao/clear.js +8 -0
  4. package/lib/dao/clear.js.map +1 -0
  5. package/lib/dao/get-poison-test-result.js +18 -0
  6. package/lib/dao/get-poison-test-result.js.map +1 -0
  7. package/lib/dao/get-route-result.js +19 -0
  8. package/lib/dao/get-route-result.js.map +1 -0
  9. package/lib/dao/upsert-poison-test-result.js +14 -0
  10. package/lib/dao/upsert-poison-test-result.js.map +1 -0
  11. package/lib/dao/upsert-route-result.js +14 -0
  12. package/lib/dao/upsert-route-result.js.map +1 -0
  13. package/lib/database.js +44 -0
  14. package/lib/database.js.map +1 -0
  15. package/lib/hostnames.js +25 -0
  16. package/lib/hostnames.js.map +1 -0
  17. package/lib/ip-ranges.js +77 -0
  18. package/lib/ip-ranges.js.map +1 -0
  19. package/lib/poison-tester.js +55 -0
  20. package/lib/poison-tester.js.map +1 -0
  21. package/lib/record-types.js +77 -0
  22. package/lib/record-types.js.map +1 -0
  23. package/lib/router.js +63 -0
  24. package/lib/router.js.map +1 -0
  25. package/lib/server.js +88 -0
  26. package/lib/server.js.map +1 -0
  27. package/lib/utils/create-dns-resolver.js +7 -0
  28. package/lib/utils/create-dns-resolver.js.map +1 -0
  29. package/lib/utils/hostname-pattern.js +11 -0
  30. package/lib/utils/hostname-pattern.js.map +1 -0
  31. package/lib/utils/is-ipv4-address.js +4 -0
  32. package/lib/utils/is-ipv4-address.js.map +1 -0
  33. package/lib/utils/is-ipv6-address.js +4 -0
  34. package/lib/utils/is-ipv6-address.js.map +1 -0
  35. package/lib/utils/is-server-online.js +21 -0
  36. package/lib/utils/is-server-online.js.map +1 -0
  37. package/lib/utils/package.js +16 -0
  38. package/lib/utils/package.js.map +1 -0
  39. package/lib/utils/parse-server-info.js +8 -0
  40. package/lib/utils/parse-server-info.js.map +1 -0
  41. package/lib/utils/resolve-a.js +14 -0
  42. package/lib/utils/resolve-a.js.map +1 -0
  43. package/package.json +56 -54
  44. package/dist/cli.cjs +0 -48324
package/lib/cli.js ADDED
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import { startServer } from './server.js';
4
+ import { Router } from './router.js';
5
+ import { IPRanges } from './ip-ranges.js';
6
+ import { Hostnames } from './hostnames.js';
7
+ import { PoisonTester } from './poison-tester.js';
8
+ import { createDNSResolver } from "./utils/create-dns-resolver.js";
9
+ import { assert } from '@blackglory/prelude';
10
+ import { Level, Logger, TerminalTransport, stringToLevel } from 'extra-logger';
11
+ import { parseServerInfo } from "./utils/parse-server-info.js";
12
+ import { youDied } from 'you-died';
13
+ import * as Database from './database.js';
14
+ import { name, version, description } from "./utils/package.js";
15
+ process.title = name;
16
+ program
17
+ .name(name)
18
+ .version(version)
19
+ .description(description)
20
+ .requiredOption('--test-server <server>')
21
+ .requiredOption('--untrusted-server <server>')
22
+ .requiredOption('--trusted-server <server>')
23
+ .option('--port <port>', '', '53')
24
+ .option('--timeout <seconds>', '', '30')
25
+ .option('--ip-whitelist <filename>', '', 'ip-whitelist.txt')
26
+ .option('--hostname-whitelist <filename>', '', 'hostname-whitelist.txt')
27
+ .option('--hostname-blacklist <filename>', '', 'hostname-blacklist.txt')
28
+ .option('--cache <filename>', '', 'cache.db')
29
+ .option('--test-timeout <milliseconds>', '', '200')
30
+ .option('--log <level>', '', 'info')
31
+ .action(async () => {
32
+ const options = program.opts();
33
+ const cacheFilename = getCacheFilename(options);
34
+ const testServer = getTestServer(options);
35
+ const testTimeout = getTestTimeout(options);
36
+ const timeout = getTimeout(options);
37
+ const port = getPort(options);
38
+ const logLevel = getLogLevel(options);
39
+ const ipWhitelistFilename = getIpWhiltelistFilename(options);
40
+ const hostnameWhitelistFilename = getHostnameWhitelistFilename(options);
41
+ const hostnameBlacklistFilename = getHostnameBlacklistFilename(options);
42
+ const untrustedServer = getUntrustedServer(options);
43
+ const trustedServer = getTrustedServer(options);
44
+ Database.openDatabase(cacheFilename);
45
+ await Database.prepareDatabase();
46
+ youDied(() => Database.closeDatabase());
47
+ const poisonTester = new PoisonTester({
48
+ server: testServer,
49
+ timeout: testTimeout
50
+ });
51
+ const untrustedResolver = createDNSResolver(untrustedServer.host
52
+ + (untrustedServer.port ? `:${untrustedServer.port}` : ''));
53
+ const ipWhitelist = await IPRanges.fromFile(ipWhitelistFilename);
54
+ const hostnameWhitelist = await Hostnames.fromFile(hostnameWhitelistFilename);
55
+ const hostnameBlacklist = await Hostnames.fromFile(hostnameBlacklistFilename);
56
+ const router = new Router({
57
+ poisonTester,
58
+ untrustedResolver,
59
+ ipWhitelist,
60
+ hostnameWhitelist,
61
+ hostnameBlacklist
62
+ });
63
+ const logger = new Logger({
64
+ level: logLevel,
65
+ transport: new TerminalTransport({})
66
+ });
67
+ startServer({
68
+ router,
69
+ logger,
70
+ trustedServer,
71
+ untrustedServer,
72
+ timeout,
73
+ port
74
+ });
75
+ })
76
+ .parse();
77
+ function getTestServer(options) {
78
+ return options.testServer;
79
+ }
80
+ function getUntrustedServer(options) {
81
+ return parseServerInfo(options.untrustedServer);
82
+ }
83
+ function getTrustedServer(options) {
84
+ return parseServerInfo(options.trustedServer);
85
+ }
86
+ function getPort(options) {
87
+ assert(/^\d+$/.test(options.port), 'The parameter port must be integer');
88
+ return Number.parseInt(options.port, 10);
89
+ }
90
+ function getTimeout(options) {
91
+ assert(/^\d+$/.test(options.timeout), 'The parameter timeout must be integer');
92
+ return Number.parseInt(options.port, 10) * 1000;
93
+ }
94
+ function getIpWhiltelistFilename(options) {
95
+ return options.ipWhitelist;
96
+ }
97
+ function getHostnameWhitelistFilename(options) {
98
+ return options.hostnameWhitelist;
99
+ }
100
+ function getHostnameBlacklistFilename(options) {
101
+ return options.hostnameBlacklist;
102
+ }
103
+ function getCacheFilename(options) {
104
+ return options.cache;
105
+ }
106
+ function getTestTimeout(options) {
107
+ assert(/^\d+$/.test(options.testTimeout), 'The parameter test timeout must be integer');
108
+ return Number.parseInt(options.testTimeout, 10);
109
+ }
110
+ function getLogLevel(options) {
111
+ return stringToLevel(options.log, Level.Info);
112
+ }
113
+ //# sourceMappingURL=cli.js.map
package/lib/cli.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { getDatabase } from "../database.js";
2
+ import { withLazyStatic, lazyStatic } from 'extra-lazy';
3
+ export const clear = withLazyStatic(function () {
4
+ lazyStatic(() => getDatabase().prepare(`
5
+ DELETE FROM hostname
6
+ `), [getDatabase()]).run();
7
+ });
8
+ //# sourceMappingURL=clear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clear.js","sourceRoot":"","sources":["../../src/dao/clear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAwB;AAC9C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,CAAC,MAAM,KAAK,GAAG,cAAc,CAAC;IAClC,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC;;GAEtC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAA;AAC5B,CAAC,CAAC,CAAA"}
@@ -0,0 +1,18 @@
1
+ import { getDatabase } from "../database.js";
2
+ import { PoisonTestResult } from "../poison-tester.js";
3
+ import { withLazyStatic, lazyStatic } from 'extra-lazy';
4
+ export const getPoisonResult = withLazyStatic((hostname) => {
5
+ const row = lazyStatic(() => getDatabase()
6
+ .prepare(`
7
+ SELECT poison_test_result
8
+ FROM hostname
9
+ WHERE hostname = $hostname
10
+ `), [getDatabase()])
11
+ .get({ hostname });
12
+ switch (row === null || row === void 0 ? void 0 : row.poison_test_result) {
13
+ case PoisonTestResult.Poisoned: return PoisonTestResult.Poisoned;
14
+ case PoisonTestResult.NotPoisoned: return PoisonTestResult.NotPoisoned;
15
+ default: return null;
16
+ }
17
+ });
18
+ //# sourceMappingURL=get-poison-test-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-poison-test-result.js","sourceRoot":"","sources":["../../src/dao/get-poison-test-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAwB;AAC9C,OAAO,EAAE,gBAAgB,EAAE,4BAA6B;AACxD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAC,CAAC,QAAgB,EAA2B,EAAE;IAC1F,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;SACvC,OAAO,CAAC;;;;KAIR,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;SACnB,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAsD,CAAA;IAEzE,QAAQ,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,kBAAkB,EAAE,CAAC;QAChC,KAAK,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,gBAAgB,CAAC,QAAQ,CAAA;QAChE,KAAK,gBAAgB,CAAC,WAAW,CAAC,CAAC,OAAO,gBAAgB,CAAC,WAAW,CAAA;QACtE,OAAO,CAAC,CAAC,OAAO,IAAI,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import { getDatabase } from "../database.js";
2
+ import { RouteResult } from "../router.js";
3
+ import { withLazyStatic, lazyStatic } from 'extra-lazy';
4
+ export const getRouteResult = withLazyStatic((hostname) => {
5
+ const row = lazyStatic(() => getDatabase()
6
+ .prepare(`
7
+ SELECT route_result
8
+ FROM hostname
9
+ WHERE hostname = $hostname
10
+ `), [getDatabase()])
11
+ .get({ hostname });
12
+ switch (row === null || row === void 0 ? void 0 : row.route_result) {
13
+ case RouteResult.Unresolved: return RouteResult.Unresolved;
14
+ case RouteResult.TrustedServer: return RouteResult.TrustedServer;
15
+ case RouteResult.UntrustedServer: return RouteResult.UntrustedServer;
16
+ default: return null;
17
+ }
18
+ });
19
+ //# sourceMappingURL=get-route-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-route-result.js","sourceRoot":"","sources":["../../src/dao/get-route-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAwB;AAC9C,OAAO,EAAE,WAAW,EAAE,qBAAsB;AAC5C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,QAAgB,EAAsB,EAAE;IACpF,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;SACvC,OAAO,CAAC;;;;KAIR,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;SACnB,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAgD,CAAA;IAEnE,QAAQ,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,YAAY,EAAE,CAAC;QAC1B,KAAK,WAAW,CAAC,UAAU,CAAC,CAAC,OAAO,WAAW,CAAC,UAAU,CAAA;QAC1D,KAAK,WAAW,CAAC,aAAa,CAAC,CAAC,OAAO,WAAW,CAAC,aAAa,CAAA;QAChE,KAAK,WAAW,CAAC,eAAe,CAAC,CAAC,OAAO,WAAW,CAAC,eAAe,CAAA;QACpE,OAAO,CAAC,CAAC,OAAO,IAAI,CAAA;IACtB,CAAC;AACH,CAAC,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { getDatabase } from "../database.js";
2
+ import { withLazyStatic, lazyStatic } from 'extra-lazy';
3
+ export const upsertPoisonTestResult = withLazyStatic(function (hostname, result) {
4
+ lazyStatic(() => getDatabase().prepare(`
5
+ INSERT INTO hostname (
6
+ hostname
7
+ , poison_test_result
8
+ )
9
+ VALUES ($hostname, $result)
10
+ ON CONFLICT(hostname)
11
+ DO UPDATE SET poison_test_result = $result
12
+ `), [getDatabase()]).run({ hostname, result });
13
+ });
14
+ //# sourceMappingURL=upsert-poison-test-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert-poison-test-result.js","sourceRoot":"","sources":["../../src/dao/upsert-poison-test-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAwB;AAE9C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,CAAC,MAAM,sBAAsB,GAAG,cAAc,CAAC,UACnD,QAAgB,EAChB,MAAwB;IAExB,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC;;;;;;;;GAQtC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;AAChD,CAAC,CAAC,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { getDatabase } from "../database.js";
2
+ import { withLazyStatic, lazyStatic } from 'extra-lazy';
3
+ export const upsertRouteResult = withLazyStatic(function (hostname, routeResult) {
4
+ lazyStatic(() => getDatabase().prepare(`
5
+ INSERT INTO hostname (
6
+ hostname
7
+ , route_result
8
+ )
9
+ VALUES ($hostname, $routeResult)
10
+ ON CONFLICT(hostname)
11
+ DO UPDATE SET route_result = $routeResult
12
+ `), [getDatabase()]).run({ hostname, routeResult });
13
+ });
14
+ //# sourceMappingURL=upsert-route-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert-route-result.js","sourceRoot":"","sources":["../../src/dao/upsert-route-result.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,uBAAwB;AAE9C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvD,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,UAC9C,QAAgB,EAChB,WAAwB;IAExB,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC;;;;;;;;GAQtC,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAA;AACrD,CAAC,CAAC,CAAA"}
@@ -0,0 +1,44 @@
1
+ import Database from 'better-sqlite3';
2
+ import path from 'path';
3
+ import { ensureDirSync, findUpPackageFilename } from 'extra-filesystem';
4
+ import { assert } from '@blackglory/errors';
5
+ import { findMigrationFilenames, readMigrationFile } from 'migration-files';
6
+ import { migrate } from '@blackglory/better-sqlite3-migrations';
7
+ import { isntUndefined } from '@blackglory/prelude';
8
+ import { map } from 'extra-promise';
9
+ import { fileURLToPath } from 'url';
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ let db;
12
+ export function openDatabase(filename) {
13
+ if (isntUndefined(filename)) {
14
+ ensureDirSync(path.dirname(filename));
15
+ db = new Database(filename);
16
+ }
17
+ else {
18
+ db = new Database(':memory:');
19
+ }
20
+ }
21
+ export async function prepareDatabase() {
22
+ assert(db, 'Database is not opened');
23
+ await migrateDatabase(db);
24
+ }
25
+ export function getDatabase() {
26
+ assert(db, 'Database is not opened');
27
+ return db;
28
+ }
29
+ export function closeDatabase() {
30
+ if (db) {
31
+ db.exec(`
32
+ PRAGMA analysis_limit=400;
33
+ PRAGMA optimize;
34
+ `);
35
+ db.close();
36
+ }
37
+ }
38
+ async function migrateDatabase(db) {
39
+ const pkgRoot = path.join((await findUpPackageFilename(__dirname)), '..');
40
+ const migrationsPath = path.join(pkgRoot, 'migrations');
41
+ const migrations = await map(await findMigrationFilenames(migrationsPath), readMigrationFile);
42
+ migrate(db, migrations);
43
+ }
44
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAErC,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,uCAAuC,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAEnC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D,IAAI,EAAa,CAAA;AAEjB,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;QAErC,EAAE,GAAG,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;SAAM,CAAC;QACN,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAA;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAA;IACpC,MAAM,eAAe,CAAC,EAAE,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAA;IACpC,OAAO,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,IAAI,CAAC;;;KAGP,CAAC,CAAA;QACF,EAAE,CAAC,KAAK,EAAE,CAAA;IACZ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,EAAa;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAE,EAAE,IAAI,CAAC,CAAA;IAC1E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACvD,MAAM,UAAU,GAAG,MAAM,GAAG,CAC1B,MAAM,sBAAsB,CAAC,cAAc,CAAC,EAC5C,iBAAiB,CAClB,CAAA;IACD,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;AACzB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { promises as fs } from 'fs';
2
+ import { HostnamePattern } from "./utils/hostname-pattern.js";
3
+ import { ensureFile } from 'extra-filesystem';
4
+ export class Hostnames {
5
+ constructor(patterns) {
6
+ this.patterns = patterns;
7
+ }
8
+ static async fromFile(filename) {
9
+ await ensureFile(filename);
10
+ const text = await fs.readFile(filename, 'utf-8');
11
+ const patterns = text.split('\n')
12
+ .map(x => x.trim())
13
+ .filter(x => x !== '')
14
+ .filter(isHostnamePattern)
15
+ .map(x => new HostnamePattern(x));
16
+ return new Hostnames(patterns);
17
+ }
18
+ includes(hostname) {
19
+ return this.patterns.some(x => x.match(hostname));
20
+ }
21
+ }
22
+ function isHostnamePattern(text) {
23
+ return /^[\da-zA-Z\-.*]+$/.test(text);
24
+ }
25
+ //# sourceMappingURL=hostnames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostnames.js","sourceRoot":"","sources":["../src/hostnames.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,oCAAkC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,OAAO,SAAS;IACpB,YAAoB,QAA2B;QAA3B,aAAQ,GAAR,QAAQ,CAAmB;IAAG,CAAC;IAEnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAgB;QACpC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;QAE1B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;aACrB,MAAM,CAAC,iBAAiB,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;QAEnC,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC;IAED,QAAQ,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IACnD,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACvC,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { IPv4AddressRange, IPv6AddressRange } from 'address-range';
2
+ import { isIPv4Address } from "./utils/is-ipv4-address.js";
3
+ import { isIPv6Address } from "./utils/is-ipv6-address.js";
4
+ import { promises as fs } from 'fs';
5
+ import { groupBy } from 'iterable-operator';
6
+ export class IPRanges {
7
+ constructor(...args) {
8
+ if (args.length === 1) {
9
+ const [ranges] = args;
10
+ const groups = groupBy(ranges, element => {
11
+ if (element instanceof IPv4AddressRange) {
12
+ return 'ipv4';
13
+ }
14
+ else {
15
+ return 'ipv6';
16
+ }
17
+ });
18
+ this.ipv4 = groups.get('ipv4');
19
+ this.ipv6 = groups.get('ipv6');
20
+ }
21
+ else {
22
+ const [ipv4, ipv6] = args;
23
+ this.ipv4 = ipv4;
24
+ this.ipv6 = ipv6;
25
+ }
26
+ }
27
+ static async fromFile(filename) {
28
+ const ipv4 = [];
29
+ const ipv6 = [];
30
+ const text = await fs.readFile(filename, 'utf-8');
31
+ text.split('\n')
32
+ .filter(x => x.trim())
33
+ .filter(x => x !== '')
34
+ .forEach(x => {
35
+ if (isIPv4Address(x)) {
36
+ ipv4.push(IPv4AddressRange.from(x, x));
37
+ }
38
+ if (isIPv6Address(x)) {
39
+ ipv6.push(IPv6AddressRange.from(x, x));
40
+ }
41
+ if (isIPv4AddressRange(x)) {
42
+ const [startAddress, endAddress] = x.split('-');
43
+ ipv4.push(IPv4AddressRange.from(startAddress, endAddress));
44
+ }
45
+ if (isIPv6AddressRange(x)) {
46
+ const [startAddress, endAddress] = x.split('-');
47
+ ipv6.push(IPv6AddressRange.from(startAddress, endAddress));
48
+ }
49
+ });
50
+ return new IPRanges(ipv4, ipv6);
51
+ }
52
+ async toFile(filename) {
53
+ const ipv4 = this.ipv4
54
+ .map(range => range.toString())
55
+ .join('\n');
56
+ const ipv6 = this.ipv6
57
+ .map(range => range.toString())
58
+ .join('\n');
59
+ await fs.writeFile(filename, [ipv4, ipv6].join('\n'));
60
+ }
61
+ includes(address) {
62
+ if (isIPv4Address(address)) {
63
+ return this.ipv4.some(x => x.includes(address));
64
+ }
65
+ if (isIPv6Address(address)) {
66
+ return this.ipv6.some(x => x.includes(address));
67
+ }
68
+ return false;
69
+ }
70
+ }
71
+ function isIPv4AddressRange(text) {
72
+ return /^[\d\.]+-[\d\.]+$/.test(text);
73
+ }
74
+ function isIPv6AddressRange(text) {
75
+ return /^[\da-f:]+-[\da-f:]+$/.test(text);
76
+ }
77
+ //# sourceMappingURL=ip-ranges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-ranges.js","sourceRoot":"","sources":["../src/ip-ranges.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { isServerOnline } from "./utils/is-server-online.js";
2
+ import { createDNSResolver } from "./utils/create-dns-resolver.js";
3
+ import { resolveA } from "./utils/resolve-a.js";
4
+ import { CustomError } from '@blackglory/errors';
5
+ import { isSuccessPromise } from 'return-style';
6
+ import { isntNull } from '@blackglory/prelude';
7
+ import { getPoisonResult } from "./dao/get-poison-test-result.js";
8
+ import { upsertPoisonTestResult } from "./dao/upsert-poison-test-result.js";
9
+ export var PoisonTestResult;
10
+ (function (PoisonTestResult) {
11
+ PoisonTestResult[PoisonTestResult["NotPoisoned"] = 0] = "NotPoisoned";
12
+ PoisonTestResult[PoisonTestResult["Poisoned"] = 1] = "Poisoned";
13
+ })(PoisonTestResult || (PoisonTestResult = {}));
14
+ export class ServerUnreachable extends CustomError {
15
+ constructor() {
16
+ super('The test server is unreachable or not sending a echo reply in time');
17
+ }
18
+ }
19
+ export class PoisonTester {
20
+ constructor(options) {
21
+ this.server = options.server;
22
+ this.timeout = options.timeout;
23
+ this.testResolver = createDNSResolver(this.server);
24
+ }
25
+ async isHostnamePoisoned(hostname) {
26
+ const result = getPoisonResult(hostname);
27
+ if (isntNull(result)) {
28
+ return poisonTestResultToIsPoisoned(result);
29
+ }
30
+ else {
31
+ const [alive, poisoned] = await Promise.all([
32
+ isServerOnline(this.server, this.timeout),
33
+ isSuccessPromise(resolveA(this.testResolver, hostname, this.timeout))
34
+ ]);
35
+ if (alive) {
36
+ const result = poisoned
37
+ ? PoisonTestResult.Poisoned
38
+ : PoisonTestResult.NotPoisoned;
39
+ upsertPoisonTestResult(hostname, result);
40
+ return poisonTestResultToIsPoisoned(result);
41
+ }
42
+ else {
43
+ throw new ServerUnreachable();
44
+ }
45
+ }
46
+ }
47
+ }
48
+ function poisonTestResultToIsPoisoned(result) {
49
+ switch (result) {
50
+ case PoisonTestResult.Poisoned: return true;
51
+ case PoisonTestResult.NotPoisoned: return false;
52
+ default: throw new Error('Unknown poision test result');
53
+ }
54
+ }
55
+ //# sourceMappingURL=poison-tester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poison-tester.js","sourceRoot":"","sources":["../src/poison-tester.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,oCAAkC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,uCAAqC;AACjE,OAAO,EAAE,QAAQ,EAAE,6BAA2B;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE9C,OAAO,EAAE,eAAe,EAAE,wCAAsC;AAChE,OAAO,EAAE,sBAAsB,EAAE,2CAAyC;AAE1E,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,qEAAe,CAAA;IACf,+DAAY,CAAA;AACd,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IAChD;QACE,KAAK,CAAC,oEAAoE,CAAC,CAAA;IAC7E,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IAKvB,YAAY,OAGX;QACC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAA;QAC9B,IAAI,CAAC,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACpD,CAAC;IAKD,KAAK,CAAC,kBAAkB,CAAC,QAAgB;QACvC,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAA;QACxC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,4BAA4B,CAAC,MAAM,CAAC,CAAA;QAC7C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC1C,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC;gBACzC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;aACtE,CAAC,CAAA;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,MAAM,GAAG,QAAQ;oBACrB,CAAC,CAAC,gBAAgB,CAAC,QAAQ;oBAC3B,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAA;gBAChC,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;gBACxC,OAAO,4BAA4B,CAAC,MAAM,CAAC,CAAA;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,iBAAiB,EAAE,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,SAAS,4BAA4B,CAAC,MAAwB;IAC5D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,gBAAgB,CAAC,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAA;QAC3C,KAAK,gBAAgB,CAAC,WAAW,CAAC,CAAC,OAAO,KAAK,CAAA;QAC/C,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IACzD,CAAC;AACH,CAAC"}
@@ -0,0 +1,77 @@
1
+ export var RecordType;
2
+ (function (RecordType) {
3
+ RecordType[RecordType["A"] = 1] = "A";
4
+ RecordType[RecordType["NS"] = 2] = "NS";
5
+ RecordType[RecordType["MD"] = 3] = "MD";
6
+ RecordType[RecordType["MF"] = 4] = "MF";
7
+ RecordType[RecordType["CNAME"] = 5] = "CNAME";
8
+ RecordType[RecordType["SOA"] = 6] = "SOA";
9
+ RecordType[RecordType["MB"] = 7] = "MB";
10
+ RecordType[RecordType["MG"] = 8] = "MG";
11
+ RecordType[RecordType["MR"] = 9] = "MR";
12
+ RecordType[RecordType["NULL"] = 10] = "NULL";
13
+ RecordType[RecordType["WKS"] = 11] = "WKS";
14
+ RecordType[RecordType["PTR"] = 12] = "PTR";
15
+ RecordType[RecordType["HINFO"] = 13] = "HINFO";
16
+ RecordType[RecordType["MINFO"] = 14] = "MINFO";
17
+ RecordType[RecordType["MX"] = 15] = "MX";
18
+ RecordType[RecordType["TXT"] = 16] = "TXT";
19
+ RecordType[RecordType["RP"] = 17] = "RP";
20
+ RecordType[RecordType["AFSDB"] = 18] = "AFSDB";
21
+ RecordType[RecordType["X25"] = 19] = "X25";
22
+ RecordType[RecordType["ISDN"] = 20] = "ISDN";
23
+ RecordType[RecordType["RT"] = 21] = "RT";
24
+ RecordType[RecordType["NSAP"] = 22] = "NSAP";
25
+ RecordType[RecordType["NSAP-PTR"] = 23] = "NSAP-PTR";
26
+ RecordType[RecordType["SIG"] = 24] = "SIG";
27
+ RecordType[RecordType["KEY"] = 25] = "KEY";
28
+ RecordType[RecordType["PX"] = 26] = "PX";
29
+ RecordType[RecordType["GPOS"] = 27] = "GPOS";
30
+ RecordType[RecordType["AAAA"] = 28] = "AAAA";
31
+ RecordType[RecordType["LOC"] = 29] = "LOC";
32
+ RecordType[RecordType["NXT"] = 30] = "NXT";
33
+ RecordType[RecordType["EID"] = 31] = "EID";
34
+ RecordType[RecordType["NIMLOC"] = 32] = "NIMLOC";
35
+ RecordType[RecordType["SRV"] = 33] = "SRV";
36
+ RecordType[RecordType["ATMA"] = 34] = "ATMA";
37
+ RecordType[RecordType["NAPTR"] = 35] = "NAPTR";
38
+ RecordType[RecordType["KX"] = 36] = "KX";
39
+ RecordType[RecordType["CERT"] = 37] = "CERT";
40
+ RecordType[RecordType["A6"] = 38] = "A6";
41
+ RecordType[RecordType["DNAME"] = 39] = "DNAME";
42
+ RecordType[RecordType["SINK"] = 40] = "SINK";
43
+ RecordType[RecordType["OPT"] = 41] = "OPT";
44
+ RecordType[RecordType["APL"] = 42] = "APL";
45
+ RecordType[RecordType["DS"] = 43] = "DS";
46
+ RecordType[RecordType["SSHFP"] = 44] = "SSHFP";
47
+ RecordType[RecordType["IPSECKEY"] = 45] = "IPSECKEY";
48
+ RecordType[RecordType["RRSIG"] = 46] = "RRSIG";
49
+ RecordType[RecordType["NSEC"] = 47] = "NSEC";
50
+ RecordType[RecordType["DNSKEY"] = 48] = "DNSKEY";
51
+ RecordType[RecordType["DHCID"] = 49] = "DHCID";
52
+ RecordType[RecordType["NSEC3"] = 50] = "NSEC3";
53
+ RecordType[RecordType["NSEC3PARAM"] = 51] = "NSEC3PARAM";
54
+ RecordType[RecordType["TLSA"] = 52] = "TLSA";
55
+ RecordType[RecordType["HIP"] = 55] = "HIP";
56
+ RecordType[RecordType["NINFO"] = 56] = "NINFO";
57
+ RecordType[RecordType["RKEY"] = 57] = "RKEY";
58
+ RecordType[RecordType["TALINK"] = 58] = "TALINK";
59
+ RecordType[RecordType["CDS"] = 59] = "CDS";
60
+ RecordType[RecordType["SPF"] = 99] = "SPF";
61
+ RecordType[RecordType["UINFO"] = 100] = "UINFO";
62
+ RecordType[RecordType["UID"] = 101] = "UID";
63
+ RecordType[RecordType["GID"] = 102] = "GID";
64
+ RecordType[RecordType["UNSPEC"] = 103] = "UNSPEC";
65
+ RecordType[RecordType["TKEY"] = 249] = "TKEY";
66
+ RecordType[RecordType["TSIG"] = 250] = "TSIG";
67
+ RecordType[RecordType["IXFR"] = 251] = "IXFR";
68
+ RecordType[RecordType["AXFR"] = 252] = "AXFR";
69
+ RecordType[RecordType["MAILB"] = 253] = "MAILB";
70
+ RecordType[RecordType["MAILA"] = 254] = "MAILA";
71
+ RecordType[RecordType["ANY"] = 255] = "ANY";
72
+ RecordType[RecordType["URI"] = 256] = "URI";
73
+ RecordType[RecordType["CAA"] = 257] = "CAA";
74
+ RecordType[RecordType["TA"] = 32768] = "TA";
75
+ RecordType[RecordType["DLV"] = 32769] = "DLV";
76
+ })(RecordType || (RecordType = {}));
77
+ //# sourceMappingURL=record-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-types.js","sourceRoot":"","sources":["../src/record-types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,UA0EX;AA1ED,WAAY,UAAU;IACpB,qCAAK,CAAA;IACL,uCAAM,CAAA;IACN,uCAAM,CAAA;IACN,uCAAM,CAAA;IACN,6CAAS,CAAA;IACT,yCAAO,CAAA;IACP,uCAAM,CAAA;IACN,uCAAM,CAAA;IACN,uCAAM,CAAA;IACN,4CAAS,CAAA;IACT,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,8CAAU,CAAA;IACV,8CAAU,CAAA;IACV,wCAAO,CAAA;IACP,0CAAQ,CAAA;IACR,wCAAO,CAAA;IACP,8CAAU,CAAA;IACV,0CAAQ,CAAA;IACR,4CAAS,CAAA;IACT,wCAAO,CAAA;IACP,4CAAS,CAAA;IACT,oDAAe,CAAA;IACf,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,wCAAO,CAAA;IACP,4CAAS,CAAA;IACT,4CAAS,CAAA;IACT,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,gDAAW,CAAA;IACX,0CAAQ,CAAA;IACR,4CAAS,CAAA;IACT,8CAAU,CAAA;IACV,wCAAO,CAAA;IACP,4CAAS,CAAA;IACT,wCAAO,CAAA;IACP,8CAAU,CAAA;IACV,4CAAS,CAAA;IACT,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,wCAAO,CAAA;IACP,8CAAU,CAAA;IACV,oDAAa,CAAA;IACb,8CAAU,CAAA;IACV,4CAAS,CAAA;IACT,gDAAW,CAAA;IACX,8CAAU,CAAA;IACV,8CAAU,CAAA;IACV,wDAAe,CAAA;IACf,4CAAS,CAAA;IACT,0CAAQ,CAAA;IACR,8CAAU,CAAA;IACV,4CAAS,CAAA;IACT,gDAAW,CAAA;IACX,0CAAQ,CAAA;IACR,0CAAQ,CAAA;IACR,+CAAW,CAAA;IACX,2CAAS,CAAA;IACT,2CAAS,CAAA;IACT,iDAAY,CAAA;IACZ,6CAAU,CAAA;IACV,6CAAU,CAAA;IACV,6CAAU,CAAA;IACV,6CAAU,CAAA;IACV,+CAAW,CAAA;IACX,+CAAW,CAAA;IACX,2CAAS,CAAA;IACT,2CAAS,CAAA;IACT,2CAAS,CAAA;IACT,2CAAU,CAAA;IACV,6CAAW,CAAA;AACb,CAAC,EA1EW,UAAU,KAAV,UAAU,QA0ErB"}
package/lib/router.js ADDED
@@ -0,0 +1,63 @@
1
+ import { resolveA } from "./utils/resolve-a.js";
2
+ import { isntNull } from '@blackglory/prelude';
3
+ import { getRouteResult } from "./dao/get-route-result.js";
4
+ import { upsertRouteResult } from "./dao/upsert-route-result.js";
5
+ export var RouteResult;
6
+ (function (RouteResult) {
7
+ RouteResult[RouteResult["UntrustedServer"] = 0] = "UntrustedServer";
8
+ RouteResult[RouteResult["TrustedServer"] = 1] = "TrustedServer";
9
+ RouteResult[RouteResult["Unresolved"] = 2] = "Unresolved";
10
+ })(RouteResult || (RouteResult = {}));
11
+ export class Router {
12
+ constructor(options) {
13
+ this.poisonTester = options.poisonTester;
14
+ this.untrustedResolver = options.untrustedResolver;
15
+ this.ipWhitelist = options.ipWhitelist;
16
+ this.hostnameWhitelist = options.hostnameWhitelist;
17
+ this.hostnameBlacklist = options.hostnameBlacklist;
18
+ }
19
+ async route(hostname) {
20
+ if (this.inHostnameWhitelist(hostname))
21
+ return RouteResult.UntrustedServer;
22
+ if (this.inHostnameBlacklist(hostname))
23
+ return RouteResult.TrustedServer;
24
+ const result = getRouteResult(hostname);
25
+ if (isntNull(result)) {
26
+ return result;
27
+ }
28
+ else {
29
+ const result = await this.resolveRoute(hostname);
30
+ upsertRouteResult(hostname, result);
31
+ return result;
32
+ }
33
+ }
34
+ async resolveRoute(hostname) {
35
+ if (await this.poisonTester.isHostnamePoisoned(hostname)) {
36
+ return RouteResult.TrustedServer;
37
+ }
38
+ else {
39
+ const addresses = await resolveA(this.untrustedResolver, hostname);
40
+ if (addresses.length > 0) {
41
+ if (this.inIPWhitelist(addresses)) {
42
+ return RouteResult.UntrustedServer;
43
+ }
44
+ else {
45
+ return RouteResult.TrustedServer;
46
+ }
47
+ }
48
+ else {
49
+ return RouteResult.Unresolved;
50
+ }
51
+ }
52
+ }
53
+ inIPWhitelist(addresses) {
54
+ return addresses.some(x => this.ipWhitelist.includes(x));
55
+ }
56
+ inHostnameWhitelist(hostname) {
57
+ return this.hostnameWhitelist.includes(hostname);
58
+ }
59
+ inHostnameBlacklist(hostname) {
60
+ return this.hostnameBlacklist.includes(hostname);
61
+ }
62
+ }
63
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,6BAA2B;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,kCAAgC;AACzD,OAAO,EAAE,iBAAiB,EAAE,qCAAmC;AAE/D,MAAM,CAAN,IAAY,WAIX;AAJD,WAAY,WAAW;IACrB,mEAAmB,CAAA;IACnB,+DAAiB,CAAA;IACjB,yDAAc,CAAA;AAChB,CAAC,EAJW,WAAW,KAAX,WAAW,QAItB;AAED,MAAM,OAAO,MAAM;IAOjB,YAAY,OAMX;QACC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;QACxC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAA;QAClD,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QACtC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAA;QAClD,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAA;IACpD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC1B,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;YAAE,OAAO,WAAW,CAAC,eAAe,CAAA;QAC1E,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;YAAE,OAAO,WAAW,CAAC,aAAa,CAAA;QAExE,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;QACvC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,MAAM,CAAA;QACf,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;YAChD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YACnC,OAAO,MAAM,CAAA;QACf,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,QAAgB;QACzC,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,OAAO,WAAW,CAAC,aAAa,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAA;YAClE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;oBAClC,OAAO,WAAW,CAAC,eAAe,CAAA;gBACpC,CAAC;qBAAM,CAAC;oBACN,OAAO,WAAW,CAAC,aAAa,CAAA;gBAClC,CAAC;YACH,CAAC;iBAAM,CAAC;gBAEN,OAAO,WAAW,CAAC,UAAU,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,SAAmB;QACvC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1D,CAAC;IAEO,mBAAmB,CAAC,QAAgB;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAClD,CAAC;IAEO,mBAAmB,CAAC,QAAgB;QAC1C,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAClD,CAAC;CACF"}