@alternative-path/testlens-playwright-reporter 0.3.9 → 0.4.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.
package/index.d.ts CHANGED
@@ -157,9 +157,15 @@ export interface SpecData {
157
157
  export declare class TestLensReporter implements Reporter {
158
158
  private config;
159
159
  private axiosInstance;
160
+ /**
161
+ * Get bundled CA certificates for TestLens
162
+ * Uses custom CA bundle packaged with the reporter
163
+ * This ensures SSL works out-of-the-box without relying on system certificates
164
+ */
165
+ private static getBundledCaCertificates;
160
166
  /**
161
167
  * Automatically detect and load system CA certificates
162
- * Uses Node.js built-in root certificates (works across all platforms)
168
+ * Uses bundled certificates as primary source, falls back to system certificates
163
169
  */
164
170
  private static getSystemCaCertificates;
165
171
  private runId;
package/index.js CHANGED
@@ -22,16 +22,36 @@ async function getMime() {
22
22
  }
23
23
  class TestLensReporter {
24
24
  /**
25
- * Automatically detect and load system CA certificates
26
- * Uses Node.js built-in root certificates (works across all platforms)
25
+ * Get bundled CA certificates for TestLens
26
+ * Uses custom CA bundle packaged with the reporter
27
+ * This ensures SSL works out-of-the-box without relying on system certificates
27
28
  */
28
- static getSystemCaCertificates() {
29
- // Use Node.js's built-in root certificates (available in Node.js 12.3.0+)
30
- // This includes all common root CAs and works reliably across Windows, macOS, and Linux
29
+ static getBundledCaCertificates() {
30
+ try {
31
+ // Load the bundled CA certificate file for testlens.qa-path.com
32
+ const certPath = path.join(__dirname, 'testlens-ca-bundle.pem');
33
+ if (fs.existsSync(certPath)) {
34
+ const certData = fs.readFileSync(certPath, 'utf8');
35
+ // Split the bundle into individual certificates
36
+ const certs = certData.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g);
37
+ if (certs && certs.length > 0) {
38
+ const buffers = certs.map(cert => Buffer.from(cert, 'utf8'));
39
+ if (process.env.DEBUG) {
40
+ console.log(`✓ Using bundled TestLens CA certificates (${buffers.length} certificate(s))`);
41
+ }
42
+ return buffers;
43
+ }
44
+ }
45
+ }
46
+ catch (error) {
47
+ if (process.env.DEBUG) {
48
+ console.log('⚠️ Bundled CA certificate not available, will use fallback');
49
+ }
50
+ }
51
+ // Fallback to Node.js built-in root certificates
31
52
  try {
32
53
  if (tls.rootCertificates && Array.isArray(tls.rootCertificates) && tls.rootCertificates.length > 0) {
33
- // Convert string certificates to Buffer
34
- const rootCerts = tls.rootCertificates.map(cert => Buffer.from(cert));
54
+ const rootCerts = tls.rootCertificates.map(cert => Buffer.from(cert, 'utf8'));
35
55
  if (process.env.DEBUG) {
36
56
  console.log(`✓ Using Node.js built-in root certificates (${rootCerts.length} certificates)`);
37
57
  }
@@ -39,15 +59,25 @@ class TestLensReporter {
39
59
  }
40
60
  }
41
61
  catch (error) {
42
- // Fall through to file-based detection if tls.rootCertificates is not available
43
62
  if (process.env.DEBUG) {
44
- console.log('⚠️ Node.js built-in root certificates not available, trying file-based detection');
63
+ console.log('⚠️ Node.js built-in root certificates not available');
45
64
  }
46
65
  }
66
+ return undefined;
67
+ }
68
+ /**
69
+ * Automatically detect and load system CA certificates
70
+ * Uses bundled certificates as primary source, falls back to system certificates
71
+ */
72
+ static getSystemCaCertificates() {
73
+ // First, try to use our bundled certificates (Node.js rootCertificates)
74
+ const bundledCerts = TestLensReporter.getBundledCaCertificates();
75
+ if (bundledCerts && bundledCerts.length > 0) {
76
+ return bundledCerts;
77
+ }
47
78
  // Fallback: Try to load from file system (for older Node.js versions or special cases)
48
79
  const platform = os.platform();
49
80
  const certificates = [];
50
- // Fallback: Try to load certificates from common file system locations
51
81
  const certPaths = [];
52
82
  if (platform === 'darwin') {
53
83
  // macOS: Common certificate locations
@@ -156,42 +186,44 @@ class TestLensReporter {
156
186
  // Determine SSL validation behavior
157
187
  let rejectUnauthorized = true; // Default to secure
158
188
  let ca = undefined;
159
- // Automatically detect and load system CA certificates
160
- // This helps resolve "unable to get local issuer certificate" errors
161
- const systemCerts = TestLensReporter.getSystemCaCertificates();
189
+ // Use bundled CA certificates as primary source (Node.js rootCertificates)
190
+ // This ensures consistent behavior across all platforms
191
+ const bundledCerts = TestLensReporter.getBundledCaCertificates();
162
192
  // Load custom CA certificate if explicitly provided (for advanced users)
193
+ // Custom certificates will be combined with bundled certificates
163
194
  if (this.config.caCertificate) {
164
195
  try {
165
196
  if (fs.existsSync(this.config.caCertificate)) {
166
197
  const customCert = fs.readFileSync(this.config.caCertificate);
167
- // Combine system certs with custom cert if system certs are available
168
- if (systemCerts && Array.isArray(systemCerts) && systemCerts.length > 0) {
169
- ca = [...systemCerts, customCert];
198
+ // Combine bundled certs with custom cert
199
+ if (bundledCerts && Array.isArray(bundledCerts) && bundledCerts.length > 0) {
200
+ ca = [...bundledCerts, customCert];
201
+ console.log(`✓ Using bundled CA certificates + custom certificate: ${this.config.caCertificate}`);
170
202
  }
171
203
  else {
172
204
  ca = customCert;
205
+ console.log(`✓ Using custom CA certificate: ${this.config.caCertificate}`);
173
206
  }
174
- console.log(`✓ Using custom CA certificate: ${this.config.caCertificate}`);
175
207
  }
176
208
  else {
177
209
  console.warn(`⚠️ CA certificate file not found: ${this.config.caCertificate}`);
178
- // Fall back to system certs if custom cert not found
179
- ca = systemCerts || undefined;
210
+ // Fall back to bundled certs if custom cert not found
211
+ ca = bundledCerts || undefined;
180
212
  }
181
213
  }
182
214
  catch (error) {
183
215
  console.warn(`⚠️ Failed to read CA certificate file: ${this.config.caCertificate}`, error.message);
184
- // Fall back to system certs if custom cert read fails
185
- ca = systemCerts || undefined;
216
+ // Fall back to bundled certs if custom cert read fails
217
+ ca = bundledCerts || undefined;
186
218
  }
187
219
  }
188
220
  else {
189
- // Use automatically detected system certificates
190
- // On Windows, systemCerts will be undefined to let Node.js use Windows certificate store
191
- // On Unix systems, systemCerts will contain certificates or be undefined
192
- ca = systemCerts;
193
- // If ca is undefined, Node.js will use its default certificate store
194
- // This is the correct behavior, especially on Windows
221
+ // Use bundled certificates as primary source
222
+ // This works reliably across all platforms (Windows, macOS, Linux)
223
+ ca = bundledCerts || undefined;
224
+ if (ca && process.env.DEBUG) {
225
+ console.log(`✓ Using bundled CA certificates (${Array.isArray(ca) ? ca.length : 1} certificates)`);
226
+ }
195
227
  }
196
228
  // Check various ways SSL validation can be disabled (in order of precedence)
197
229
  if (this.config.ignoreSslErrors) {
package/index.ts CHANGED
@@ -185,33 +185,63 @@ export class TestLensReporter implements Reporter {
185
185
  private axiosInstance: AxiosInstance;
186
186
 
187
187
  /**
188
- * Automatically detect and load system CA certificates
189
- * Uses Node.js built-in root certificates (works across all platforms)
188
+ * Get bundled CA certificates for TestLens
189
+ * Uses custom CA bundle packaged with the reporter
190
+ * This ensures SSL works out-of-the-box without relying on system certificates
190
191
  */
191
- private static getSystemCaCertificates(): Buffer[] | undefined {
192
- // Use Node.js's built-in root certificates (available in Node.js 12.3.0+)
193
- // This includes all common root CAs and works reliably across Windows, macOS, and Linux
192
+ private static getBundledCaCertificates(): Buffer[] | undefined {
193
+ try {
194
+ // Load the bundled CA certificate file for testlens.qa-path.com
195
+ const certPath = path.join(__dirname, 'testlens-ca-bundle.pem');
196
+ if (fs.existsSync(certPath)) {
197
+ const certData = fs.readFileSync(certPath, 'utf8');
198
+ // Split the bundle into individual certificates
199
+ const certs = certData.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/g);
200
+ if (certs && certs.length > 0) {
201
+ const buffers = certs.map(cert => Buffer.from(cert, 'utf8'));
202
+ if (process.env.DEBUG) {
203
+ console.log(`✓ Using bundled TestLens CA certificates (${buffers.length} certificate(s))`);
204
+ }
205
+ return buffers;
206
+ }
207
+ }
208
+ } catch (error) {
209
+ if (process.env.DEBUG) {
210
+ console.log('⚠️ Bundled CA certificate not available, will use fallback');
211
+ }
212
+ }
213
+
214
+ // Fallback to Node.js built-in root certificates
194
215
  try {
195
216
  if (tls.rootCertificates && Array.isArray(tls.rootCertificates) && tls.rootCertificates.length > 0) {
196
- // Convert string certificates to Buffer
197
- const rootCerts = tls.rootCertificates.map(cert => Buffer.from(cert));
217
+ const rootCerts = tls.rootCertificates.map(cert => Buffer.from(cert, 'utf8'));
198
218
  if (process.env.DEBUG) {
199
219
  console.log(`✓ Using Node.js built-in root certificates (${rootCerts.length} certificates)`);
200
220
  }
201
221
  return rootCerts;
202
222
  }
203
223
  } catch (error) {
204
- // Fall through to file-based detection if tls.rootCertificates is not available
205
224
  if (process.env.DEBUG) {
206
- console.log('⚠️ Node.js built-in root certificates not available, trying file-based detection');
225
+ console.log('⚠️ Node.js built-in root certificates not available');
207
226
  }
208
227
  }
228
+ return undefined;
229
+ }
230
+
231
+ /**
232
+ * Automatically detect and load system CA certificates
233
+ * Uses bundled certificates as primary source, falls back to system certificates
234
+ */
235
+ private static getSystemCaCertificates(): Buffer[] | undefined {
236
+ // First, try to use our bundled certificates (Node.js rootCertificates)
237
+ const bundledCerts = TestLensReporter.getBundledCaCertificates();
238
+ if (bundledCerts && bundledCerts.length > 0) {
239
+ return bundledCerts;
240
+ }
209
241
 
210
242
  // Fallback: Try to load from file system (for older Node.js versions or special cases)
211
243
  const platform = os.platform();
212
244
  const certificates: Buffer[] = [];
213
-
214
- // Fallback: Try to load certificates from common file system locations
215
245
  const certPaths: string[] = [];
216
246
 
217
247
  if (platform === 'darwin') {
@@ -348,39 +378,41 @@ export class TestLensReporter implements Reporter {
348
378
  let rejectUnauthorized = true; // Default to secure
349
379
  let ca: Buffer | string | Buffer[] | undefined = undefined;
350
380
 
351
- // Automatically detect and load system CA certificates
352
- // This helps resolve "unable to get local issuer certificate" errors
353
- const systemCerts = TestLensReporter.getSystemCaCertificates();
381
+ // Use bundled CA certificates as primary source (Node.js rootCertificates)
382
+ // This ensures consistent behavior across all platforms
383
+ const bundledCerts = TestLensReporter.getBundledCaCertificates();
354
384
 
355
385
  // Load custom CA certificate if explicitly provided (for advanced users)
386
+ // Custom certificates will be combined with bundled certificates
356
387
  if (this.config.caCertificate) {
357
388
  try {
358
389
  if (fs.existsSync(this.config.caCertificate)) {
359
390
  const customCert = fs.readFileSync(this.config.caCertificate);
360
- // Combine system certs with custom cert if system certs are available
361
- if (systemCerts && Array.isArray(systemCerts) && systemCerts.length > 0) {
362
- ca = [...systemCerts, customCert];
391
+ // Combine bundled certs with custom cert
392
+ if (bundledCerts && Array.isArray(bundledCerts) && bundledCerts.length > 0) {
393
+ ca = [...bundledCerts, customCert];
394
+ console.log(`✓ Using bundled CA certificates + custom certificate: ${this.config.caCertificate}`);
363
395
  } else {
364
396
  ca = customCert;
397
+ console.log(`✓ Using custom CA certificate: ${this.config.caCertificate}`);
365
398
  }
366
- console.log(`✓ Using custom CA certificate: ${this.config.caCertificate}`);
367
399
  } else {
368
400
  console.warn(`⚠️ CA certificate file not found: ${this.config.caCertificate}`);
369
- // Fall back to system certs if custom cert not found
370
- ca = systemCerts || undefined;
401
+ // Fall back to bundled certs if custom cert not found
402
+ ca = bundledCerts || undefined;
371
403
  }
372
404
  } catch (error) {
373
405
  console.warn(`⚠️ Failed to read CA certificate file: ${this.config.caCertificate}`, (error as Error).message);
374
- // Fall back to system certs if custom cert read fails
375
- ca = systemCerts || undefined;
406
+ // Fall back to bundled certs if custom cert read fails
407
+ ca = bundledCerts || undefined;
376
408
  }
377
409
  } else {
378
- // Use automatically detected system certificates
379
- // On Windows, systemCerts will be undefined to let Node.js use Windows certificate store
380
- // On Unix systems, systemCerts will contain certificates or be undefined
381
- ca = systemCerts;
382
- // If ca is undefined, Node.js will use its default certificate store
383
- // This is the correct behavior, especially on Windows
410
+ // Use bundled certificates as primary source
411
+ // This works reliably across all platforms (Windows, macOS, Linux)
412
+ ca = bundledCerts || undefined;
413
+ if (ca && process.env.DEBUG) {
414
+ console.log(`✓ Using bundled CA certificates (${Array.isArray(ca) ? ca.length : 1} certificates)`);
415
+ }
384
416
  }
385
417
 
386
418
  // Check various ways SSL validation can be disabled (in order of precedence)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alternative-path/testlens-playwright-reporter",
3
- "version": "0.3.9",
3
+ "version": "0.4.0",
4
4
  "description": "Universal Playwright reporter for TestLens - works with both TypeScript and JavaScript projects",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -14,6 +14,7 @@
14
14
  "lib/",
15
15
  "postinstall.js",
16
16
  "cross-env.js",
17
+ "testlens-ca-bundle.pem",
17
18
  "README.md",
18
19
  "CHANGELOG.md"
19
20
  ],
@@ -0,0 +1,88 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFvDCCBKSgAwIBAgIQCCpc5jpiqFvmHWmaKaa8zTANBgkqhkiG9w0BAQsFADA8
3
+ MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g
4
+ UlNBIDIwNDggTTA0MB4XDTI1MTExNDAwMDAwMFoXDTI2MTIxMzIzNTk1OVowGDEW
5
+ MBQGA1UEAwwNKi5xYS1wYXRoLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
6
+ AQoCggEBAMFsdDGpKLNQ9GayoFXQpE9VLNxEZ/76AaiJMj30Nkuf245KxcPdmPMQ
7
+ rklyBsKv2r4vGwqIrIh4ey59Zpi5z/GMtSP6DwPU/MGGRQGJ9Mpc2dhpxNvka7hW
8
+ 9+t/uFAMbwvAhAe82fahsd6q/jtRMChkKQ2Ndln41PPnTPzqqoc2GWdYJO69W1x0
9
+ 5CbovMOOoGKkskrS2TNe5+vYp8c8AWR6ga3zR2lxMVDAAXKcD/ejMq/FMR8TD9rf
10
+ 6pWnsalQE7UAIgSltu9hrJRttCnyC6343WIQKspd3x+fZ6WdqtR4YywLij9DMBgJ
11
+ KwYUHMjoY4lfkSgowhgnuCUFeqVhBrsCAwEAAaOCAtwwggLYMB8GA1UdIwQYMBaA
12
+ FB9SkmFWglR/gWbYHT0KqjJch90IMB0GA1UdDgQWBBSsbNiBXRvG7yzfgQnHA4Fm
13
+ Gvve1TAYBgNVHREEETAPgg0qLnFhLXBhdGguY29tMBMGA1UdIAQMMAowCAYGZ4EM
14
+ AQIBMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATA7BgNVHR8E
15
+ NDAyMDCgLqAshipodHRwOi8vY3JsLnIybTA0LmFtYXpvbnRydXN0LmNvbS9yMm0w
16
+ NC5jcmwwdQYIKwYBBQUHAQEEaTBnMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5y
17
+ Mm0wNC5hbWF6b250cnVzdC5jb20wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQucjJt
18
+ MDQuYW1hem9udHJ1c3QuY29tL3IybTA0LmNlcjAMBgNVHRMBAf8EAjAAMIIBfgYK
19
+ KwYBBAHWeQIEAgSCAW4EggFqAWgAdgDYCVU7lE96/8gWGW+UT4WrsPj8XodVJg8V
20
+ 0S5yu0VLFAAAAZqBmF/qAAAEAwBHMEUCIHg3mktTsuS8r57mR014haS8fqwcbqa1
21
+ P3so9Qd02JFBAiEAsHQf6eH9AL0HoG5jEVfz4aZdNp/Y8unnDO+ZWSfW/wcAdgDC
22
+ MX5XRRmjRe5/ON6ykEHrx8IhWiK/f9W1rXaa2Q5SzQAAAZqBmF/lAAAEAwBHMEUC
23
+ IQCZhIaG3vpxTThIdHhvNCymkHGKFLggUBcPCqYMdYVFpAIgW+BszH9Kdon3IKNJ
24
+ xKx5e4K+XZ+NhfXqqnCmPYeCwzQAdgCUTkOH+uzB74HzGSQmqBhlAcfTXzgCAT9y
25
+ Z31VNy4Z2AAAAZqBmF/1AAAEAwBHMEUCIQDGh+jKNI6NO30js2yl0ItBltCDGA5d
26
+ 3A1qoPf81FCF8wIgFTxoXXotS8nhDzOeyJh1wL6wKMxcwKXUUMcOKEjFsH4wDQYJ
27
+ KoZIhvcNAQELBQADggEBAMY6zXuf7YSu4s/nHd4qSjOq7mAPvWKSumPMXcRp4FfX
28
+ 16dAyqaiasX2B7dXccks4QeCUyNxCjh89irTYwgDcde8J05PEM9dpxUglyWE6gEB
29
+ r+pp8xJzT9hP2TmLhkNsFKhiT8aR+wz9fiALVDeQLyUS1GOSmnAXbH8MjZkm5Cxb
30
+ Taqb+N8alKrMf7Y9Cwf77KRFpKqm+b1e6h/EuVIJWAFau1jKVS5Qd6KTjyf0sRys
31
+ 7nvF3JqKVIb6BlTimNUq1wYMJKX6mOb/MlHo8juzKMb+MYUA5ZHrO36u3nOgThiI
32
+ oOJavnwzLhk7AWp8urdy9yTj8P3b/3H3VtCfYMeAabE=
33
+ -----END CERTIFICATE-----
34
+
35
+ -----BEGIN CERTIFICATE-----
36
+ MIIEXjCCA0agAwIBAgITB3MSTyqVLj7Rili9uF0bwM5fJzANBgkqhkiG9w0BAQsF
37
+ ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
38
+ b24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjYzNVoXDTMwMDgyMzIyMjYzNVowPDEL
39
+ MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT
40
+ QSAyMDQ4IE0wNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM3pVR6A
41
+ lQOp4xe776FdePXyejgA38mYx1ou9/jrpV6Sfn+/oqBKgwhY6ePsQHHQayWBJdBn
42
+ v4Wz363qRI4XUh9swBFJ11TnZ3LqOMvHmWq2+loA0QPtOfXdJ2fHBLrBrngtJ/GB
43
+ 0p5olAVYrSZgvQGP16Rf8ddtNyxEEhYm3HuhmNi+vSeAq1tLYJPAvRCXonTpWdSD
44
+ xY6hvdmxlqTYi82AtBXSfpGQ58HHM0hw0C6aQakghrwWi5fGslLOqzpimNMIsT7c
45
+ qa0GJx6JfKqJqmQQNplO2h8n9ZsFJgBowof01ppdoLAWg6caMOM0om/VILKaa30F
46
+ 9W/r8Qjah7ltGVkCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD
47
+ VR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV
48
+ HQ4EFgQUH1KSYVaCVH+BZtgdPQqqMlyH3QgwHwYDVR0jBBgwFoAUhBjMhTTsvAyU
49
+ lC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v
50
+ b2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov
51
+ L2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E
52
+ ODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv
53
+ b3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB
54
+ AQA+1O5UsAaNuW3lHzJtpNGwBnZd9QEYFtxpiAnIaV4qApnGS9OCw5ZPwie7YSlD
55
+ ZF5yyFPsFhUC2Q9uJHY/CRV1b5hIiGH0+6+w5PgKiY1MWuWT8VAaJjFxvuhM7a/e
56
+ fN2TIw1Wd6WCl6YRisunjQOrSP+unqC8A540JNyZ1JOE3jVqat3OZBGgMvihdj2w
57
+ Y23EpwesrKiQzkHzmvSH67PVW4ycbPy08HVZnBxZ5NrlGG9bwXR3fNTaz+c+Ej6c
58
+ 5AnwI3qkOFgSkg3Y75cdFz6pO/olK+e3AqygAcv0WjzmkDPuBjssuZjCHMC56oH3
59
+ GJkV29Di2j5prHJbwZjG1inU
60
+ -----END CERTIFICATE-----
61
+
62
+ -----BEGIN CERTIFICATE-----
63
+ MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF
64
+ ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj
65
+ b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x
66
+ OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1
67
+ dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL
68
+ MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
69
+ b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
70
+ ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
71
+ 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
72
+ IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
73
+ VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
74
+ 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
75
+ jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
76
+ BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW
77
+ gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH
78
+ MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH
79
+ MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy
80
+ MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0
81
+ LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF
82
+ AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW
83
+ MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma
84
+ eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK
85
+ bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN
86
+ 0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U
87
+ akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==
88
+ -----END CERTIFICATE-----