scanoss 0.40.1 → 0.40.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
5
  ## [Unreleased]
6
+ ## [0.40.2] (2026-06-08)
7
+ ### Fixed
8
+ - `scanoss-js wfp <file>` no longer emits an empty path in the `file=` line when fingerprinting a single file.
9
+
6
10
  ## [0.40.1] (2026-06-05)
7
11
  ### Fixed
8
12
  - `scanoss-js scan <file>` no longer fails with `ENOTDIR` when the scan target is a single file. The automatic `scanoss.json` settings lookup now resolves the file's parent directory instead of calling `readdir` on the file itself.
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.wfpHandler = wfpHandler;
7
7
  const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
8
9
  const cli_progress_1 = __importDefault(require("cli-progress"));
9
10
  const helpers_1 = require("./helpers");
10
11
  const ScannerTypes_1 = require("../../sdk/scanner/ScannerTypes");
@@ -17,13 +18,16 @@ async function wfpHandler(rootPath, options) {
17
18
  const pathIsFolder = await (0, helpers_1.isFolder)(rootPath);
18
19
  const wfpCalculator = new WfpCalculator_1.WfpCalculator();
19
20
  let filesToFingerprint = [];
21
+ let folderRoot = rootPath;
20
22
  if (pathIsFolder) {
21
23
  const tree = new Tree_1.Tree(rootPath);
22
24
  tree.build();
23
25
  filesToFingerprint = tree.getFileList(new ScanFilter_1.ScanFilter(""));
24
26
  }
25
27
  else {
26
- filesToFingerprint.push(rootPath);
28
+ const absoluteFilePath = path_1.default.resolve(rootPath);
29
+ filesToFingerprint.push(absoluteFilePath);
30
+ folderRoot = path_1.default.dirname(absoluteFilePath);
27
31
  }
28
32
  const optBar1 = { format: 'Fingerprinting Progress: [{bar}] {percentage}% | Fingerprinted {value} files of {total}' };
29
33
  const bar1 = new cli_progress_1.default.SingleBar(optBar1, cli_progress_1.default.Presets.shades_classic);
@@ -46,9 +50,9 @@ async function wfpHandler(rootPath, options) {
46
50
  console.log(fingerprints);
47
51
  }
48
52
  });
49
- const wfpInput = { fileList: filesToFingerprint, folderRoot: rootPath, obfuscate: options.obfuscate };
53
+ const wfpInput = { fileList: filesToFingerprint, folderRoot, obfuscate: options.obfuscate };
50
54
  if (options.hpsm)
51
55
  wfpInput.winnowingMode = ScannerTypes_1.WinnowingMode.FULL_WINNOWING_HPSM;
52
56
  await wfpCalculator.start(wfpInput);
53
57
  }
54
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ZwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy93ZnAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFhQSxnQ0E4Q0M7QUEzREQsNENBQW9CO0FBRXBCLGdFQUF1QztBQUV2Qyx1Q0FBcUM7QUFDckMsaUVBQThFO0FBRTlFLDZGQUEwRjtBQUUxRiw4Q0FBMkM7QUFDM0Msa0VBQStEO0FBR3hELEtBQUssVUFBVSxVQUFVLENBQUMsUUFBZ0IsRUFBRSxPQUFZO0lBRTdELFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFFLGtDQUFrQztJQUMzRSxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFFLDBDQUEwQztJQUNoRyxNQUFNLFlBQVksR0FBRyxNQUFNLElBQUEsa0JBQVEsRUFBQyxRQUFRLENBQUMsQ0FBQztJQUM5QyxNQUFNLGFBQWEsR0FBRyxJQUFJLDZCQUFhLEVBQUUsQ0FBQztJQUUxQyxJQUFJLGtCQUFrQixHQUFhLEVBQUUsQ0FBQztJQUN0QyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxHQUFHLElBQUksV0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLGtCQUFrQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSx1QkFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztTQUFNLENBQUM7UUFDTixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUdELE1BQU0sT0FBTyxHQUFHLEVBQUUsTUFBTSxFQUFFLHlGQUF5RixFQUFFLENBQUM7SUFDdEgsTUFBTSxJQUFJLEdBQUcsSUFBSSxzQkFBVyxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsc0JBQVcsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDcEYsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFekMsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDO0lBQ3RCLGFBQWEsQ0FBQyxFQUFFLENBQUMsNEJBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLGtCQUFzQyxFQUFFLEVBQUU7UUFDL0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQywyQkFBMkIsRUFBRSxDQUFDLENBQUM7UUFDakUsWUFBWSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUUsa0JBQWtCLENBQUMsVUFBVSxFQUFFLENBQUUsQ0FBQztJQUN4RSxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksT0FBTyxDQUFDLE9BQU87UUFDakIsYUFBYSxDQUFDLEVBQUUsQ0FBQyw0QkFBYSxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQVcsRUFBRSxFQUFFO1lBQzNELE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7SUFFTCxhQUFhLENBQUMsRUFBRSxDQUFDLDRCQUFhLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO1FBQ3RELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNaLElBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2xCLFlBQUUsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNqRCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQXNCLEVBQUMsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQTtJQUN2SCxJQUFHLE9BQU8sQ0FBQyxJQUFJO1FBQUUsUUFBUSxDQUFDLGFBQWEsR0FBRyw0QkFBYSxDQUFDLG1CQUFtQixDQUFDO0lBQzVFLE1BQU0sYUFBYSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUd0QyxDQUFDIn0=
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ZwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NsaS9jb21tYW5kcy93ZnAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFjQSxnQ0FpREM7QUEvREQsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUV4QixnRUFBdUM7QUFFdkMsdUNBQXFDO0FBQ3JDLGlFQUE4RTtBQUU5RSw2RkFBMEY7QUFFMUYsOENBQTJDO0FBQzNDLGtFQUErRDtBQUd4RCxLQUFLLFVBQVUsVUFBVSxDQUFDLFFBQWdCLEVBQUUsT0FBWTtJQUU3RCxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBRSxrQ0FBa0M7SUFDM0UsUUFBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBRSwwQ0FBMEM7SUFDaEcsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFBLGtCQUFRLEVBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUMsTUFBTSxhQUFhLEdBQUcsSUFBSSw2QkFBYSxFQUFFLENBQUM7SUFFMUMsSUFBSSxrQkFBa0IsR0FBYSxFQUFFLENBQUM7SUFDdEMsSUFBSSxVQUFVLEdBQUcsUUFBUSxDQUFDO0lBQzFCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEdBQUcsSUFBSSxXQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2Isa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLHVCQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM1RCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sZ0JBQWdCLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMxQyxVQUFVLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFHRCxNQUFNLE9BQU8sR0FBRyxFQUFFLE1BQU0sRUFBRSx5RkFBeUYsRUFBRSxDQUFDO0lBQ3RILE1BQU0sSUFBSSxHQUFHLElBQUksc0JBQVcsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLHNCQUFXLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3BGLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXpDLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztJQUN0QixhQUFhLENBQUMsRUFBRSxDQUFDLDRCQUFhLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxrQkFBc0MsRUFBRSxFQUFFO1FBQy9GLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDO1FBQ2pFLFlBQVksR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFFLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxDQUFFLENBQUM7SUFDeEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLE9BQU8sQ0FBQyxPQUFPO1FBQ2pCLGFBQWEsQ0FBQyxFQUFFLENBQUMsNEJBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFXLEVBQUUsRUFBRTtZQUMzRCxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO0lBRUwsYUFBYSxDQUFDLEVBQUUsQ0FBQyw0QkFBYSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtRQUN0RCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDWixJQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNsQixZQUFFLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDakQsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sUUFBUSxHQUFzQixFQUFDLFFBQVEsRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQTtJQUM3RyxJQUFHLE9BQU8sQ0FBQyxJQUFJO1FBQUUsUUFBUSxDQUFDLGFBQWEsR0FBRyw0QkFBYSxDQUFDLG1CQUFtQixDQUFDO0lBQzVFLE1BQU0sYUFBYSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUd0QyxDQUFDIn0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const chai_1 = require("chai");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const wfp_1 = require("./wfp");
11
+ describe('Suit test for wfp command', () => {
12
+ let tmpDir;
13
+ let cwd;
14
+ let pwd;
15
+ beforeEach(() => {
16
+ tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'scanoss-wfp-'));
17
+ cwd = process.cwd();
18
+ pwd = process.env.PWD;
19
+ });
20
+ afterEach(() => {
21
+ process.chdir(cwd);
22
+ process.env.PWD = pwd;
23
+ fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
24
+ });
25
+ // SP-4442: fingerprinting a single file must emit a non-empty path in the
26
+ // file= line. Previously folderRoot was set to the file path itself, so the
27
+ // relative-path strip produced an empty path, which the scan server rejects
28
+ // ("no files found in .wfp content") and the C engine crashes on.
29
+ it('Emits a non-empty file path when fingerprinting a single file', async () => {
30
+ const sampleFile = path_1.default.join(tmpDir, 'sample.js');
31
+ fs_1.default.writeFileSync(sampleFile, 'function hello() { return "world"; }\n');
32
+ const outputFile = path_1.default.join(tmpDir, 'out.wfp');
33
+ await (0, wfp_1.wfpHandler)(sampleFile, { output: outputFile });
34
+ const wfp = fs_1.default.readFileSync(outputFile, 'utf-8');
35
+ const fileLine = wfp.split('\n').find((l) => l.startsWith('file='));
36
+ (0, chai_1.expect)(fileLine, 'expected a file= line in the wfp output').to.not.be.undefined;
37
+ // file=<md5>,<size>,<path>
38
+ const filePath = fileLine.split(',')[2];
39
+ (0, chai_1.expect)(filePath, 'file= path should not be empty for a single file').to.equal('/sample.js');
40
+ });
41
+ // SP-4442: the customer ran `cd <dir> && scanoss-js wfp <name>`. A bare
42
+ // relative filename must still resolve to a correct path, not get mangled by
43
+ // the relative-path strip (folderRoot must be a real prefix, not ".").
44
+ it('Emits a correct file path for a bare relative filename', async () => {
45
+ fs_1.default.writeFileSync(path_1.default.join(tmpDir, 'jquery-1.8.1-min.js'), 'function hello() { return "world"; }\n');
46
+ process.chdir(tmpDir);
47
+ process.env.PWD = tmpDir;
48
+ const outputFile = path_1.default.join(tmpDir, 'out.wfp');
49
+ await (0, wfp_1.wfpHandler)('jquery-1.8.1-min.js', { output: outputFile });
50
+ const wfp = fs_1.default.readFileSync(outputFile, 'utf-8');
51
+ const fileLine = wfp.split('\n').find((l) => l.startsWith('file='));
52
+ const filePath = fileLine.split(',')[2];
53
+ (0, chai_1.expect)(filePath, 'bare relative filename should not be corrupted').to.equal('/jquery-1.8.1-min.js');
54
+ });
55
+ });
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ZwLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2xpL2NvbW1hbmRzL3dmcC5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsK0JBQThCO0FBQzlCLDRDQUFvQjtBQUNwQiw0Q0FBb0I7QUFDcEIsZ0RBQXdCO0FBQ3hCLCtCQUFtQztBQUVuQyxRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBRXpDLElBQUksTUFBYyxDQUFDO0lBQ25CLElBQUksR0FBVyxDQUFDO0lBQ2hCLElBQUksR0FBdUIsQ0FBQztJQUU1QixVQUFVLENBQUMsR0FBRyxFQUFFO1FBQ2QsTUFBTSxHQUFHLFlBQUUsQ0FBQyxXQUFXLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxZQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUNoRSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUN0QixZQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7SUFFSCwwRUFBMEU7SUFDMUUsNEVBQTRFO0lBQzVFLDRFQUE0RTtJQUM1RSxrRUFBa0U7SUFDbEUsRUFBRSxDQUFDLCtEQUErRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzdFLE1BQU0sVUFBVSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELFlBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLHdDQUF3QyxDQUFDLENBQUM7UUFDdkUsTUFBTSxVQUFVLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFaEQsTUFBTSxJQUFBLGdCQUFVLEVBQUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFFckQsTUFBTSxHQUFHLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakQsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNwRSxJQUFBLGFBQU0sRUFBQyxRQUFRLEVBQUUseUNBQXlDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUM7UUFFaEYsMkJBQTJCO1FBQzNCLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsSUFBQSxhQUFNLEVBQUMsUUFBUSxFQUFFLGtEQUFrRCxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUM5RixDQUFDLENBQUMsQ0FBQztJQUVILHdFQUF3RTtJQUN4RSw2RUFBNkU7SUFDN0UsdUVBQXVFO0lBQ3ZFLEVBQUUsQ0FBQyx3REFBd0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0RSxZQUFFLENBQUMsYUFBYSxDQUFDLGNBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLHFCQUFxQixDQUFDLEVBQUUsd0NBQXdDLENBQUMsQ0FBQztRQUNyRyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUN6QixNQUFNLFVBQVUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUVoRCxNQUFNLElBQUEsZ0JBQVUsRUFBQyxxQkFBcUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBRWhFLE1BQU0sR0FBRyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2pELE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDcEUsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxJQUFBLGFBQU0sRUFBQyxRQUFRLEVBQUUsZ0RBQWdELENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDdEcsQ0FBQyxDQUFDLENBQUM7QUFFTCxDQUFDLENBQUMsQ0FBQyJ9