@push.rocks/smartproxy 12.0.0 → 13.1.2

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 (258) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/certificate/acme/acme-factory.d.ts +17 -0
  3. package/dist_ts/certificate/acme/acme-factory.js +40 -0
  4. package/dist_ts/certificate/acme/challenge-handler.d.ts +44 -0
  5. package/dist_ts/certificate/acme/challenge-handler.js +92 -0
  6. package/dist_ts/certificate/acme/index.d.ts +4 -0
  7. package/dist_ts/certificate/acme/index.js +5 -0
  8. package/dist_ts/certificate/events/certificate-events.d.ts +33 -0
  9. package/dist_ts/certificate/events/certificate-events.js +38 -0
  10. package/dist_ts/certificate/index.d.ts +24 -0
  11. package/dist_ts/certificate/index.js +39 -0
  12. package/dist_ts/certificate/models/certificate-types.d.ts +77 -0
  13. package/dist_ts/certificate/models/certificate-types.js +2 -0
  14. package/dist_ts/certificate/providers/cert-provisioner.d.ts +93 -0
  15. package/dist_ts/certificate/providers/cert-provisioner.js +262 -0
  16. package/dist_ts/certificate/providers/index.d.ts +4 -0
  17. package/dist_ts/certificate/providers/index.js +5 -0
  18. package/dist_ts/certificate/storage/file-storage.d.ts +66 -0
  19. package/dist_ts/certificate/storage/file-storage.js +194 -0
  20. package/dist_ts/certificate/storage/index.d.ts +4 -0
  21. package/dist_ts/certificate/storage/index.js +5 -0
  22. package/dist_ts/certificate/utils/certificate-helpers.d.ts +17 -0
  23. package/dist_ts/certificate/utils/certificate-helpers.js +45 -0
  24. package/dist_ts/common/eventUtils.d.ts +1 -1
  25. package/dist_ts/common/port80-adapter.d.ts +1 -1
  26. package/dist_ts/core/events/index.d.ts +4 -0
  27. package/dist_ts/core/events/index.js +5 -0
  28. package/dist_ts/core/index.d.ts +6 -0
  29. package/dist_ts/core/index.js +8 -0
  30. package/dist_ts/core/models/common-types.d.ts +82 -0
  31. package/dist_ts/core/models/common-types.js +15 -0
  32. package/dist_ts/core/models/index.d.ts +4 -0
  33. package/dist_ts/core/models/index.js +5 -0
  34. package/dist_ts/core/utils/event-utils.d.ts +15 -0
  35. package/dist_ts/core/utils/event-utils.js +19 -0
  36. package/dist_ts/core/utils/index.d.ts +6 -0
  37. package/dist_ts/core/utils/index.js +7 -0
  38. package/dist_ts/core/utils/ip-utils.d.ts +53 -0
  39. package/dist_ts/core/utils/ip-utils.js +153 -0
  40. package/dist_ts/core/utils/validation-utils.d.ts +61 -0
  41. package/dist_ts/core/utils/validation-utils.js +149 -0
  42. package/dist_ts/forwarding/config/domain-config.d.ts +12 -0
  43. package/dist_ts/forwarding/config/domain-config.js +12 -0
  44. package/dist_ts/forwarding/config/domain-manager.d.ts +86 -0
  45. package/dist_ts/forwarding/config/domain-manager.js +242 -0
  46. package/dist_ts/forwarding/config/forwarding-types.d.ts +104 -0
  47. package/dist_ts/forwarding/config/forwarding-types.js +50 -0
  48. package/dist_ts/forwarding/config/index.d.ts +6 -0
  49. package/dist_ts/forwarding/config/index.js +7 -0
  50. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +25 -0
  51. package/dist_ts/forwarding/factory/forwarding-factory.js +138 -0
  52. package/dist_ts/forwarding/factory/index.d.ts +4 -0
  53. package/dist_ts/forwarding/factory/index.js +5 -0
  54. package/dist_ts/forwarding/handlers/base-handler.d.ts +55 -0
  55. package/dist_ts/forwarding/handlers/base-handler.js +94 -0
  56. package/dist_ts/forwarding/handlers/http-handler.d.ts +30 -0
  57. package/dist_ts/forwarding/handlers/http-handler.js +131 -0
  58. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +29 -0
  59. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +162 -0
  60. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +36 -0
  61. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +229 -0
  62. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +35 -0
  63. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +254 -0
  64. package/dist_ts/forwarding/handlers/index.d.ts +8 -0
  65. package/dist_ts/forwarding/handlers/index.js +9 -0
  66. package/dist_ts/forwarding/index.d.ts +19 -0
  67. package/dist_ts/forwarding/index.js +25 -0
  68. package/dist_ts/http/index.d.ts +15 -0
  69. package/dist_ts/http/index.js +20 -0
  70. package/dist_ts/http/models/http-types.d.ts +81 -0
  71. package/dist_ts/http/models/http-types.js +62 -0
  72. package/dist_ts/http/port80/acme-interfaces.d.ts +78 -0
  73. package/dist_ts/http/port80/acme-interfaces.js +6 -0
  74. package/dist_ts/http/port80/challenge-responder.d.ts +53 -0
  75. package/dist_ts/http/port80/challenge-responder.js +203 -0
  76. package/dist_ts/http/port80/index.d.ts +6 -0
  77. package/dist_ts/http/port80/index.js +9 -0
  78. package/dist_ts/http/port80/port80-handler.d.ts +121 -0
  79. package/dist_ts/http/port80/port80-handler.js +554 -0
  80. package/dist_ts/http/redirects/index.d.ts +4 -0
  81. package/dist_ts/http/redirects/index.js +5 -0
  82. package/dist_ts/http/router/index.d.ts +4 -0
  83. package/dist_ts/http/router/index.js +5 -0
  84. package/dist_ts/http/router/proxy-router.d.ts +115 -0
  85. package/dist_ts/http/router/proxy-router.js +325 -0
  86. package/dist_ts/index.d.ts +15 -8
  87. package/dist_ts/index.js +26 -10
  88. package/dist_ts/networkproxy/classes.np.certificatemanager.js +2 -2
  89. package/dist_ts/networkproxy/index.d.ts +1 -6
  90. package/dist_ts/networkproxy/index.js +4 -8
  91. package/dist_ts/plugins.d.ts +2 -1
  92. package/dist_ts/plugins.js +3 -2
  93. package/dist_ts/port80handler/classes.port80handler.d.ts +8 -136
  94. package/dist_ts/port80handler/classes.port80handler.js +14 -567
  95. package/dist_ts/proxies/index.d.ts +6 -0
  96. package/dist_ts/proxies/index.js +8 -0
  97. package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +77 -0
  98. package/dist_ts/proxies/network-proxy/certificate-manager.js +373 -0
  99. package/dist_ts/proxies/network-proxy/connection-pool.d.ts +47 -0
  100. package/dist_ts/proxies/network-proxy/connection-pool.js +210 -0
  101. package/dist_ts/proxies/network-proxy/index.d.ts +10 -0
  102. package/dist_ts/proxies/network-proxy/index.js +12 -0
  103. package/dist_ts/proxies/network-proxy/models/index.d.ts +4 -0
  104. package/dist_ts/proxies/network-proxy/models/index.js +5 -0
  105. package/dist_ts/proxies/network-proxy/models/types.d.ts +80 -0
  106. package/dist_ts/proxies/network-proxy/models/types.js +35 -0
  107. package/dist_ts/proxies/network-proxy/network-proxy.d.ts +118 -0
  108. package/dist_ts/proxies/network-proxy/network-proxy.js +387 -0
  109. package/dist_ts/proxies/network-proxy/request-handler.d.ts +57 -0
  110. package/dist_ts/proxies/network-proxy/request-handler.js +394 -0
  111. package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +38 -0
  112. package/dist_ts/proxies/network-proxy/websocket-handler.js +188 -0
  113. package/dist_ts/proxies/nftables-proxy/index.d.ts +5 -0
  114. package/dist_ts/proxies/nftables-proxy/index.js +6 -0
  115. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +15 -0
  116. package/dist_ts/proxies/nftables-proxy/models/errors.js +28 -0
  117. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +5 -0
  118. package/dist_ts/proxies/nftables-proxy/models/index.js +6 -0
  119. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +75 -0
  120. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +5 -0
  121. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +136 -0
  122. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +1516 -0
  123. package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +39 -0
  124. package/dist_ts/proxies/smart-proxy/connection-handler.js +894 -0
  125. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +78 -0
  126. package/dist_ts/proxies/smart-proxy/connection-manager.js +378 -0
  127. package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +95 -0
  128. package/dist_ts/proxies/smart-proxy/domain-config-manager.js +255 -0
  129. package/dist_ts/proxies/smart-proxy/index.d.ts +13 -0
  130. package/dist_ts/proxies/smart-proxy/index.js +17 -0
  131. package/dist_ts/proxies/smart-proxy/models/index.d.ts +4 -0
  132. package/dist_ts/proxies/smart-proxy/models/index.js +5 -0
  133. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +107 -0
  134. package/dist_ts/proxies/smart-proxy/models/interfaces.js +2 -0
  135. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +62 -0
  136. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +316 -0
  137. package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +56 -0
  138. package/dist_ts/proxies/smart-proxy/port-range-manager.js +176 -0
  139. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +64 -0
  140. package/dist_ts/proxies/smart-proxy/security-manager.js +149 -0
  141. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +63 -0
  142. package/dist_ts/proxies/smart-proxy/smart-proxy.js +523 -0
  143. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +47 -0
  144. package/dist_ts/proxies/smart-proxy/timeout-manager.js +154 -0
  145. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +57 -0
  146. package/dist_ts/proxies/smart-proxy/tls-manager.js +132 -0
  147. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +2 -2
  148. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +1 -1
  149. package/dist_ts/smartproxy/classes.pp.tlsmanager.js +2 -2
  150. package/dist_ts/smartproxy/classes.smartproxy.js +3 -3
  151. package/dist_ts/tls/alerts/index.d.ts +4 -0
  152. package/dist_ts/tls/alerts/index.js +5 -0
  153. package/dist_ts/tls/alerts/tls-alert.d.ts +150 -0
  154. package/dist_ts/tls/alerts/tls-alert.js +226 -0
  155. package/dist_ts/tls/index.d.ts +18 -0
  156. package/dist_ts/tls/index.js +27 -0
  157. package/dist_ts/tls/sni/client-hello-parser.d.ts +100 -0
  158. package/dist_ts/tls/sni/client-hello-parser.js +463 -0
  159. package/dist_ts/tls/sni/index.d.ts +4 -0
  160. package/dist_ts/tls/sni/index.js +5 -0
  161. package/dist_ts/tls/sni/sni-extraction.d.ts +58 -0
  162. package/dist_ts/tls/sni/sni-extraction.js +275 -0
  163. package/dist_ts/tls/sni/sni-handler.d.ts +154 -0
  164. package/dist_ts/tls/sni/sni-handler.js +191 -0
  165. package/dist_ts/tls/utils/index.d.ts +4 -0
  166. package/dist_ts/tls/utils/index.js +5 -0
  167. package/dist_ts/tls/utils/tls-utils.d.ts +158 -0
  168. package/dist_ts/tls/utils/tls-utils.js +187 -0
  169. package/package.json +1 -1
  170. package/readme.md +89 -21
  171. package/readme.plan.md +253 -469
  172. package/ts/00_commitinfo_data.ts +1 -1
  173. package/ts/certificate/acme/acme-factory.ts +48 -0
  174. package/ts/certificate/acme/challenge-handler.ts +110 -0
  175. package/ts/certificate/acme/index.ts +3 -0
  176. package/ts/certificate/events/certificate-events.ts +36 -0
  177. package/ts/certificate/index.ts +67 -0
  178. package/ts/certificate/models/certificate-types.ts +88 -0
  179. package/ts/certificate/providers/cert-provisioner.ts +326 -0
  180. package/ts/certificate/providers/index.ts +3 -0
  181. package/ts/certificate/storage/file-storage.ts +234 -0
  182. package/ts/certificate/storage/index.ts +3 -0
  183. package/ts/certificate/utils/certificate-helpers.ts +50 -0
  184. package/ts/common/eventUtils.ts +1 -1
  185. package/ts/common/port80-adapter.ts +1 -1
  186. package/ts/core/events/index.ts +3 -0
  187. package/ts/core/index.ts +8 -0
  188. package/ts/core/models/common-types.ts +91 -0
  189. package/ts/core/models/index.ts +5 -0
  190. package/ts/core/utils/event-utils.ts +34 -0
  191. package/ts/core/utils/index.ts +7 -0
  192. package/ts/core/utils/ip-utils.ts +175 -0
  193. package/ts/core/utils/validation-utils.ts +177 -0
  194. package/ts/{smartproxy/forwarding → forwarding/config}/domain-config.ts +1 -1
  195. package/ts/{smartproxy/forwarding → forwarding/config}/domain-manager.ts +8 -8
  196. package/ts/{smartproxy/types/forwarding.types.ts → forwarding/config/forwarding-types.ts} +6 -6
  197. package/ts/forwarding/config/index.ts +7 -0
  198. package/ts/{smartproxy/forwarding/forwarding.factory.ts → forwarding/factory/forwarding-factory.ts} +12 -11
  199. package/ts/forwarding/factory/index.ts +5 -0
  200. package/ts/{smartproxy/forwarding/forwarding.handler.ts → forwarding/handlers/base-handler.ts} +2 -2
  201. package/ts/{smartproxy/forwarding/http.handler.ts → forwarding/handlers/http-handler.ts} +13 -4
  202. package/ts/{smartproxy/forwarding/https-passthrough.handler.ts → forwarding/handlers/https-passthrough-handler.ts} +13 -4
  203. package/ts/{smartproxy/forwarding/https-terminate-to-http.handler.ts → forwarding/handlers/https-terminate-to-http-handler.ts} +3 -3
  204. package/ts/{smartproxy/forwarding/https-terminate-to-https.handler.ts → forwarding/handlers/https-terminate-to-https-handler.ts} +3 -3
  205. package/ts/forwarding/handlers/index.ts +9 -0
  206. package/ts/forwarding/index.ts +34 -0
  207. package/ts/http/index.ts +23 -0
  208. package/ts/http/models/http-types.ts +105 -0
  209. package/ts/http/port80/acme-interfaces.ts +85 -0
  210. package/ts/http/port80/challenge-responder.ts +246 -0
  211. package/ts/http/port80/index.ts +13 -0
  212. package/ts/{port80handler/classes.port80handler.ts → http/port80/port80-handler.ts} +164 -161
  213. package/ts/http/redirects/index.ts +3 -0
  214. package/ts/http/router/index.ts +5 -0
  215. package/ts/{classes.router.ts → http/router/proxy-router.ts} +27 -20
  216. package/ts/index.ts +32 -9
  217. package/ts/plugins.ts +2 -1
  218. package/ts/proxies/index.ts +8 -0
  219. package/ts/{networkproxy/classes.np.certificatemanager.ts → proxies/network-proxy/certificate-manager.ts} +17 -16
  220. package/ts/{networkproxy/classes.np.connectionpool.ts → proxies/network-proxy/connection-pool.ts} +3 -3
  221. package/ts/proxies/network-proxy/index.ts +13 -0
  222. package/ts/proxies/network-proxy/models/index.ts +4 -0
  223. package/ts/{networkproxy/classes.np.types.ts → proxies/network-proxy/models/types.ts} +7 -11
  224. package/ts/{networkproxy/classes.np.networkproxy.ts → proxies/network-proxy/network-proxy.ts} +31 -24
  225. package/ts/{networkproxy/classes.np.requesthandler.ts → proxies/network-proxy/request-handler.ts} +12 -7
  226. package/ts/{networkproxy/classes.np.websockethandler.ts → proxies/network-proxy/websocket-handler.ts} +6 -6
  227. package/ts/proxies/nftables-proxy/index.ts +5 -0
  228. package/ts/proxies/nftables-proxy/models/errors.ts +30 -0
  229. package/ts/proxies/nftables-proxy/models/index.ts +5 -0
  230. package/ts/proxies/nftables-proxy/models/interfaces.ts +94 -0
  231. package/ts/{nfttablesproxy/classes.nftablesproxy.ts → proxies/nftables-proxy/nftables-proxy.ts} +24 -126
  232. package/ts/{smartproxy/classes.pp.connectionhandler.ts → proxies/smart-proxy/connection-handler.ts} +12 -12
  233. package/ts/{smartproxy/classes.pp.connectionmanager.ts → proxies/smart-proxy/connection-manager.ts} +8 -8
  234. package/ts/{smartproxy/classes.pp.domainconfigmanager.ts → proxies/smart-proxy/domain-config-manager.ts} +15 -14
  235. package/ts/proxies/smart-proxy/index.ts +18 -0
  236. package/ts/proxies/smart-proxy/models/index.ts +4 -0
  237. package/ts/{smartproxy/classes.pp.interfaces.ts → proxies/smart-proxy/models/interfaces.ts} +12 -8
  238. package/ts/{smartproxy/classes.pp.networkproxybridge.ts → proxies/smart-proxy/network-proxy-bridge.ts} +14 -14
  239. package/ts/{smartproxy/classes.pp.portrangemanager.ts → proxies/smart-proxy/port-range-manager.ts} +1 -1
  240. package/ts/{smartproxy/classes.pp.securitymanager.ts → proxies/smart-proxy/security-manager.ts} +3 -3
  241. package/ts/{smartproxy/classes.smartproxy.ts → proxies/smart-proxy/smart-proxy.ts} +29 -24
  242. package/ts/{smartproxy/classes.pp.timeoutmanager.ts → proxies/smart-proxy/timeout-manager.ts} +3 -3
  243. package/ts/{smartproxy/classes.pp.tlsmanager.ts → proxies/smart-proxy/tls-manager.ts} +3 -3
  244. package/ts/tls/alerts/index.ts +3 -0
  245. package/ts/{smartproxy/classes.pp.tlsalert.ts → tls/alerts/tls-alert.ts} +44 -43
  246. package/ts/tls/index.ts +33 -0
  247. package/ts/tls/sni/client-hello-parser.ts +629 -0
  248. package/ts/tls/sni/index.ts +3 -0
  249. package/ts/tls/sni/sni-extraction.ts +353 -0
  250. package/ts/tls/sni/sni-handler.ts +264 -0
  251. package/ts/tls/utils/index.ts +3 -0
  252. package/ts/tls/utils/tls-utils.ts +201 -0
  253. package/ts/common/acmeFactory.ts +0 -23
  254. package/ts/helpers.certificates.ts +0 -30
  255. package/ts/networkproxy/index.ts +0 -7
  256. package/ts/smartproxy/classes.pp.certprovisioner.ts +0 -200
  257. package/ts/smartproxy/classes.pp.snihandler.ts +0 -1281
  258. package/ts/smartproxy/forwarding/index.ts +0 -52
@@ -0,0 +1,77 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { type INetworkProxyOptions, type ICertificateEntry } from './models/types.js';
3
+ import { Port80Handler } from '../../http/port80/port80-handler.js';
4
+ /**
5
+ * Manages SSL certificates for NetworkProxy including ACME integration
6
+ */
7
+ export declare class CertificateManager {
8
+ private options;
9
+ private defaultCertificates;
10
+ private certificateCache;
11
+ private port80Handler;
12
+ private externalPort80Handler;
13
+ private certificateStoreDir;
14
+ private logger;
15
+ private httpsServer;
16
+ constructor(options: INetworkProxyOptions);
17
+ /**
18
+ * Loads default certificates from the filesystem
19
+ */
20
+ loadDefaultCertificates(): void;
21
+ /**
22
+ * Set the HTTPS server reference for context updates
23
+ */
24
+ setHttpsServer(server: plugins.https.Server): void;
25
+ /**
26
+ * Get default certificates
27
+ */
28
+ getDefaultCertificates(): {
29
+ key: string;
30
+ cert: string;
31
+ };
32
+ /**
33
+ * Sets an external Port80Handler for certificate management
34
+ */
35
+ setExternalPort80Handler(handler: Port80Handler): void;
36
+ /**
37
+ * Handle newly issued or renewed certificates from Port80Handler
38
+ */
39
+ private handleCertificateIssued;
40
+ /**
41
+ * Handle certificate issuance failures
42
+ */
43
+ private handleCertificateFailed;
44
+ /**
45
+ * Saves certificate and private key to the filesystem
46
+ */
47
+ private saveCertificateToStore;
48
+ /**
49
+ * Handles SNI (Server Name Indication) for TLS connections
50
+ * Used by the HTTPS server to select the correct certificate for each domain
51
+ */
52
+ handleSNI(domain: string, cb: (err: Error | null, ctx: plugins.tls.SecureContext) => void): void;
53
+ /**
54
+ * Updates certificate in cache
55
+ */
56
+ updateCertificateCache(domain: string, certificate: string, privateKey: string, expiryDate?: Date): void;
57
+ /**
58
+ * Gets a certificate for a domain
59
+ */
60
+ getCertificate(domain: string): ICertificateEntry | undefined;
61
+ /**
62
+ * Requests a new certificate for a domain
63
+ */
64
+ requestCertificate(domain: string): Promise<boolean>;
65
+ /**
66
+ * Registers domains with Port80Handler for ACME certificate management
67
+ */
68
+ registerDomainsWithPort80Handler(domains: string[]): void;
69
+ /**
70
+ * Initialize internal Port80Handler
71
+ */
72
+ initializePort80Handler(): Promise<Port80Handler | null>;
73
+ /**
74
+ * Stop the Port80Handler if it was internally created
75
+ */
76
+ stopPort80Handler(): Promise<void>;
77
+ }
@@ -0,0 +1,373 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { createLogger } from './models/types.js';
6
+ import { Port80Handler } from '../../http/port80/port80-handler.js';
7
+ import { CertificateEvents } from '../../certificate/events/certificate-events.js';
8
+ import { buildPort80Handler } from '../../certificate/acme/acme-factory.js';
9
+ import { subscribeToPort80Handler } from '../../core/utils/event-utils.js';
10
+ /**
11
+ * Manages SSL certificates for NetworkProxy including ACME integration
12
+ */
13
+ export class CertificateManager {
14
+ constructor(options) {
15
+ this.options = options;
16
+ this.certificateCache = new Map();
17
+ this.port80Handler = null;
18
+ this.externalPort80Handler = false;
19
+ this.httpsServer = null;
20
+ this.certificateStoreDir = path.resolve(options.acme?.certificateStore || './certs');
21
+ this.logger = createLogger(options.logLevel || 'info');
22
+ // Ensure certificate store directory exists
23
+ try {
24
+ if (!fs.existsSync(this.certificateStoreDir)) {
25
+ fs.mkdirSync(this.certificateStoreDir, { recursive: true });
26
+ this.logger.info(`Created certificate store directory: ${this.certificateStoreDir}`);
27
+ }
28
+ }
29
+ catch (error) {
30
+ this.logger.warn(`Failed to create certificate store directory: ${error}`);
31
+ }
32
+ this.loadDefaultCertificates();
33
+ }
34
+ /**
35
+ * Loads default certificates from the filesystem
36
+ */
37
+ loadDefaultCertificates() {
38
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
39
+ // Fix the path to look for certificates at the project root instead of inside ts directory
40
+ const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
41
+ try {
42
+ this.defaultCertificates = {
43
+ key: fs.readFileSync(path.join(certPath, 'key.pem'), 'utf8'),
44
+ cert: fs.readFileSync(path.join(certPath, 'cert.pem'), 'utf8')
45
+ };
46
+ this.logger.info('Default certificates loaded successfully');
47
+ }
48
+ catch (error) {
49
+ this.logger.error('Error loading default certificates', error);
50
+ // Generate self-signed fallback certificates
51
+ try {
52
+ // This is a placeholder for actual certificate generation code
53
+ // In a real implementation, you would use a library like selfsigned to generate certs
54
+ this.defaultCertificates = {
55
+ key: "FALLBACK_KEY_CONTENT",
56
+ cert: "FALLBACK_CERT_CONTENT"
57
+ };
58
+ this.logger.warn('Using fallback self-signed certificates');
59
+ }
60
+ catch (fallbackError) {
61
+ this.logger.error('Failed to generate fallback certificates', fallbackError);
62
+ throw new Error('Could not load or generate SSL certificates');
63
+ }
64
+ }
65
+ }
66
+ /**
67
+ * Set the HTTPS server reference for context updates
68
+ */
69
+ setHttpsServer(server) {
70
+ this.httpsServer = server;
71
+ }
72
+ /**
73
+ * Get default certificates
74
+ */
75
+ getDefaultCertificates() {
76
+ return { ...this.defaultCertificates };
77
+ }
78
+ /**
79
+ * Sets an external Port80Handler for certificate management
80
+ */
81
+ setExternalPort80Handler(handler) {
82
+ if (this.port80Handler && !this.externalPort80Handler) {
83
+ this.logger.warn('Replacing existing internal Port80Handler with external handler');
84
+ // Clean up existing handler if needed
85
+ if (this.port80Handler !== handler) {
86
+ // Unregister event handlers to avoid memory leaks
87
+ this.port80Handler.removeAllListeners(CertificateEvents.CERTIFICATE_ISSUED);
88
+ this.port80Handler.removeAllListeners(CertificateEvents.CERTIFICATE_RENEWED);
89
+ this.port80Handler.removeAllListeners(CertificateEvents.CERTIFICATE_FAILED);
90
+ this.port80Handler.removeAllListeners(CertificateEvents.CERTIFICATE_EXPIRING);
91
+ }
92
+ }
93
+ // Set the external handler
94
+ this.port80Handler = handler;
95
+ this.externalPort80Handler = true;
96
+ // Subscribe to Port80Handler events
97
+ subscribeToPort80Handler(this.port80Handler, {
98
+ onCertificateIssued: this.handleCertificateIssued.bind(this),
99
+ onCertificateRenewed: this.handleCertificateIssued.bind(this),
100
+ onCertificateFailed: this.handleCertificateFailed.bind(this),
101
+ onCertificateExpiring: (data) => {
102
+ this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
103
+ }
104
+ });
105
+ this.logger.info('External Port80Handler connected to CertificateManager');
106
+ // Register domains with Port80Handler if we have any certificates cached
107
+ if (this.certificateCache.size > 0) {
108
+ const domains = Array.from(this.certificateCache.keys())
109
+ .filter(domain => !domain.includes('*')); // Skip wildcard domains
110
+ this.registerDomainsWithPort80Handler(domains);
111
+ }
112
+ }
113
+ /**
114
+ * Handle newly issued or renewed certificates from Port80Handler
115
+ */
116
+ handleCertificateIssued(data) {
117
+ const { domain, certificate, privateKey, expiryDate } = data;
118
+ this.logger.info(`Certificate ${this.certificateCache.has(domain) ? 'renewed' : 'issued'} for ${domain}, valid until ${expiryDate.toISOString()}`);
119
+ // Update certificate in HTTPS server
120
+ this.updateCertificateCache(domain, certificate, privateKey, expiryDate);
121
+ // Save the certificate to the filesystem if not using external handler
122
+ if (!this.externalPort80Handler && this.options.acme?.certificateStore) {
123
+ this.saveCertificateToStore(domain, certificate, privateKey);
124
+ }
125
+ }
126
+ /**
127
+ * Handle certificate issuance failures
128
+ */
129
+ handleCertificateFailed(data) {
130
+ this.logger.error(`Certificate issuance failed for ${data.domain}: ${data.error}`);
131
+ }
132
+ /**
133
+ * Saves certificate and private key to the filesystem
134
+ */
135
+ saveCertificateToStore(domain, certificate, privateKey) {
136
+ try {
137
+ const certPath = path.join(this.certificateStoreDir, `${domain}.cert.pem`);
138
+ const keyPath = path.join(this.certificateStoreDir, `${domain}.key.pem`);
139
+ fs.writeFileSync(certPath, certificate);
140
+ fs.writeFileSync(keyPath, privateKey);
141
+ // Ensure private key has restricted permissions
142
+ try {
143
+ fs.chmodSync(keyPath, 0o600);
144
+ }
145
+ catch (error) {
146
+ this.logger.warn(`Failed to set permissions on private key for ${domain}: ${error}`);
147
+ }
148
+ this.logger.info(`Saved certificate for ${domain} to ${certPath}`);
149
+ }
150
+ catch (error) {
151
+ this.logger.error(`Failed to save certificate for ${domain}: ${error}`);
152
+ }
153
+ }
154
+ /**
155
+ * Handles SNI (Server Name Indication) for TLS connections
156
+ * Used by the HTTPS server to select the correct certificate for each domain
157
+ */
158
+ handleSNI(domain, cb) {
159
+ this.logger.debug(`SNI request for domain: ${domain}`);
160
+ // Check if we have a certificate for this domain
161
+ const certs = this.certificateCache.get(domain);
162
+ if (certs) {
163
+ try {
164
+ // Create TLS context with the cached certificate
165
+ const context = plugins.tls.createSecureContext({
166
+ key: certs.key,
167
+ cert: certs.cert
168
+ });
169
+ this.logger.debug(`Using cached certificate for ${domain}`);
170
+ cb(null, context);
171
+ return;
172
+ }
173
+ catch (err) {
174
+ this.logger.error(`Error creating secure context for ${domain}:`, err);
175
+ }
176
+ }
177
+ // No existing certificate: trigger dynamic provisioning via Port80Handler
178
+ if (this.port80Handler) {
179
+ try {
180
+ this.logger.info(`Triggering on-demand certificate retrieval for ${domain}`);
181
+ this.port80Handler.addDomain({
182
+ domainName: domain,
183
+ sslRedirect: false,
184
+ acmeMaintenance: true
185
+ });
186
+ }
187
+ catch (err) {
188
+ this.logger.error(`Error registering domain for on-demand certificate: ${domain}`, err);
189
+ }
190
+ }
191
+ // Check if we should trigger certificate issuance
192
+ if (this.options.acme?.enabled && this.port80Handler && !domain.includes('*')) {
193
+ // Check if this domain is already registered
194
+ const certData = this.port80Handler.getCertificate(domain);
195
+ if (!certData) {
196
+ this.logger.info(`No certificate found for ${domain}, registering for issuance`);
197
+ // Register with new domain options format
198
+ const domainOptions = {
199
+ domainName: domain,
200
+ sslRedirect: true,
201
+ acmeMaintenance: true
202
+ };
203
+ this.port80Handler.addDomain(domainOptions);
204
+ }
205
+ }
206
+ // Fall back to default certificate
207
+ try {
208
+ const context = plugins.tls.createSecureContext({
209
+ key: this.defaultCertificates.key,
210
+ cert: this.defaultCertificates.cert
211
+ });
212
+ this.logger.debug(`Using default certificate for ${domain}`);
213
+ cb(null, context);
214
+ }
215
+ catch (err) {
216
+ this.logger.error(`Error creating default secure context:`, err);
217
+ cb(new Error('Cannot create secure context'), null);
218
+ }
219
+ }
220
+ /**
221
+ * Updates certificate in cache
222
+ */
223
+ updateCertificateCache(domain, certificate, privateKey, expiryDate) {
224
+ // Update certificate context in HTTPS server if it's running
225
+ if (this.httpsServer) {
226
+ try {
227
+ this.httpsServer.addContext(domain, {
228
+ key: privateKey,
229
+ cert: certificate
230
+ });
231
+ this.logger.debug(`Updated SSL context for domain: ${domain}`);
232
+ }
233
+ catch (error) {
234
+ this.logger.error(`Error updating SSL context for domain ${domain}:`, error);
235
+ }
236
+ }
237
+ // Update certificate in cache
238
+ this.certificateCache.set(domain, {
239
+ key: privateKey,
240
+ cert: certificate,
241
+ expires: expiryDate
242
+ });
243
+ }
244
+ /**
245
+ * Gets a certificate for a domain
246
+ */
247
+ getCertificate(domain) {
248
+ return this.certificateCache.get(domain);
249
+ }
250
+ /**
251
+ * Requests a new certificate for a domain
252
+ */
253
+ async requestCertificate(domain) {
254
+ if (!this.options.acme?.enabled && !this.externalPort80Handler) {
255
+ this.logger.warn('ACME certificate management is not enabled');
256
+ return false;
257
+ }
258
+ if (!this.port80Handler) {
259
+ this.logger.error('Port80Handler is not initialized');
260
+ return false;
261
+ }
262
+ // Skip wildcard domains - can't get certs for these with HTTP-01 validation
263
+ if (domain.includes('*')) {
264
+ this.logger.error(`Cannot request certificate for wildcard domain: ${domain}`);
265
+ return false;
266
+ }
267
+ try {
268
+ // Use the new domain options format
269
+ const domainOptions = {
270
+ domainName: domain,
271
+ sslRedirect: true,
272
+ acmeMaintenance: true
273
+ };
274
+ this.port80Handler.addDomain(domainOptions);
275
+ this.logger.info(`Certificate request submitted for domain: ${domain}`);
276
+ return true;
277
+ }
278
+ catch (error) {
279
+ this.logger.error(`Error requesting certificate for domain ${domain}:`, error);
280
+ return false;
281
+ }
282
+ }
283
+ /**
284
+ * Registers domains with Port80Handler for ACME certificate management
285
+ */
286
+ registerDomainsWithPort80Handler(domains) {
287
+ if (!this.port80Handler) {
288
+ this.logger.warn('Port80Handler is not initialized');
289
+ return;
290
+ }
291
+ for (const domain of domains) {
292
+ // Skip wildcard domains - can't get certs for these with HTTP-01 validation
293
+ if (domain.includes('*')) {
294
+ this.logger.info(`Skipping wildcard domain for ACME: ${domain}`);
295
+ continue;
296
+ }
297
+ // Skip domains already with certificates if configured to do so
298
+ if (this.options.acme?.skipConfiguredCerts) {
299
+ const cachedCert = this.certificateCache.get(domain);
300
+ if (cachedCert) {
301
+ this.logger.info(`Skipping domain with existing certificate: ${domain}`);
302
+ continue;
303
+ }
304
+ }
305
+ // Register the domain for certificate issuance with new domain options format
306
+ const domainOptions = {
307
+ domainName: domain,
308
+ sslRedirect: true,
309
+ acmeMaintenance: true
310
+ };
311
+ this.port80Handler.addDomain(domainOptions);
312
+ this.logger.info(`Registered domain for ACME certificate issuance: ${domain}`);
313
+ }
314
+ }
315
+ /**
316
+ * Initialize internal Port80Handler
317
+ */
318
+ async initializePort80Handler() {
319
+ // Skip if using external handler
320
+ if (this.externalPort80Handler) {
321
+ this.logger.info('Using external Port80Handler, skipping initialization');
322
+ return this.port80Handler;
323
+ }
324
+ if (!this.options.acme?.enabled) {
325
+ return null;
326
+ }
327
+ // Build and configure Port80Handler
328
+ this.port80Handler = buildPort80Handler({
329
+ port: this.options.acme.port,
330
+ accountEmail: this.options.acme.accountEmail,
331
+ useProduction: this.options.acme.useProduction,
332
+ httpsRedirectPort: this.options.port, // Redirect to our HTTPS port
333
+ enabled: this.options.acme.enabled,
334
+ certificateStore: this.options.acme.certificateStore,
335
+ skipConfiguredCerts: this.options.acme.skipConfiguredCerts
336
+ });
337
+ // Subscribe to Port80Handler events
338
+ subscribeToPort80Handler(this.port80Handler, {
339
+ onCertificateIssued: this.handleCertificateIssued.bind(this),
340
+ onCertificateRenewed: this.handleCertificateIssued.bind(this),
341
+ onCertificateFailed: this.handleCertificateFailed.bind(this),
342
+ onCertificateExpiring: (data) => {
343
+ this.logger.info(`Certificate for ${data.domain} expires in ${data.daysRemaining} days`);
344
+ }
345
+ });
346
+ // Start the handler
347
+ try {
348
+ await this.port80Handler.start();
349
+ this.logger.info(`Port80Handler started on port ${this.options.acme.port}`);
350
+ return this.port80Handler;
351
+ }
352
+ catch (error) {
353
+ this.logger.error(`Failed to start Port80Handler: ${error}`);
354
+ this.port80Handler = null;
355
+ return null;
356
+ }
357
+ }
358
+ /**
359
+ * Stop the Port80Handler if it was internally created
360
+ */
361
+ async stopPort80Handler() {
362
+ if (this.port80Handler && !this.externalPort80Handler) {
363
+ try {
364
+ await this.port80Handler.stop();
365
+ this.logger.info('Port80Handler stopped');
366
+ }
367
+ catch (error) {
368
+ this.logger.error('Error stopping Port80Handler', error);
369
+ }
370
+ }
371
+ }
372
+ }
373
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUtbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvbmV0d29yay1wcm94eS9jZXJ0aWZpY2F0ZS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxJQUFJLENBQUM7QUFDekIsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNwQyxPQUFPLEVBQW1FLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNwRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUNuRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUM1RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUczRTs7R0FFRztBQUNILE1BQU0sT0FBTyxrQkFBa0I7SUFTN0IsWUFBb0IsT0FBNkI7UUFBN0IsWUFBTyxHQUFQLE9BQU8sQ0FBc0I7UUFQekMscUJBQWdCLEdBQW1DLElBQUksR0FBRyxFQUFFLENBQUM7UUFDN0Qsa0JBQWEsR0FBeUIsSUFBSSxDQUFDO1FBQzNDLDBCQUFxQixHQUFZLEtBQUssQ0FBQztRQUd2QyxnQkFBVyxHQUFnQyxJQUFJLENBQUM7UUFHdEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsSUFBSSxTQUFTLENBQUMsQ0FBQztRQUNyRixJQUFJLENBQUMsTUFBTSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxDQUFDO1FBRXZELDRDQUE0QztRQUM1QyxJQUFJLENBQUM7WUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO2dCQUM3QyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM1RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3Q0FBd0MsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQztZQUN2RixDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxpREFBaUQsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3RSxDQUFDO1FBRUQsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksdUJBQXVCO1FBQzVCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvRCwyRkFBMkY7UUFDM0YsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTNFLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxtQkFBbUIsR0FBRztnQkFDekIsR0FBRyxFQUFFLEVBQUUsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLEVBQUUsTUFBTSxDQUFDO2dCQUM1RCxJQUFJLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsRUFBRSxNQUFNLENBQUM7YUFDL0QsQ0FBQztZQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUUvRCw2Q0FBNkM7WUFDN0MsSUFBSSxDQUFDO2dCQUNILCtEQUErRDtnQkFDL0Qsc0ZBQXNGO2dCQUN0RixJQUFJLENBQUMsbUJBQW1CLEdBQUc7b0JBQ3pCLEdBQUcsRUFBRSxzQkFBc0I7b0JBQzNCLElBQUksRUFBRSx1QkFBdUI7aUJBQzlCLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQztZQUM5RCxDQUFDO1lBQUMsT0FBTyxhQUFhLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsMENBQTBDLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQzdFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztZQUNqRSxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLGNBQWMsQ0FBQyxNQUE0QjtRQUNoRCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQztJQUM1QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxzQkFBc0I7UUFDM0IsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksd0JBQXdCLENBQUMsT0FBc0I7UUFDcEQsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDdEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUVBQWlFLENBQUMsQ0FBQztZQUVwRixzQ0FBc0M7WUFDdEMsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUNuQyxrREFBa0Q7Z0JBQ2xELElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztnQkFDNUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUM3RSxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixDQUFDLENBQUM7Z0JBQzVFLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsaUJBQWlCLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNoRixDQUFDO1FBQ0gsQ0FBQztRQUVELDJCQUEyQjtRQUMzQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDO1FBRWxDLG9DQUFvQztRQUNwQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQzNDLG1CQUFtQixFQUFFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzVELG9CQUFvQixFQUFFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzdELG1CQUFtQixFQUFFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQzVELHFCQUFxQixFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQzlCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLENBQUMsTUFBTSxlQUFlLElBQUksQ0FBQyxhQUFhLE9BQU8sQ0FBQyxDQUFDO1lBQzNGLENBQUM7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx3REFBd0QsQ0FBQyxDQUFDO1FBRTNFLHlFQUF5RTtRQUN6RSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7aUJBQ3JELE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsd0JBQXdCO1lBRXBFLElBQUksQ0FBQyxnQ0FBZ0MsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNqRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssdUJBQXVCLENBQUMsSUFBbUY7UUFDakgsTUFBTSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQztRQUU3RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxRQUFRLE1BQU0saUJBQWlCLFVBQVUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFbkoscUNBQXFDO1FBQ3JDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUV6RSx1RUFBdUU7UUFDdkUsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3ZFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQy9ELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyx1QkFBdUIsQ0FBQyxJQUF1QztRQUNyRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBRUQ7O09BRUc7SUFDSyxzQkFBc0IsQ0FBQyxNQUFjLEVBQUUsV0FBbUIsRUFBRSxVQUFrQjtRQUNwRixJQUFJLENBQUM7WUFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLE1BQU0sV0FBVyxDQUFDLENBQUM7WUFDM0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxDQUFDO1lBRXpFLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQ3hDLEVBQUUsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBRXRDLGdEQUFnRDtZQUNoRCxJQUFJLENBQUM7Z0JBQ0gsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDL0IsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELE1BQU0sS0FBSyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZGLENBQUM7WUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx5QkFBeUIsTUFBTSxPQUFPLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsTUFBTSxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUUsQ0FBQztJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSSxTQUFTLENBQUMsTUFBYyxFQUFFLEVBQStEO1FBQzlGLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDJCQUEyQixNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRXZELGlEQUFpRDtRQUNqRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2hELElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixJQUFJLENBQUM7Z0JBQ0gsaURBQWlEO2dCQUNqRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO29CQUM5QyxHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7b0JBQ2QsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO2lCQUNqQixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQzVELEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xCLE9BQU87WUFDVCxDQUFDO1lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztnQkFDYixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsTUFBTSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDekUsQ0FBQztRQUNILENBQUM7UUFDRCwwRUFBMEU7UUFDMUUsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDO2dCQUNILElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtEQUFrRCxNQUFNLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RSxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQztvQkFDM0IsVUFBVSxFQUFFLE1BQU07b0JBQ2xCLFdBQVcsRUFBRSxLQUFLO29CQUNsQixlQUFlLEVBQUUsSUFBSTtpQkFDdEIsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsdURBQXVELE1BQU0sRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzFGLENBQUM7UUFDSCxDQUFDO1FBRUQsa0RBQWtEO1FBQ2xELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDOUUsNkNBQTZDO1lBQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRTNELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsTUFBTSw0QkFBNEIsQ0FBQyxDQUFDO2dCQUVqRiwwQ0FBMEM7Z0JBQzFDLE1BQU0sYUFBYSxHQUFtQjtvQkFDcEMsVUFBVSxFQUFFLE1BQU07b0JBQ2xCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixlQUFlLEVBQUUsSUFBSTtpQkFDdEIsQ0FBQztnQkFFRixJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztRQUVELG1DQUFtQztRQUNuQyxJQUFJLENBQUM7WUFDSCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO2dCQUM5QyxHQUFHLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUc7Z0JBQ2pDLElBQUksRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSTthQUNwQyxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUM3RCxFQUFFLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDakUsRUFBRSxDQUFDLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLHNCQUFzQixDQUFDLE1BQWMsRUFBRSxXQUFtQixFQUFFLFVBQWtCLEVBQUUsVUFBaUI7UUFDdEcsNkRBQTZEO1FBQzdELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUU7b0JBQ2xDLEdBQUcsRUFBRSxVQUFVO29CQUNmLElBQUksRUFBRSxXQUFXO2lCQUNsQixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDakUsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMseUNBQXlDLE1BQU0sR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQy9FLENBQUM7UUFDSCxDQUFDO1FBRUQsOEJBQThCO1FBQzlCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFO1lBQ2hDLEdBQUcsRUFBRSxVQUFVO1lBQ2YsSUFBSSxFQUFFLFdBQVc7WUFDakIsT0FBTyxFQUFFLFVBQVU7U0FDcEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksY0FBYyxDQUFDLE1BQWM7UUFDbEMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFjO1FBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUMvRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1lBQy9ELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQztZQUN0RCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCw0RUFBNEU7UUFDNUUsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsbURBQW1ELE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDL0UsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsb0NBQW9DO1lBQ3BDLE1BQU0sYUFBYSxHQUFtQjtnQkFDcEMsVUFBVSxFQUFFLE1BQU07Z0JBQ2xCLFdBQVcsRUFBRSxJQUFJO2dCQUNqQixlQUFlLEVBQUUsSUFBSTthQUN0QixDQUFDO1lBRUYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsNkNBQTZDLE1BQU0sRUFBRSxDQUFDLENBQUM7WUFDeEUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxNQUFNLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvRSxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQ0FBZ0MsQ0FBQyxPQUFpQjtRQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxDQUFDLENBQUM7WUFDckQsT0FBTztRQUNULENBQUM7UUFFRCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzdCLDRFQUE0RTtZQUM1RSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsc0NBQXNDLE1BQU0sRUFBRSxDQUFDLENBQUM7Z0JBQ2pFLFNBQVM7WUFDWCxDQUFDO1lBRUQsZ0VBQWdFO1lBQ2hFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztnQkFDM0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDckQsSUFBSSxVQUFVLEVBQUUsQ0FBQztvQkFDZixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyw4Q0FBOEMsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDekUsU0FBUztnQkFDWCxDQUFDO1lBQ0gsQ0FBQztZQUVELDhFQUE4RTtZQUM5RSxNQUFNLGFBQWEsR0FBbUI7Z0JBQ3BDLFVBQVUsRUFBRSxNQUFNO2dCQUNsQixXQUFXLEVBQUUsSUFBSTtnQkFDakIsZUFBZSxFQUFFLElBQUk7YUFDdEIsQ0FBQztZQUVGLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsdUJBQXVCO1FBQ2xDLGlDQUFpQztRQUNqQyxJQUFJLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLHVEQUF1RCxDQUFDLENBQUM7WUFDMUUsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQzVCLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDaEMsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyxhQUFhLEdBQUcsa0JBQWtCLENBQUM7WUFDdEMsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUk7WUFDNUIsWUFBWSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVk7WUFDNUMsYUFBYSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWE7WUFDOUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsNkJBQTZCO1lBQ25FLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQ2xDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQjtZQUNwRCxtQkFBbUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxtQkFBbUI7U0FDM0QsQ0FBQyxDQUFDO1FBQ0gsb0NBQW9DO1FBQ3BDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDM0MsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUQsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDN0QsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDNUQscUJBQXFCLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDOUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLElBQUksQ0FBQyxNQUFNLGVBQWUsSUFBSSxDQUFDLGFBQWEsT0FBTyxDQUFDLENBQUM7WUFDM0YsQ0FBQztTQUNGLENBQUMsQ0FBQztRQUVILG9CQUFvQjtRQUNwQixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDNUUsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQzVCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7WUFDMUIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGlCQUFpQjtRQUM1QixJQUFJLElBQUksQ0FBQyxhQUFhLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUN0RCxJQUFJLENBQUM7Z0JBQ0gsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBQzVDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDhCQUE4QixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGIn0=
@@ -0,0 +1,47 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import { type INetworkProxyOptions } from './models/types.js';
3
+ /**
4
+ * Manages a pool of backend connections for efficient reuse
5
+ */
6
+ export declare class ConnectionPool {
7
+ private options;
8
+ private connectionPool;
9
+ private roundRobinPositions;
10
+ private logger;
11
+ constructor(options: INetworkProxyOptions);
12
+ /**
13
+ * Get a connection from the pool or create a new one
14
+ */
15
+ getConnection(host: string, port: number): Promise<plugins.net.Socket>;
16
+ /**
17
+ * Return a connection to the pool for reuse
18
+ */
19
+ returnConnection(socket: plugins.net.Socket, host: string, port: number): void;
20
+ /**
21
+ * Cleanup the connection pool by removing idle connections
22
+ * or reducing pool size if it exceeds the configured maximum
23
+ */
24
+ cleanupConnectionPool(): void;
25
+ /**
26
+ * Close all connections in the pool
27
+ */
28
+ closeAllConnections(): void;
29
+ /**
30
+ * Get load balancing target using round-robin
31
+ */
32
+ getNextTarget(targets: string[], port: number): {
33
+ host: string;
34
+ port: number;
35
+ };
36
+ /**
37
+ * Gets the connection pool status
38
+ */
39
+ getPoolStatus(): Record<string, {
40
+ total: number;
41
+ idle: number;
42
+ }>;
43
+ /**
44
+ * Setup a periodic cleanup task
45
+ */
46
+ setupPeriodicCleanup(interval?: number): NodeJS.Timeout;
47
+ }