'use strict';const require$$0=require('foxts/append-set-elements-to-array'),require$$2=require('foxts/noop'),misc=require('./misc.BpcQjda1.cjs'),fetchRetry=require('./fetch-retry.D06uBUaW.cjs'),require$$4=require('json-stringify-pretty-compact'),trie=require('./trie.Vu1FNyv-.cjs'),require$$6=require('foxts/guard'),require$$2$2=require('fast-cidr-tools'),require$$3=require('foxts/retrie'),require$$0$2=require('node:path'),createFile=require('./create-file.loOMbJEN.cjs'),require$$2$1=require('foxts/is-probably-ip'),require$$0$1=require('picocolors'),normalizeDomain=require('./normalize-domain.Cfz4j8eP.cjs');var description = {};var hasRequiredDescription; function requireDescription () { if (hasRequiredDescription) return description; hasRequiredDescription = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { SHARED_DESCRIPTION: function() { return SHARED_DESCRIPTION; }, createFileDescription: function() { return createFileDescription; } }); function createFileDescription(license = 'AGPL 3.0') { return [ `License: ${license}`, 'Homepage: https://ruleset.skk.moe', 'GitHub: https://github.com/SukkaW/Surge' ]; } const SHARED_DESCRIPTION = createFileDescription('AGPL 3.0'); } (description)); return description; }var base$1 = {};var hasRequiredBase$1; function requireBase$1 () { if (hasRequiredBase$1) return base$1; hasRequiredBase$1 = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "BaseWriteStrategy", { enumerable: true, get: function() { return BaseWriteStrategy; } }); const _createfile = /*@__PURE__*/ createFile.r(); class BaseWriteStrategy { outputDir; /** * Sometimes a ruleset will create extra files (e.g. reject-url-regex w/ mitm.sgmodule), * and doesn't share the same filename and id. This property is used to overwrite the filename. */ overwriteFilename; withFilename(filename) { this.overwriteFilename = filename; return this; } constructor(outputDir){ this.outputDir = outputDir; this.overwriteFilename = null; } static domainWildCardToRegex = (domain)=>{ let result = '^'; for(let i = 0, len = domain.length; i < len; i++){ switch(domain[i]){ case '.': result += String.raw`\.`; break; case '*': result += String.raw`[\w.-]*?`; break; case '?': result += String.raw`[\w.-]`; break; default: result += domain[i]; } } result += '$'; return result; }; output(span, title, description, date, filePath) { if (!this.result) { return; } return (0, _createfile.compareAndWriteFile)(span, this.withPadding(title, description, date, this.result), filePath); } get content() { return this.result; } } } (base$1)); return base$1; }var clash = {};var appendArrayInPlace = {};var hasRequiredAppendArrayInPlace; function requireAppendArrayInPlace () { if (hasRequiredAppendArrayInPlace) return appendArrayInPlace; hasRequiredAppendArrayInPlace = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { appendArrayInPlace: function() { return appendArrayInPlace; }, appendArrayInPlaceCurried: function() { return appendArrayInPlaceCurried; } }); const MAX_BLOCK_SIZE = 65535; // max parameter array size for use in Webkit function appendArrayInPlace(dest, source) { let offset = 0; let itemsLeft = source.length; if (itemsLeft <= MAX_BLOCK_SIZE) { // eslint-disable-next-line prefer-spread -- performance dest.push.apply(dest, source); } else { while(itemsLeft > 0){ const pushCount = itemsLeft > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : itemsLeft; const subSource = source.slice(offset, offset + pushCount); // eslint-disable-next-line prefer-spread -- performance dest.push.apply(dest, subSource); itemsLeft -= pushCount; offset += pushCount; } } return dest; } const appendArrayInPlaceCurried = (dest)=>(source)=>appendArrayInPlace(dest, source); } (appendArrayInPlace)); return appendArrayInPlace; }var hasRequiredClash; function requireClash () { if (hasRequiredClash) return clash; hasRequiredClash = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { ClashClassicRuleSet: function() { return ClashClassicRuleSet; }, ClashDomainSet: function() { return ClashDomainSet; }, ClashIPSet: function() { return ClashIPSet; } }); const _appendsetelementstoarray = require$$0; const _base = /*@__PURE__*/ requireBase$1(); const _noop = require$$2; const _misc = /*@__PURE__*/ misc.r(); const _dir = /*@__PURE__*/ fetchRetry.a(); const _appendarrayinplace = /*@__PURE__*/ requireAppendArrayInPlace(); class ClashDomainSet extends _base.BaseWriteStrategy { outputDir; // readonly type = 'domainset'; fileExtension; type; result; constructor(outputDir = _dir.OUTPUT_CLASH_DIR){ super(outputDir), this.outputDir = outputDir, this.fileExtension = 'txt', this.type = 'domainset', this.result = [ 'this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ], this.withPadding = _misc.withBannerArray, this.writeDomainKeywords = _noop.noop, this.writeDomainWildcards = _noop.noop, this.writeUserAgents = _noop.noop, this.writeProcessNames = _noop.noop, this.writeProcessPaths = _noop.noop, this.writeUrlRegexes = _noop.noop, this.writeIpCidrs = _noop.noop, this.writeIpCidr6s = _noop.noop, this.writeGeoip = _noop.noop, this.writeIpAsns = _noop.noop, this.writeSourceIpCidrs = _noop.noop, this.writeSourcePorts = _noop.noop, this.writeDestinationPorts = _noop.noop, this.writeOtherRules = _noop.noop; } withPadding; writeDomain(domain) { this.result.push(domain); } writeDomainSuffix(domain) { this.result.push('+.' + domain); } writeDomainKeywords; writeDomainWildcards; writeUserAgents; writeProcessNames; writeProcessPaths; writeUrlRegexes; writeIpCidrs; writeIpCidr6s; writeGeoip; writeIpAsns; writeSourceIpCidrs; writeSourcePorts; writeDestinationPorts; writeOtherRules; } class ClashIPSet extends _base.BaseWriteStrategy { outputDir; // readonly type = 'domainset'; fileExtension; type; result; constructor(outputDir = _dir.OUTPUT_CLASH_DIR){ super(outputDir), this.outputDir = outputDir, this.fileExtension = 'txt', this.type = 'ip', this.result = [], this.withPadding = _misc.withBannerArray, this.writeDomain = (0, _misc.notSupported)('writeDomain'), this.writeDomainSuffix = (0, _misc.notSupported)('writeDomainSuffix'), this.writeDomainKeywords = (0, _misc.notSupported)('writeDomainKeywords'), this.writeDomainWildcards = (0, _misc.notSupported)('writeDomainWildcards'), this.writeUserAgents = (0, _misc.notSupported)('writeUserAgents'), this.writeProcessNames = (0, _misc.notSupported)('writeProcessNames'), this.writeProcessPaths = (0, _misc.notSupported)('writeProcessPaths'), this.writeUrlRegexes = (0, _misc.notSupported)('writeUrlRegexes'), this.writeGeoip = (0, _misc.notSupported)('writeGeoip'), this.writeIpAsns = (0, _misc.notSupported)('writeIpAsns'), this.writeSourceIpCidrs = (0, _misc.notSupported)('writeSourceIpCidrs'), this.writeSourcePorts = (0, _misc.notSupported)('writeSourcePorts'), this.writeDestinationPorts = _noop.noop, this.writeOtherRules = _noop.noop; } withPadding; writeDomain; writeDomainSuffix; writeDomainKeywords; writeDomainWildcards; writeUserAgents; writeProcessNames; writeProcessPaths; writeUrlRegexes; writeIpCidrs(ipCidr) { (0, _appendarrayinplace.appendArrayInPlace)(this.result, ipCidr); } writeIpCidr6s(ipCidr6) { (0, _appendarrayinplace.appendArrayInPlace)(this.result, ipCidr6); } writeGeoip; writeIpAsns; writeSourceIpCidrs; writeSourcePorts; writeDestinationPorts; writeOtherRules; } class ClashClassicRuleSet extends _base.BaseWriteStrategy { type; outputDir; fileExtension; result; constructor(type/* | (string & {}) */ , outputDir = _dir.OUTPUT_CLASH_DIR){ super(outputDir), this.type = type, this.outputDir = outputDir, this.fileExtension = 'txt', this.result = [ 'DOMAIN,this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ], this.withPadding = _misc.withBannerArray, this.writeUserAgents = _noop.noop, this.writeUrlRegexes = _noop.noop, this.writeOtherRules = _noop.noop; } withPadding; writeDomain(domain) { this.result.push('DOMAIN,' + domain); } writeDomainSuffix(domain) { this.result.push('DOMAIN-SUFFIX,' + domain); } writeDomainKeywords(keyword) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, keyword, (i)=>`DOMAIN-KEYWORD,${i}`); } writeDomainWildcards(wildcard) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, wildcard, (i)=>`DOMAIN-REGEX,${ClashClassicRuleSet.domainWildCardToRegex(i)}`); } writeUserAgents; writeProcessNames(processName) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, processName, (i)=>`PROCESS-NAME,${i}`); } writeProcessPaths(processPath) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, processPath, (i)=>`PROCESS-PATH,${i}`); } writeUrlRegexes; writeIpCidrs(ipCidr, noResolve) { for(let i = 0, len = ipCidr.length; i < len; i++){ this.result.push(`IP-CIDR,${ipCidr[i]}${noResolve ? ',no-resolve' : ''}`); } } writeIpCidr6s(ipCidr6, noResolve) { for(let i = 0, len = ipCidr6.length; i < len; i++){ this.result.push(`IP-CIDR6,${ipCidr6[i]}${noResolve ? ',no-resolve' : ''}`); } } writeGeoip(geoip, noResolve) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, geoip, (i)=>`GEOIP,${i}${noResolve ? ',no-resolve' : ''}`); } writeIpAsns(asns, noResolve) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, asns, (i)=>`IP-ASN,${i}${noResolve ? ',no-resolve' : ''}`); } writeSourceIpCidrs(sourceIpCidr) { for(let i = 0, len = sourceIpCidr.length; i < len; i++){ const value = sourceIpCidr[i]; if (value.includes('/')) { this.result.push(`SRC-IP-CIDR,${value}`); continue; } const v = (0, _misc.fastIpVersion)(value); if (v === 4) { this.result.push(`SRC-IP-CIDR,${value}/32`); continue; } if (v === 6) { this.result.push(`SRC-IP-CIDR6,${value}/128`); continue; } } } writeSourcePorts(port) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, port, (i)=>`SRC-PORT,${i}`); } writeDestinationPorts(port) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, port, (i)=>`DST-PORT,${i}`); } writeOtherRules; } } (clash)); return clash; }var singbox = {};var hasRequiredSingbox; function requireSingbox () { if (hasRequiredSingbox) return singbox; hasRequiredSingbox = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "SingboxSource", { enumerable: true, get: function() { return SingboxSource; } }); const _base = /*@__PURE__*/ requireBase$1(); const _appendarrayinplace = /*@__PURE__*/ requireAppendArrayInPlace(); const _noop = require$$2; const _misc = /*@__PURE__*/ misc.r(); const _jsonstringifyprettycompact = /*#__PURE__*/ _interop_require_default(require$$4); const _dir = /*@__PURE__*/ fetchRetry.a(); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class SingboxSource extends _base.BaseWriteStrategy { type; outputDir; fileExtension; static jsonToLines = (json)=>(0, _jsonstringifyprettycompact.default)(json).split('\n'); singbox; get result() { return SingboxSource.jsonToLines({ version: 2, rules: [ this.singbox ] }); } constructor(/** Since sing-box only have one format that does not reflect type, we need to specify it */ type/* | (string & {}) */ , outputDir = _dir.OUTPUT_SINGBOX_DIR){ super(outputDir), this.type = type, this.outputDir = outputDir, this.fileExtension = 'json', this.singbox = { domain: [ 'this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ], domain_suffix: [ 'this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ] }, this.withPadding = _misc.withIdentityContent, this.writeUserAgents = _noop.noop, this.writeUrlRegexes = _noop.noop, this.writeGeoip = _noop.noop, this.writeIpAsns = _noop.noop, this.writeOtherRules = _noop.noop; } withPadding; writeDomain(domain) { this.singbox.domain.push(domain); } writeDomainSuffix(domain) { this.singbox.domain_suffix.push(domain); } writeDomainKeywords(keyword) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.domain_keyword ??= [], Array.from(keyword)); } writeDomainWildcards(wildcard) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.domain_regex ??= [], Array.from(wildcard, SingboxSource.domainWildCardToRegex)); } writeUserAgents; writeProcessNames(processName) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.process_name ??= [], Array.from(processName)); } writeProcessPaths(processPath) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.process_path ??= [], Array.from(processPath)); } writeUrlRegexes; writeIpCidrs(ipCidr) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.ip_cidr ??= [], ipCidr); } writeIpCidr6s(ipCidr6) { (0, _appendarrayinplace.appendArrayInPlace)(this.singbox.ip_cidr ??= [], ipCidr6); } writeGeoip; writeIpAsns; writeSourceIpCidrs(sourceIpCidr) { this.singbox.source_ip_cidr ??= []; for(let i = 0, len = sourceIpCidr.length; i < len; i++){ const value = sourceIpCidr[i]; if (value.includes('/')) { this.singbox.source_ip_cidr.push(value); continue; } const v = (0, _misc.fastIpVersion)(value); if (v === 4) { this.singbox.source_ip_cidr.push(`${value}/32`); continue; } if (v === 6) { this.singbox.source_ip_cidr.push(`${value}/128`); continue; } } } writeSourcePorts(port) { this.singbox.source_port ??= []; for (const i of port){ const tmp = Number(i); if (!Number.isNaN(tmp)) { this.singbox.source_port.push(tmp); } } } writeDestinationPorts(port) { this.singbox.port ??= []; for (const i of port){ const tmp = Number(i); if (!Number.isNaN(tmp)) { this.singbox.port.push(tmp); } } } writeOtherRules; } } (singbox)); return singbox; }var surge = {};var hasRequiredSurge; function requireSurge () { if (hasRequiredSurge) return surge; hasRequiredSurge = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { SurgeDomainSet: function() { return SurgeDomainSet; }, SurgeMitmSgmodule: function() { return SurgeMitmSgmodule; }, SurgeRuleSet: function() { return SurgeRuleSet; } }); const _appendsetelementstoarray = require$$0; const _base = /*@__PURE__*/ requireBase$1(); const _appendarrayinplace = /*@__PURE__*/ requireAppendArrayInPlace(); const _noop = require$$2; const _isprobablyip = require$$2$1; const _picocolors = /*#__PURE__*/ _interop_require_default(require$$0$1); const _normalizedomain = /*@__PURE__*/ normalizeDomain.r(); const _dir = /*@__PURE__*/ fetchRetry.a(); const _misc = /*@__PURE__*/ misc.r(); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class SurgeDomainSet extends _base.BaseWriteStrategy { // readonly type = 'domainset'; fileExtension = 'conf'; type = 'domainset'; result = [ 'this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ]; constructor(outputDir = _dir.OUTPUT_SURGE_DIR){ super(outputDir); } withPadding = _misc.withBannerArray; writeDomain(domain) { this.result.push(domain); } writeDomainSuffix(domain) { this.result.push('.' + domain); } writeDomainKeywords = _noop.noop; writeDomainWildcards = _noop.noop; writeUserAgents = _noop.noop; writeProcessNames = _noop.noop; writeProcessPaths = _noop.noop; writeUrlRegexes = _noop.noop; writeIpCidrs = _noop.noop; writeIpCidr6s = _noop.noop; writeGeoip = _noop.noop; writeIpAsns = _noop.noop; writeSourceIpCidrs = _noop.noop; writeSourcePorts = _noop.noop; writeDestinationPorts = _noop.noop; writeOtherRules = _noop.noop; } class SurgeRuleSet extends _base.BaseWriteStrategy { type; outputDir; fileExtension; result; constructor(/** Surge RULE-SET can be both ip or non_ip, so this needs to be specified */ type, outputDir = _dir.OUTPUT_SURGE_DIR){ super(outputDir), this.type = type, this.outputDir = outputDir, this.fileExtension = 'conf', this.result = [ 'DOMAIN,this_ruleset_is_made_by_sukkaw.ruleset.skk.moe' ], this.withPadding = _misc.withBannerArray; } withPadding; writeDomain(domain) { this.result.push('DOMAIN,' + domain); } writeDomainSuffix(domain) { this.result.push('DOMAIN-SUFFIX,' + domain); } writeDomainKeywords(keyword) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, keyword, (i)=>`DOMAIN-KEYWORD,${i}`); } writeDomainWildcards(wildcard) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, wildcard, (i)=>`DOMAIN-WILDCARD,${i}`); } writeUserAgents(userAgent) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, userAgent, (i)=>`USER-AGENT,${i}`); } writeProcessNames(processName) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, processName, (i)=>`PROCESS-NAME,${i}`); } writeProcessPaths(processPath) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, processPath, (i)=>`PROCESS-NAME,${i}`); } writeUrlRegexes(urlRegex) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, urlRegex, (i)=>`URL-REGEX,${i}`); } writeIpCidrs(ipCidr, noResolve) { for(let i = 0, len = ipCidr.length; i < len; i++){ this.result.push(`IP-CIDR,${ipCidr[i]}${noResolve ? ',no-resolve' : ''}`); } } writeIpCidr6s(ipCidr6, noResolve) { for(let i = 0, len = ipCidr6.length; i < len; i++){ this.result.push(`IP-CIDR6,${ipCidr6[i]}${noResolve ? ',no-resolve' : ''}`); } } writeGeoip(geoip, noResolve) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, geoip, (i)=>`GEOIP,${i}${noResolve ? ',no-resolve' : ''}`); } writeIpAsns(asns, noResolve) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, asns, (i)=>`IP-ASN,${i}${noResolve ? ',no-resolve' : ''}`); } writeSourceIpCidrs(sourceIpCidr) { for(let i = 0, len = sourceIpCidr.length; i < len; i++){ this.result.push(`SRC-IP,${sourceIpCidr[i]}`); } } writeSourcePorts(port) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, port, (i)=>`SRC-PORT,${i}`); } writeDestinationPorts(port) { (0, _appendsetelementstoarray.appendSetElementsToArray)(this.result, port, (i)=>`DEST-PORT,${i}`); } writeOtherRules(rule) { (0, _appendarrayinplace.appendArrayInPlace)(this.result, rule); } } class SurgeMitmSgmodule extends _base.BaseWriteStrategy { // readonly type = 'domainset'; fileExtension = 'sgmodule'; type = ''; rules = new Set(); get result() { if (this.rules.size === 0) { return null; } return [ '#!name=[Sukka] Surge Reject MITM', `#!desc=为 URL Regex 规则组启用 MITM (size: ${this.rules.size})`, '', '[MITM]', 'hostname = %APPEND% ' + Array.from(this.rules).join(', ') ]; } withPadding = _misc.withIdentityContent; constructor(moduleName, outputDir = _dir.OUTPUT_MODULES_DIR){ super(outputDir); this.withFilename(moduleName); } writeDomain = _noop.noop; writeDomainSuffix = _noop.noop; writeDomainKeywords = _noop.noop; writeDomainWildcards = _noop.noop; writeUserAgents = _noop.noop; writeProcessNames = _noop.noop; writeProcessPaths = _noop.noop; writeUrlRegexes(urlRegexes) { const urlRegexResults = []; const parsedFailures = []; const parsed = []; for (let urlRegex of urlRegexes){ if (urlRegex.startsWith('http://') || urlRegex.startsWith('^http://')) { continue; } if (urlRegex.startsWith('^https?://')) { urlRegex = urlRegex.slice(10); } if (urlRegex.startsWith('^https://')) { urlRegex = urlRegex.slice(9); } const potentialHostname = urlRegex.split('/')[0]// pre process regex .replaceAll(String.raw`\.`, '.').replaceAll('.+', '*').replaceAll(/([a-z])\?/g, '($1|)')// convert regex to surge hostlist syntax .replaceAll('([a-z])', '?').replaceAll(String.raw`\d`, '?').replaceAll(/\*+/g, '*'); let processed = [ potentialHostname ]; const matches = [ ...potentialHostname.matchAll(/\((?:([^()|]+)\|)+([^()|]*)\)/g) ]; if (matches.length > 0) { const replaceVariant = (combinations, fullMatch, options)=>{ const newCombinations = []; combinations.forEach((combination)=>{ options.forEach((option)=>{ newCombinations.push(combination.replace(fullMatch, option)); }); }); return newCombinations; }; for(let i = 0; i < matches.length; i++){ const match = matches[i]; const [_, ...options] = match; processed = replaceVariant(processed, _, options); } } urlRegexResults.push({ origin: potentialHostname, processed }); } for (const i of urlRegexResults){ for (const processed of i.processed){ if ((0, _normalizedomain.normalizeDomain)(processed.replaceAll('*', 'a').replaceAll('?', 'b'))) { parsed.push([ i.origin, processed ]); } else if (!(0, _isprobablyip.isProbablyIpv4)(processed)) { parsedFailures.push([ i.origin, processed ]); } } } if (parsedFailures.length > 0) { console.error(_picocolors.default.bold('Parsed Failed')); console.table(parsedFailures); } for(let i = 0, len = parsed.length; i < len; i++){ this.rules.add(parsed[i][1]); } } writeIpCidrs = _noop.noop; writeIpCidr6s = _noop.noop; writeGeoip = _noop.noop; writeIpAsns = _noop.noop; writeSourceIpCidrs = _noop.noop; writeSourcePorts = _noop.noop; writeDestinationPorts = _noop.noop; writeOtherRules = _noop.noop; } } (surge)); return surge; }var base = {};var hasRequiredBase; function requireBase () { if (hasRequiredBase) return base; hasRequiredBase = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "FileOutput", { enumerable: true, get: function() { return FileOutput; } }); const _trie = /*@__PURE__*/ trie.r(); const _guard = require$$6; const _fastcidrtools = require$$2$2; const _retrie = require$$3; const _nodepath = /*#__PURE__*/ _interop_require_default(require$$0$2); const _surge = /*@__PURE__*/ requireSurge(); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class FileOutput { id; strategies; domainTrie; domainKeywords; domainWildcard; userAgent; processName; processPath; urlRegex; ipcidr; ipcidrNoResolve; ipasn; ipasnNoResolve; ipcidr6; ipcidr6NoResolve; geoip; groipNoResolve; sourceIpOrCidr; sourcePort; destPort; otherRules; pendingPromise; whitelistDomain; span; constructor($span, id){ this.id = id; this.strategies = []; this.domainTrie = new _trie.HostnameSmolTrie(null); this.domainKeywords = new Set(); this.domainWildcard = new Set(); this.userAgent = new Set(); this.processName = new Set(); this.processPath = new Set(); this.urlRegex = new Set(); this.ipcidr = new Set(); this.ipcidrNoResolve = new Set(); this.ipasn = new Set(); this.ipasnNoResolve = new Set(); this.ipcidr6 = new Set(); this.ipcidr6NoResolve = new Set(); this.geoip = new Set(); this.groipNoResolve = new Set(); this.sourceIpOrCidr = new Set(); this.sourcePort = new Set(); this.destPort = new Set(); this.otherRules = []; this.pendingPromise = null; this.whitelistDomain = (domain)=>{ this.domainTrie.whitelist(domain); return this; }; this.title = null; this.description = null; this.date = new Date(); this.strategiesWritten = false; this.span = $span.traceChild('RuleOutput#' + id); } title; withTitle(title) { this.title = title; return this; } withStrategies(strategies) { this.strategies = strategies; return this; } withExtraStrategies(strategy) { if (strategy) { this.strategies.push(strategy); } } description; withDescription(description) { this.description = description; return this; } date; withDate(date) { this.date = date; return this; } addDomain(domain) { this.domainTrie.add(domain); return this; } bulkAddDomain(domains) { let d; for(let i = 0, len = domains.length; i < len; i++){ d = domains[i]; if (d !== null) { this.domainTrie.add(d, false, null, 0); } } return this; } addDomainSuffix(domain, lineFromDot = domain[0] === '.') { this.domainTrie.add(domain, true, lineFromDot ? 1 : 0); return this; } bulkAddDomainSuffix(domains) { for(let i = 0, len = domains.length; i < len; i++){ this.addDomainSuffix(domains[i]); } return this; } addDomainKeyword(keyword) { this.domainKeywords.add(keyword); return this; } addIPASN(asn) { this.ipasn.add(asn); return this; } bulkAddIPASN(asns) { for(let i = 0, len = asns.length; i < len; i++){ this.ipasn.add(asns[i]); } return this; } async addFromDomainsetPromise(source) { for await (const line of source){ if (line[0] === '.') { this.addDomainSuffix(line, true); } else { this.domainTrie.add(line, false, null, 0); } } } addFromDomainset(source) { if (this.pendingPromise) { if ('then' in source) { this.pendingPromise = this.pendingPromise.then(()=>source).then((src)=>this.addFromDomainsetPromise(src)); return this; } this.pendingPromise = this.pendingPromise.then(()=>this.addFromDomainsetPromise(source)); return this; } if ('then' in source) { this.pendingPromise = source.then((src)=>this.addFromDomainsetPromise(src)); return this; } this.pendingPromise = this.addFromDomainsetPromise(source); return this; } async addFromRulesetPromise(source) { for await (const line of source){ const splitted = line.split(','); const type = splitted[0]; const value = splitted[1]; const arg = splitted[2]; switch(type){ case 'DOMAIN': this.domainTrie.add(value, false, null, 0); break; case 'DOMAIN-SUFFIX': this.addDomainSuffix(value, false); break; case 'DOMAIN-KEYWORD': this.addDomainKeyword(value); break; case 'DOMAIN-WILDCARD': this.domainWildcard.add(value); break; case 'USER-AGENT': this.userAgent.add(value); break; case 'PROCESS-NAME': if (value.includes('/') || value.includes('\\')) { this.processPath.add(value); } else { this.processName.add(value); } break; case 'URL-REGEX': { const [, ...rest] = splitted; this.urlRegex.add(rest.join(',')); break; } case 'IP-CIDR': (arg === 'no-resolve' ? this.ipcidrNoResolve : this.ipcidr).add(value); break; case 'IP-CIDR6': (arg === 'no-resolve' ? this.ipcidr6NoResolve : this.ipcidr6).add(value); break; case 'IP-ASN': (arg === 'no-resolve' ? this.ipasnNoResolve : this.ipasn).add(value); break; case 'GEOIP': (arg === 'no-resolve' ? this.groipNoResolve : this.geoip).add(value); break; case 'SRC-IP': this.sourceIpOrCidr.add(value); break; case 'SRC-PORT': this.sourcePort.add(value); break; case 'DEST-PORT': this.destPort.add(value); break; default: this.otherRules.push(line); break; } } } addFromRuleset(source) { if (this.pendingPromise) { if ('then' in source) { this.pendingPromise = this.pendingPromise.then(()=>source).then((src)=>this.addFromRulesetPromise(src)); return this; } this.pendingPromise = this.pendingPromise.then(()=>this.addFromRulesetPromise(source)); return this; } if ('then' in source) { this.pendingPromise = source.then((src)=>this.addFromRulesetPromise(src)); return this; } this.pendingPromise = this.addFromRulesetPromise(source); return this; } static ipToCidr = (ip, version)=>{ if (ip.includes('/')) return ip; if (version === 4) { return ip + '/32'; } return ip + '/128'; }; bulkAddCIDR4(cidrs) { for(let i = 0, len = cidrs.length; i < len; i++){ this.ipcidr.add(FileOutput.ipToCidr(cidrs[i], 4)); } return this; } bulkAddCIDR4NoResolve(cidrs) { for(let i = 0, len = cidrs.length; i < len; i++){ this.ipcidrNoResolve.add(FileOutput.ipToCidr(cidrs[i], 4)); } return this; } bulkAddCIDR6(cidrs) { for(let i = 0, len = cidrs.length; i < len; i++){ this.ipcidr6.add(FileOutput.ipToCidr(cidrs[i], 6)); } return this; } bulkAddCIDR6NoResolve(cidrs) { for(let i = 0, len = cidrs.length; i < len; i++){ this.ipcidr6NoResolve.add(FileOutput.ipToCidr(cidrs[i], 6)); } return this; } async done() { await this.pendingPromise; this.pendingPromise = null; return this; } // private guardPendingPromise() { // // reverse invariant // if (this.pendingPromise !== null) { // console.trace('Pending promise:', this.pendingPromise); // throw new Error('You should call done() before calling this method'); // } // } // async writeClash(outputDir?: null | string) { // await this.done(); // invariant(this.title, 'Missing title'); // invariant(this.description, 'Missing description'); // return compareAndWriteFile( // this.span, // withBannerArray( // this.title, // this.description, // this.date, // this.clash() // ), // path.join(outputDir ?? OUTPUT_CLASH_DIR, this.type, this.id + '.txt') // ); // } strategiesWritten; writeToStrategies() { if (this.pendingPromise) { throw new Error('You should call done() before calling writeToStrategies()'); } if (this.strategiesWritten) { throw new Error('Strategies already written'); } this.strategiesWritten = true; const kwfilter = (0, _retrie.createRetrieKeywordFilter)(Array.from(this.domainKeywords)); if (this.strategies.filter((0, _guard.not)(false)).length === 0) { throw new Error('No strategies to write ' + this.id); } this.domainTrie.dumpWithoutDot((domain, includeAllSubdomain)=>{ if (kwfilter(domain)) { return; } for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (strategy) { if (includeAllSubdomain) { strategy.writeDomainSuffix(domain); } else { strategy.writeDomain(domain); } } } }, true); for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (!strategy) continue; if (this.domainKeywords.size) { strategy.writeDomainKeywords(this.domainKeywords); } if (this.domainWildcard.size) { strategy.writeDomainWildcards(this.domainWildcard); } if (this.userAgent.size) { strategy.writeUserAgents(this.userAgent); } if (this.processName.size) { strategy.writeProcessNames(this.processName); } if (this.processPath.size) { strategy.writeProcessPaths(this.processPath); } } if (this.sourceIpOrCidr.size) { const sourceIpOrCidr = Array.from(this.sourceIpOrCidr); for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (strategy) { strategy.writeSourceIpCidrs(sourceIpOrCidr); } } } for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (strategy) { if (this.sourcePort.size) { strategy.writeSourcePorts(this.sourcePort); } if (this.destPort.size) { strategy.writeDestinationPorts(this.destPort); } if (this.otherRules.length) { strategy.writeOtherRules(this.otherRules); } if (this.urlRegex.size) { strategy.writeUrlRegexes(this.urlRegex); } } } let ipcidr = null; let ipcidrNoResolve = null; let ipcidr6 = null; let ipcidr6NoResolve = null; if (this.ipcidr.size) { ipcidr = (0, _fastcidrtools.merge)(Array.from(this.ipcidr), true); } if (this.ipcidrNoResolve.size) { ipcidrNoResolve = (0, _fastcidrtools.merge)(Array.from(this.ipcidrNoResolve), true); } if (this.ipcidr6.size) { ipcidr6 = Array.from(this.ipcidr6); } if (this.ipcidr6NoResolve.size) { ipcidr6NoResolve = Array.from(this.ipcidr6NoResolve); } for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (strategy) { // no-resolve if (ipcidrNoResolve?.length) { strategy.writeIpCidrs(ipcidrNoResolve, true); } if (ipcidr6NoResolve?.length) { strategy.writeIpCidr6s(ipcidr6NoResolve, true); } if (this.ipasnNoResolve.size) { strategy.writeIpAsns(this.ipasnNoResolve, true); } if (this.groipNoResolve.size) { strategy.writeGeoip(this.groipNoResolve, true); } // triggers DNS resolution if (ipcidr?.length) { strategy.writeIpCidrs(ipcidr, false); } if (ipcidr6?.length) { strategy.writeIpCidr6s(ipcidr6, false); } if (this.ipasn.size) { strategy.writeIpAsns(this.ipasn, false); } if (this.geoip.size) { strategy.writeGeoip(this.geoip, false); } } } } write() { return this.span.traceChildAsync('write all', async (childSpan)=>{ await this.done(); childSpan.traceChildSync('write to strategies', this.writeToStrategies.bind(this)); return childSpan.traceChildAsync('output to disk', (childSpan)=>{ const promises = []; (0, _guard.invariant)(this.title, 'Missing title'); (0, _guard.invariant)(this.description, 'Missing description'); for(let i = 0, len = this.strategies.length; i < len; i++){ const strategy = this.strategies[i]; if (strategy) { const basename = (strategy.overwriteFilename || this.id) + '.' + strategy.fileExtension; promises.push(strategy.output(childSpan, this.title, this.description, this.date, _nodepath.default.join(strategy.outputDir, strategy.type ? _nodepath.default.join(strategy.type, basename) : basename))); } } return Promise.all(promises); }); }); } async compile() { await this.done(); this.writeToStrategies(); return this.strategies.reduce((acc, strategy)=>{ if (strategy) { acc.push(strategy.content); } else { acc.push(null); } return acc; }, []); } withMitmSgmodulePath(moduleName) { if (moduleName) { this.withExtraStrategies(new _surge.SurgeMitmSgmodule(moduleName)); } return this; } } } (base)); return base; }exports.a=requireAppendArrayInPlace;exports.b=requireBase;exports.c=requireClash;exports.d=requireBase$1;exports.e=requireSurge;exports.f=requireSingbox;exports.r=requireDescription;