@ngx-cache/fs-storage
Version:
Fs storage for ngx-cache (server platform)
178 lines • 23.1 kB
JavaScript
import { Injectable } from '@angular/core';
import { Storage } from '@ngx-cache/core';
import { EventEmitter } from 'events';
import { mkdirSync, readdirSync, readFileSync, rmdirSync, statSync, unlinkSync, writeFileSync } from 'fs';
import { join, resolve } from 'path';
import { FsStorageLoader } from './fs-storage.loader';
import { FsEvent } from './models/fs-event';
import { FsItemMetadata } from './models/fs-item-metadata';
import * as i0 from "@angular/core";
import * as i1 from "./fs-storage.loader";
export class FsStorageService extends Storage {
constructor(loader) {
super();
this.loader = loader;
this.instances = {};
this.path = resolve(this.loader.path);
this.quota = this.loader.quota;
if (this.instances[this.path]) {
return this.instances[this.path];
}
this.length = 0;
this.keys = [];
this.pid = `pid:${process.pid}`;
this.metadata = new Map();
this.bytesUsed = 0;
try {
let stat = statSync(this.path);
if (!stat.hasOwnProperty('isDirectory')) {
throw new Error(`A file exists at the location ${this.path} when trying to create/open localStorage`);
}
this.length = 0;
this.keys = readdirSync(this.path);
this.bytesUsed = 0;
const decodedKeys = [];
this.keys.forEach((key, index) => {
const decodedKey = decodeURIComponent(key);
decodedKeys.push(decodedKey);
const item = new FsItemMetadata(key, index);
this.metadata[decodedKey] = item;
stat = this.getStats(key);
if (!stat.hasOwnProperty('size')) {
item.size = stat.size;
this.metadata[decodedKey] = item;
this.bytesUsed += stat.size;
}
});
this.keys = decodedKeys;
this.length = this.keys.length;
}
catch (error) {
mkdirSync(this.path);
}
this.instances[this.path] = this;
}
setItem(key, value) {
const hasListeners = EventEmitter.listenerCount(this, 'fs-storage');
const oldValue = hasListeners ? this.getItem(key) : undefined;
let item = this.metadata[key];
const oldLength = item ? item.size : 0;
if (this.bytesUsed - oldLength + Number(value.toString().length) > this.quota) {
throw new Error(`Disk quota (${this.quota / 1024}KB) has been reached!`);
}
const encodedKey = encodeURIComponent(key);
const filename = join(this.path, encodedKey);
writeFileSync(filename, value.toString(), 'utf8');
if (!item) {
item = new FsItemMetadata(encodedKey, this.keys.push(key) - 1);
item.size = value.toString().length;
this.length += 1;
this.metadata[key] = item;
this.bytesUsed += value.toString().length;
}
if (!hasListeners) {
return false;
}
const e = new FsEvent(key, oldValue, value, this.pid);
return this.emit('fs-storage', e);
}
getItem(key) {
const item = this.metadata[key];
if (item) {
const filename = join(this.path, item.key);
try {
return readFileSync(filename, 'utf8');
}
catch (error) {
this.removeItem(key);
}
}
return undefined;
}
removeItem(key) {
const hasListeners = EventEmitter.listenerCount(this, 'fs-storage');
const oldValue = hasListeners ? this.getItem(key) : undefined;
const item = this.metadata[key];
if (item) {
delete this.metadata[key];
this.length -= 1;
this.bytesUsed -= item.size;
this.keys.splice(item.index, 1);
const metadataRef = this.metadata;
metadataRef.forEach((k) => {
const i = this.metadata[k];
if (i.index > item.index) {
i.index -= 1;
}
});
const itemPath = join(this.path, item.key);
try {
this.deletePath(itemPath);
}
catch (error) {
}
if (!hasListeners) {
return false;
}
const e = new FsEvent(key, oldValue, undefined, this.pid);
return this.emit('fs-storage', e);
}
return false;
}
key(index) {
return this.keys[index];
}
clear() {
this.deleteDirectory(this.path);
this.length = 0;
this.keys = [];
this.metadata = new Map();
this.bytesUsed = 0;
const hasListeners = EventEmitter.listenerCount(this, 'fs-storage');
if (!hasListeners) {
return false;
}
const e = new FsEvent(undefined, undefined, undefined, this.pid);
return this.emit('fs-storage', e);
}
getStats(key) {
const filename = join(this.path, encodeURIComponent(key));
try {
return statSync(filename);
}
catch (error) {
return undefined;
}
}
deleteDirectory(dirPath) {
const contents = readdirSync(dirPath);
contents.forEach((path) => {
const joined = join(dirPath, path);
this.deletePath(joined);
});
}
deletePath(path) {
const isDirectory = statSync(path).isDirectory();
if (isDirectory) {
this.deleteDirectory(path);
rmdirSync(path);
}
else {
unlinkSync(path);
}
}
deleteInstance() {
delete this.instances[this.path];
this.deletePath(this.path);
this.length = 0;
this.keys = [];
this.metadata = new Map();
this.bytesUsed = 0;
}
}
FsStorageService.ɵfac = function FsStorageService_Factory(t) { return new (t || FsStorageService)(i0.ɵɵinject(i1.FsStorageLoader)); };
FsStorageService.ɵprov = i0.ɵɵdefineInjectable({ token: FsStorageService, factory: FsStorageService.ɵfac });
(function () { i0.ɵsetClassMetadata(FsStorageService, [{
type: Injectable
}], function () { return [{ type: i1.FsStorageLoader }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnMtc3RvcmFnZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vQG5neC1jYWNoZS9mcy1zdG9yYWdlLyIsInNvdXJjZXMiOlsiZnMtc3RvcmFnZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDdEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLElBQUksQ0FBQztBQUMxRyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVyQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBRzNELE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxPQUFPO0lBYTNDLFlBQXFCLE1BQXVCO1FBQzFDLEtBQUssRUFBRSxDQUFDO1FBRFcsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFUM0IsY0FBUyxHQUFHLEVBQUUsQ0FBQztRQVk5QixJQUFJLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFFL0IsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3QixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFD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SSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTNCLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBMEIsQ0FBQztRQUNsRCxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNyQixDQUFDOztnRkE3TlUsZ0JBQWdCO3dEQUFoQixnQkFBZ0IsV0FBaEIsZ0JBQWdCO29DQUFoQixnQkFBZ0I7Y0FENUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN0b3JhZ2UgfSBmcm9tICdAbmd4LWNhY2hlL2NvcmUnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCB7IG1rZGlyU3luYywgcmVhZGRpclN5bmMsIHJlYWRGaWxlU3luYywgcm1kaXJTeW5jLCBzdGF0U3luYywgdW5saW5rU3luYywgd3JpdGVGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCB7IGpvaW4sIHJlc29sdmUgfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHsgRnNTdG9yYWdlTG9hZGVyIH0gZnJvbSAnLi9mcy1zdG9yYWdlLmxvYWRlcic7XG5pbXBvcnQgeyBGc0V2ZW50IH0gZnJvbSAnLi9tb2RlbHMvZnMtZXZlbnQnO1xuaW1wb3J0IHsgRnNJdGVtTWV0YWRhdGEgfSBmcm9tICcuL21vZGVscy9mcy1pdGVtLW1ldGFkYXRhJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEZzU3RvcmFnZVNlcnZpY2UgZXh0ZW5kcyBTdG9yYWdlIHtcbiAgbGVuZ3RoOiBudW1iZXI7XG4gIGtleXM6IEFycmF5PHN0cmluZz47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBpbnN0YW5jZXMgPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBxdW90YTogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHBpZDogc3RyaW5nO1xuXG4gIHByaXZhdGUgbWV0YWRhdGE6IE1hcDxzdHJpbmcsIEZzSXRlbU1ldGFkYXRhPjtcbiAgcHJpdmF0ZSBieXRlc1VzZWQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihyZWFkb25seSBsb2FkZXI6IEZzU3RvcmFnZUxvYWRlcikge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnBhdGggPSByZXNvbHZlKHRoaXMubG9hZGVyLnBhdGgpO1xuICAgIHRoaXMucXVvdGEgPSB0aGlzLmxvYWRlci5xdW90YTtcblxuICAgIGlmICh0aGlzLmluc3RhbmNlc1t0aGlzLnBhdGhdKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZXNbdGhpcy5wYXRoXTtcbiAgICB9XG5cbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5rZXlzID0gW107XG4gICAgdGhpcy5waWQgPSBgcGlkOiR7cHJvY2Vzcy5waWR9YDtcbiAgICB0aGlzLm1ldGFkYXRhID0gbmV3IE1hcDxzdHJpbmcsIEZzSXRlbU1ldGFkYXRhPigpO1xuICAgIHRoaXMuYnl0ZXNVc2VkID0gMDtcblxuICAgIHRyeSB7XG4gICAgICBsZXQgc3RhdCA9IHN0YXRTeW5jKHRoaXMucGF0aCk7XG5cbiAgICAgIGlmICghc3RhdC5oYXNPd25Qcm9wZXJ0eSgnaXNEaXJlY3RvcnknKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEEgZmlsZSBleGlzdHMgYXQgdGhlIGxvY2F0aW9uICR7dGhpcy5wYXRofSB3aGVuIHRyeWluZyB0byBjcmVhdGUvb3BlbiBsb2NhbFN0b3JhZ2VgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5sZW5ndGggPSAwO1xuICAgICAgdGhpcy5rZXlzID0gcmVhZGRpclN5bmModGhpcy5wYXRoKTtcbiAgICAgIHRoaXMuYnl0ZXNVc2VkID0gMDtcblxuICAgICAgY29uc3QgZGVjb2RlZEtleXM6IEFycmF5PHN0cmluZz4gPSBbXTtcblxuICAgICAgdGhpcy5rZXlzLmZvckVhY2goKGtleTogc3RyaW5nLCBpbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlY29kZWRLZXkgPSBkZWNvZGVVUklDb21wb25lbnQoa2V5KTtcbiAgICAgICAgZGVjb2RlZEtleXMucHVzaChkZWNvZGVkS2V5KTtcblxuICAgICAgICBjb25zdCBpdGVtID0gbmV3IEZzSXRlbU1ldGFkYXRhKGtleSwgaW5kZXgpO1xuICAgICAgICB0aGlzLm1ldGFkYXRhW2RlY29kZWRLZXldID0gaXRlbTtcblxuICAgICAgICBzdGF0ID0gdGhpcy5nZXRTdGF0cyhrZXkpO1xuXG4gICAgICAgIGlmICghc3RhdC5oYXNPd25Qcm9wZXJ0eSgnc2l6ZScpKSB7XG4gICAgICAgICAgaXRlbS5zaXplID0gc3RhdC5zaXplO1xuICAgICAgICAgIHRoaXMubWV0YWRhdGFbZGVjb2RlZEtleV0gPSBpdGVtO1xuICAgICAgICAgIHRoaXMuYnl0ZXNVc2VkICs9IHN0YXQuc2l6ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHRoaXMua2V5cyA9IGRlY29kZWRLZXlzO1xuICAgICAgdGhpcy5sZW5ndGggPSB0aGlzLmtleXMubGVuZ3RoO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBta2RpclN5bmModGhpcy5wYXRoKTtcbiAgICB9XG5cbiAgICB0aGlzLmluc3RhbmNlc1t0aGlzLnBhdGhdID0gdGhpcztcbiAgfVxuXG4gIHNldEl0ZW0oa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBib29sZWFuIHtcbiAgICBjb25zdCBoYXNMaXN0ZW5lcnMgPSBFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCh0aGlzLCAnZnMtc3RvcmFnZScpO1xuICAgIGNvbnN0IG9sZFZhbHVlID0gaGFzTGlzdGVuZXJzID8gdGhpcy5nZXRJdGVtKGtleSkgOiB1bmRlZmluZWQ7XG5cbiAgICBsZXQgaXRlbSA9IHRoaXMubWV0YWRhdGFba2V5XTtcbiAgICBjb25zdCBvbGRMZW5ndGggPSBpdGVtID8gaXRlbS5zaXplIDogMDtcblxuICAgIGlmICh0aGlzLmJ5dGVzVXNlZCAtIG9sZExlbmd0aCArIE51bWJlcih2YWx1ZS50b1N0cmluZygpLmxlbmd0aCkgPiB0aGlzLnF1b3RhKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc2sgcXVvdGEgKCR7dGhpcy5xdW90YSAvIDEwMjR9S0IpIGhhcyBiZWVuIHJlYWNoZWQhYCk7XG4gICAgfVxuXG4gICAgY29uc3QgZW5jb2RlZEtleSA9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpO1xuICAgIGNvbnN0IGZpbGVuYW1lID0gam9pbih0aGlzLnBhdGgsIGVuY29kZWRLZXkpO1xuXG4gICAgd3JpdGVGaWxlU3luYyhmaWxlbmFtZSwgdmFsdWUudG9TdHJpbmcoKSwgJ3V0ZjgnKTtcblxuICAgIGlmICghaXRlbSkge1xuICAgICAgaXRlbSA9IG5ldyBGc0l0ZW1NZXRhZGF0YShlbmNvZGVkS2V5LCB0aGlzLmtleXMucHVzaChrZXkpIC0gMSk7XG4gICAgICBpdGVtLnNpemUgPSB2YWx1ZS50b1N0cmluZygpLmxlbmd0aDtcblxuICAgICAgdGhpcy5sZW5ndGggKz0gMTtcbiAgICAgIHRoaXMubWV0YWRhdGFba2V5XSA9IGl0ZW07XG4gICAgICB0aGlzLmJ5dGVzVXNlZCArPSB2YWx1ZS50b1N0cmluZygpLmxlbmd0aDtcbiAgICB9XG5cbiAgICBpZiAoIWhhc0xpc3RlbmVycykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGUgPSBuZXcgRnNFdmVudChrZXksIG9sZFZhbHVlLCB2YWx1ZSwgdGhpcy5waWQpO1xuXG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZnMtc3RvcmFnZScsIGUpO1xuICB9XG5cbiAgZ2V0SXRlbShrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgaXRlbSA9IHRoaXMubWV0YWRhdGFba2V5XTtcblxuICAgIGlmIChpdGVtKSB7XG4gICAgICBjb25zdCBmaWxlbmFtZSA9IGpvaW4odGhpcy5wYXRoLCBpdGVtLmtleSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiByZWFkRmlsZVN5bmMoZmlsZW5hbWUsICd1dGY4Jyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oa2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmVtb3ZlSXRlbShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGhhc0xpc3RlbmVycyA9IEV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50KHRoaXMsICdmcy1zdG9yYWdlJyk7XG4gICAgY29uc3Qgb2xkVmFsdWUgPSBoYXNMaXN0ZW5lcnMgPyB0aGlzLmdldEl0ZW0oa2V5KSA6IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLm1ldGFkYXRhW2tleV07XG5cbiAgICBpZiAoaXRlbSkge1xuICAgICAgZGVsZXRlIHRoaXMubWV0YWRhdGFba2V5XTtcbiAgICAgIHRoaXMubGVuZ3RoIC09IDE7XG4gICAgICB0aGlzLmJ5dGVzVXNlZCAtPSBpdGVtLnNpemU7XG4gICAgICB0aGlzLmtleXMuc3BsaWNlKGl0ZW0uaW5kZXgsIDEpO1xuXG4gICAgICBjb25zdCBtZXRhZGF0YVJlZiA9IHRoaXMubWV0YWRhdGE7XG5cbiAgICAgIG1ldGFkYXRhUmVmLmZvckVhY2goKGs6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBpID0gdGhpcy5tZXRhZGF0YVtrXTtcblxuICAgICAgICBpZiAoaS5pbmRleCA+IGl0ZW0uaW5kZXgpIHtcbiAgICAgICAgICBpLmluZGV4IC09IDE7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBpdGVtUGF0aCA9IGpvaW4odGhpcy5wYXRoLCBpdGVtLmtleSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuZGVsZXRlUGF0aChpdGVtUGF0aCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBOT1RFOiBzZWVtcyBsaWtlIHBhdGggY2FuJ3QgYmUgZGVsZXRlZFxuICAgICAgfVxuXG4gICAgICBpZiAoIWhhc0xpc3RlbmVycykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGUgPSBuZXcgRnNFdmVudChrZXksIG9sZFZhbHVlLCB1bmRlZmluZWQsIHRoaXMucGlkKTtcblxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZnMtc3RvcmFnZScsIGUpO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGtleShpbmRleDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5rZXlzW2luZGV4XTtcbiAgfVxuXG4gIGNsZWFyKCk6IGJvb2xlYW4ge1xuICAgIHRoaXMuZGVsZXRlRGlyZWN0b3J5KHRoaXMucGF0aCk7XG5cbiAgICB0aGlzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5rZXlzID0gW107XG4gICAgdGhpcy5tZXRhZGF0YSA9IG5ldyBNYXA8c3RyaW5nLCBGc0l0ZW1NZXRhZGF0YT4oKTtcbiAgICB0aGlzLmJ5dGVzVXNlZCA9IDA7XG5cbiAgICBjb25zdCBoYXNMaXN0ZW5lcnMgPSBFdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCh0aGlzLCAnZnMtc3RvcmFnZScpO1xuXG4gICAgaWYgKCFoYXNMaXN0ZW5lcnMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBlID0gbmV3IEZzRXZlbnQodW5kZWZpbmVkLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGhpcy5waWQpO1xuXG4gICAgcmV0dXJuIHRoaXMuZW1pdCgnZnMtc3RvcmFnZScsIGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTdGF0cyhrZXk6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBqb2luKHRoaXMucGF0aCwgZW5jb2RlVVJJQ29tcG9uZW50KGtleSkpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBzdGF0U3luYyhmaWxlbmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVEaXJlY3RvcnkoZGlyUGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY29udGVudHMgPSByZWFkZGlyU3luYyhkaXJQYXRoKTtcblxuICAgIGNvbnRlbnRzLmZvckVhY2goKHBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3Qgam9pbmVkID0gam9pbihkaXJQYXRoLCBwYXRoKTtcbiAgICAgIHRoaXMuZGVsZXRlUGF0aChqb2luZWQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVQYXRoKHBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGlzRGlyZWN0b3J5ID0gc3RhdFN5bmMocGF0aCkuaXNEaXJlY3RvcnkoKTtcblxuICAgIGlmIChpc0RpcmVjdG9yeSkge1xuICAgICAgdGhpcy5kZWxldGVEaXJlY3RvcnkocGF0aCk7XG5cbiAgICAgIHJtZGlyU3luYyhwYXRoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdW5saW5rU3luYyhwYXRoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUluc3RhbmNlKCk6IHZvaWQge1xuICAgIGRlbGV0ZSB0aGlzLmluc3RhbmNlc1t0aGlzLnBhdGhdO1xuICAgIHRoaXMuZGVsZXRlUGF0aCh0aGlzLnBhdGgpO1xuXG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIHRoaXMua2V5cyA9IFtdO1xuICAgIHRoaXMubWV0YWRhdGEgPSBuZXcgTWFwPHN0cmluZywgRnNJdGVtTWV0YWRhdGE+KCk7XG4gICAgdGhpcy5ieXRlc1VzZWQgPSAwO1xuICB9XG59XG4iXX0=