browserfs
Version:
A filesystem in your browser!
207 lines • 31.6 kB
JavaScript
"use strict";
var node_fs_stats_1 = require('../core/node_fs_stats');
var path = require('path');
var FileIndex = (function () {
function FileIndex() {
this._index = {};
this.addPath('/', new DirInode());
}
FileIndex.prototype._split_path = function (p) {
var dirpath = path.dirname(p);
var itemname = p.substr(dirpath.length + (dirpath === "/" ? 0 : 1));
return [dirpath, itemname];
};
FileIndex.prototype.fileIterator = function (cb) {
for (var path in this._index) {
var dir = this._index[path];
var files = dir.getListing();
for (var i = 0; i < files.length; i++) {
var item = dir.getItem(files[i]);
if (isFileInode(item)) {
cb(item.getData());
}
}
}
};
FileIndex.prototype.addPath = function (path, inode) {
if (inode == null) {
throw new Error('Inode must be specified');
}
if (path[0] !== '/') {
throw new Error('Path must be absolute, got: ' + path);
}
if (this._index.hasOwnProperty(path)) {
return this._index[path] === inode;
}
var splitPath = this._split_path(path);
var dirpath = splitPath[0];
var itemname = splitPath[1];
var parent = this._index[dirpath];
if (parent === undefined && path !== '/') {
parent = new DirInode();
if (!this.addPath(dirpath, parent)) {
return false;
}
}
if (path !== '/') {
if (!parent.addItem(itemname, inode)) {
return false;
}
}
if (isDirInode(inode)) {
this._index[path] = inode;
}
return true;
};
FileIndex.prototype.addPathFast = function (path, inode) {
var itemNameMark = path.lastIndexOf('/');
var parentPath = itemNameMark == 0 ? "/" : path.substring(0, itemNameMark);
var itemName = path.substring(itemNameMark + 1);
var parent = this._index[parentPath];
if (parent === undefined) {
parent = new DirInode();
this.addPathFast(parentPath, parent);
}
if (!parent.addItem(itemName, inode)) {
return false;
}
if (inode.isDir()) {
this._index[path] = inode;
}
return true;
};
FileIndex.prototype.removePath = function (path) {
var splitPath = this._split_path(path);
var dirpath = splitPath[0];
var itemname = splitPath[1];
var parent = this._index[dirpath];
if (parent === undefined) {
return null;
}
var inode = parent.remItem(itemname);
if (inode === null) {
return null;
}
if (isDirInode(inode)) {
var children = inode.getListing();
for (var i = 0; i < children.length; i++) {
this.removePath(path + '/' + children[i]);
}
if (path !== '/') {
delete this._index[path];
}
}
return inode;
};
FileIndex.prototype.ls = function (path) {
var item = this._index[path];
if (item === undefined) {
return null;
}
return item.getListing();
};
FileIndex.prototype.getInode = function (path) {
var splitPath = this._split_path(path);
var dirpath = splitPath[0];
var itemname = splitPath[1];
var parent = this._index[dirpath];
if (parent === undefined) {
return null;
}
if (dirpath === path) {
return parent;
}
return parent.getItem(itemname);
};
FileIndex.fromListing = function (listing) {
var idx = new FileIndex();
var rootInode = new DirInode();
idx._index['/'] = rootInode;
var queue = [['', listing, rootInode]];
while (queue.length > 0) {
var inode;
var next = queue.pop();
var pwd = next[0];
var tree = next[1];
var parent = next[2];
for (var node in tree) {
var children = tree[node];
var name = "" + pwd + "/" + node;
if (children != null) {
idx._index[name] = inode = new DirInode();
queue.push([name, children, inode]);
}
else {
inode = new FileInode(new node_fs_stats_1["default"](node_fs_stats_1.FileType.FILE, -1, 0x16D));
}
if (parent != null) {
parent._ls[node] = inode;
}
}
}
return idx;
};
return FileIndex;
}());
exports.FileIndex = FileIndex;
var FileInode = (function () {
function FileInode(data) {
this.data = data;
}
FileInode.prototype.isFile = function () { return true; };
FileInode.prototype.isDir = function () { return false; };
FileInode.prototype.getData = function () { return this.data; };
FileInode.prototype.setData = function (data) { this.data = data; };
return FileInode;
}());
exports.FileInode = FileInode;
var DirInode = (function () {
function DirInode(data) {
if (data === void 0) { data = null; }
this.data = data;
this._ls = {};
}
DirInode.prototype.isFile = function () {
return false;
};
DirInode.prototype.isDir = function () {
return true;
};
DirInode.prototype.getData = function () { return this.data; };
DirInode.prototype.getStats = function () {
return new node_fs_stats_1["default"](node_fs_stats_1.FileType.DIRECTORY, 4096, 0x16D);
};
DirInode.prototype.getListing = function () {
return Object.keys(this._ls);
};
DirInode.prototype.getItem = function (p) {
var _ref;
return (_ref = this._ls[p]) != null ? _ref : null;
};
DirInode.prototype.addItem = function (p, inode) {
if (p in this._ls) {
return false;
}
this._ls[p] = inode;
return true;
};
DirInode.prototype.remItem = function (p) {
var item = this._ls[p];
if (item === undefined) {
return null;
}
delete this._ls[p];
return item;
};
return DirInode;
}());
exports.DirInode = DirInode;
function isFileInode(inode) {
return inode && inode.isFile();
}
exports.isFileInode = isFileInode;
function isDirInode(inode) {
return inode && inode.isDir();
}
exports.isDirInode = isDirInode;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZV9pbmRleC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9nZW5lcmljL2ZpbGVfaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDhCQUF5Qyx1QkFBdUIsQ0FBQyxDQUFBO0FBQ2pFLElBQU8sSUFBSSxXQUFXLE1BQU0sQ0FBQyxDQUFDO0FBUzlCO0lBT0U7UUFHRSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUVqQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUtPLCtCQUFXLEdBQW5CLFVBQW9CLENBQVM7UUFDM0IsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLFFBQVEsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxPQUFPLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBS00sZ0NBQVksR0FBbkIsVUFBdUIsRUFBcUI7UUFDMUMsR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDN0IsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QixJQUFJLEtBQUssR0FBRyxHQUFHLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDN0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3RDLElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMs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Q0FBQztRQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNILGVBQUM7QUFBRCxDQUFDLEFBckVELElBcUVDO0FBckVZLGdCQUFRLFdBcUVwQixDQUFBO0FBRUQscUJBQStCLEtBQVk7SUFDekMsTUFBTSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7QUFDakMsQ0FBQztBQUZlLG1CQUFXLGNBRTFCLENBQUE7QUFFRCxvQkFBOEIsS0FBWTtJQUN4QyxNQUFNLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBRmUsa0JBQVUsYUFFekIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7ZGVmYXVsdCBhcyBTdGF0cywgRmlsZVR5cGV9IGZyb20gJy4uL2NvcmUvbm9kZV9mc19zdGF0cyc7XG5pbXBvcnQgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcblxuLyoqXG4gKiBBIHNpbXBsZSBjbGFzcyBmb3Igc3RvcmluZyBhIGZpbGVzeXN0ZW0gaW5kZXguIEFzc3VtZXMgdGhhdCBhbGwgcGF0aHMgcGFzc2VkXG4gKiB0byBpdCBhcmUgKmFic29sdXRlKiBwYXRocy5cbiAqXG4gKiBDYW4gYmUgdXNlZCBhcyBhIHBhcnRpYWwgb3IgYSBmdWxsIGluZGV4LCBhbHRob3VnaCBjYXJlIG11c3QgYmUgdGFrZW4gaWYgdXNlZFxuICogZm9yIHRoZSBmb3JtZXIgcHVycG9zZSwgZXNwZWNpYWxseSB3aGVuIGRpcmVjdG9yaWVzIGFyZSBjb25jZXJuZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBGaWxlSW5kZXg8VD4ge1xuICAvLyBNYXBzIGRpcmVjdG9yeSBwYXRocyB0byBkaXJlY3RvcnkgaW5vZGVzLCB3aGljaCBjb250YWluIGZpbGVzLlxuICBwcml2YXRlIF9pbmRleDoge1twYXRoOiBzdHJpbmddOiBEaXJJbm9kZTxUPn1cblxuICAvKipcbiAgICogQ29uc3RydWN0cyBhIG5ldyBGaWxlSW5kZXguXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBfaW5kZXggaXMgYSBzaW5nbGUtbGV2ZWwga2V5LHZhbHVlIHN0b3JlIHRoYXQgbWFwcyAqZGlyZWN0b3J5KiBwYXRocyB0b1xuICAgIC8vIERpcklub2Rlcy4gRmlsZSBpbmZvcm1hdGlvbiBpcyBvbmx5IGNvbnRhaW5lZCBpbiBEaXJJbm9kZXMgdGhlbXNlbHZlcy5cbiAgICB0aGlzLl9pbmRleCA9IHt9O1xuICAgIC8vIENyZWF0ZSB0aGUgcm9vdCBkaXJlY3RvcnkuXG4gICAgdGhpcy5hZGRQYXRoKCcvJywgbmV3IERpcklub2RlKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0IGludG8gYSAoZGlyZWN0b3J5IHBhdGgsIGl0ZW0gbmFtZSkgcGFpclxuICAgKi9cbiAgcHJpdmF0ZSBfc3BsaXRfcGF0aChwOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgdmFyIGRpcnBhdGggPSBwYXRoLmRpcm5hbWUocCk7XG4gICAgdmFyIGl0ZW1uYW1lID0gcC5zdWJzdHIoZGlycGF0aC5sZW5ndGggKyAoZGlycGF0aCA9PT0gXCIvXCIgPyAwIDogMSkpO1xuICAgIHJldHVybiBbZGlycGF0aCwgaXRlbW5hbWVdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdGhlIGdpdmVuIGZ1bmN0aW9uIG92ZXIgYWxsIGZpbGVzIGluIHRoZSBpbmRleC5cbiAgICovXG4gIHB1YmxpYyBmaWxlSXRlcmF0b3I8VD4oY2I6IChmaWxlOiBUKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgZm9yICh2YXIgcGF0aCBpbiB0aGlzLl9pbmRleCkge1xuICAgICAgdmFyIGRpciA9IHRoaXMuX2luZGV4W3BhdGhdO1xuICAgICAgdmFyIGZpbGVzID0gZGlyLmdldExpc3RpbmcoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGl0ZW0gPSBkaXIuZ2V0SXRlbShmaWxlc1tpXSk7XG4gICAgICAgIGlmIChpc0ZpbGVJbm9kZTxUPihpdGVtKSkge1xuICAgICAgICAgIGNiKGl0ZW0uZ2V0RGF0YSgpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIHRoZSBnaXZlbiBhYnNvbHV0ZSBwYXRoIHRvIHRoZSBpbmRleCBpZiBpdCBpcyBub3QgYWxyZWFkeSBpbiB0aGUgaW5kZXguXG4gICAqIENyZWF0ZXMgYW55IG5lZWRlZCBwYXJlbnQgZGlyZWN0b3JpZXMuXG4gICAqIEBwYXJhbSBbU3RyaW5nXSBwYXRoIFRoZSBwYXRoIHRvIGFkZCB0byB0aGUgaW5kZXguXG4gICAqIEBwYXJhbSBbQnJvd3NlckZTLkZpbGVJbm9kZSB8IEJyb3dzZXJGUy5EaXJJbm9kZV0gaW5vZGUgVGhlIGlub2RlIGZvciB0aGVcbiAgICogICBwYXRoIHRvIGFkZC5cbiAgICogQHJldHVybiBbQm9vbGVhbl0gJ1RydWUnIGlmIGl0IHdhcyBhZGRlZCBvciBhbHJlYWR5IGV4aXN0cywgJ2ZhbHNlJyBpZiB0aGVyZVxuICAgKiAgIHdhcyBhbiBpc3N1ZSBhZGRpbmcgaXQgKGUuZy4gaXRlbSBpbiBwYXRoIGlzIGEgZmlsZSwgaXRlbSBleGlzdHMgYnV0IGlzXG4gICAqICAgZGlmZmVyZW50KS5cbiAgICogQHRvZG8gSWYgYWRkaW5nIGZhaWxzIGFuZCBpbXBsaWNpdGx5IGNyZWF0ZXMgZGlyZWN0b3JpZXMsIHdlIGRvIG5vdCBjbGVhbiB1cFxuICAgKiAgIHRoZSBuZXcgZW1wdHkgZGlyZWN0b3JpZXMuXG4gICAqL1xuICBwdWJsaWMgYWRkUGF0aChwYXRoOiBzdHJpbmcsIGlub2RlOiBJbm9kZSk6IGJvb2xlYW4ge1xuICAgIGlmIChpbm9kZSA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lub2RlIG11c3QgYmUgc3BlY2lmaWVkJyk7XG4gICAgfVxuICAgIGlmIChwYXRoWzBdICE9PSAnLycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGF0aCBtdXN0IGJlIGFic29sdXRlLCBnb3Q6ICcgKyBwYXRoKTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBpdCBhbHJlYWR5IGV4aXN0cy5cbiAgICBpZiAodGhpcy5faW5kZXguaGFzT3duUHJvcGVydHkocGF0aCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pbmRleFtwYXRoXSA9PT0gaW5vZGU7XG4gICAgfVxuXG4gICAgdmFyIHNwbGl0UGF0aCA9IHRoaXMuX3NwbGl0X3BhdGgocGF0aCk7XG4gICAgdmFyIGRpcnBhdGggPSBzcGxpdFBhdGhbMF07XG4gICAgdmFyIGl0ZW1uYW1lID0gc3BsaXRQYXRoWzFdO1xuICAgIC8vIFRyeSB0byBhZGQgdG8gaXRzIHBhcmVudCBkaXJlY3RvcnkgZmlyc3QuXG4gICAgdmFyIHBhcmVudCA9IHRoaXMuX2luZGV4W2RpcnBhdGhdO1xuICAgIGlmIChwYXJlbnQgPT09IHVuZGVmaW5lZCAmJiBwYXRoICE9PSAnLycpIHtcbiAgICAgIC8vIENyZWF0ZSBwYXJlbnQuXG4gICAgICBwYXJlbnQgPSBuZXcgRGlySW5vZGU8VD4oKTtcbiAgICAgIGlmICghdGhpcy5hZGRQYXRoKGRpcnBhdGgsIHBhcmVudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBZGQgbXlzZWxmIHRvIG15IHBhcmVudC5cbiAgICBpZiAocGF0aCAhPT0gJy8nKSB7XG4gICAgICBpZiAoIXBhcmVudC5hZGRJdGVtKGl0ZW1uYW1lLCBpbm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiBJJ20gYSBkaXJlY3RvcnksIGFkZCBteXNlbGYgdG8gdGhlIGluZGV4LlxuICAgIGlmIChpc0Rpcklub2RlPFQ+KGlub2RlKSkge1xuICAgICAgdGhpcy5faW5kZXhbcGF0aF0gPSBpbm9kZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyB0aGUgZ2l2ZW4gYWJzb2x1dGUgcGF0aCB0byB0aGUgaW5kZXggaWYgaXQgaXMgbm90IGFscmVhZHkgaW4gdGhlIGluZGV4LlxuICAgKiBUaGUgcGF0aCBpcyBhZGRlZCB3aXRob3V0IHNwZWNpYWwgdHJlYXRtZW50IChubyBqb2luaW5nIG9mIGFkamFjZW50IHNlcGFyYXRvcnMsIGV0YykuXG4gICAqIENyZWF0ZXMgYW55IG5lZWRlZCBwYXJlbnQgZGlyZWN0b3JpZXMuXG4gICAqIEBwYXJhbSBbU3RyaW5nXSBwYXRoIFRoZSBwYXRoIHRvIGFkZCB0byB0aGUgaW5kZXguXG4gICAqIEBwYXJhbSBbQnJvd3NlckZTLkZpbGVJbm9kZSB8IEJyb3dzZXJGUy5EaXJJbm9kZV0gaW5vZGUgVGhlIGlub2RlIGZvciB0aGVcbiAgICogICBwYXRoIHRvIGFkZC5cbiAgICogQHJldHVybiBbQm9vbGVhbl0gJ1RydWUnIGlmIGl0IHdhcyBhZGRlZCBvciBhbHJlYWR5IGV4aXN0cywgJ2ZhbHNlJyBpZiB0aGVyZVxuICAgKiAgIHdhcyBhbiBpc3N1ZSBhZGRpbmcgaXQgKGUuZy4gaXRlbSBpbiBwYXRoIGlzIGEgZmlsZSwgaXRlbSBleGlzdHMgYnV0IGlzXG4gICAqICAgZGlmZmVyZW50KS5cbiAgICogQHRvZG8gSWYgYWRkaW5nIGZhaWxzIGFuZCBpbXBsaWNpdGx5IGNyZWF0ZXMgZGlyZWN0b3JpZXMsIHdlIGRvIG5vdCBjbGVhbiB1cFxuICAgKiAgIHRoZSBuZXcgZW1wdHkgZGlyZWN0b3JpZXMuXG4gICAqL1xuICBwdWJsaWMgYWRkUGF0aEZhc3QocGF0aDogc3RyaW5nLCBpbm9kZTogSW5vZGUpOiBib29sZWFuIHtcblxuICAgIGNvbnN0IGl0ZW1OYW1lTWFyayA9IHBhdGgubGFzdEluZGV4T2YoJy8nKTtcbiAgICBjb25zdCBwYXJlbnRQYXRoID0gaXRlbU5hbWVNYXJrID09IDAgPyBcIi9cIiA6IHBhdGguc3Vic3RyaW5nKDAsIGl0ZW1OYW1lTWFyayk7XG4gICAgY29uc3QgaXRlbU5hbWUgPSBwYXRoLnN1YnN0cmluZyhpdGVtTmFtZU1hcmsrMSk7XG5cbiAgICAvLyBUcnkgdG8gYWRkIHRvIGl0cyBwYXJlbnQgZGlyZWN0b3J5IGZpcnN0LlxuICAgIGxldCBwYXJlbnQgPSB0aGlzLl9pbmRleFtwYXJlbnRQYXRoXTtcbiAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIENyZWF0ZSBwYXJlbnQuXG4gICAgICBwYXJlbnQgPSBuZXcgRGlySW5vZGU8VD4oKTtcbiAgICAgIHRoaXMuYWRkUGF0aEZhc3QocGFyZW50UGF0aCwgcGFyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoIXBhcmVudC5hZGRJdGVtKGl0ZW1OYW1lLCBpbm9kZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBJZiBhZGRpbmcgYSBkaXJlY3RvcnksIGFkZCB0byB0aGUgaW5kZXggYXMgd2VsbC5cbiAgICBpZiAoaW5vZGUuaXNEaXIoKSkge1xuICAgICAgdGhpcy5faW5kZXhbcGF0aF0gPSA8RGlySW5vZGU8VD4+IGlub2RlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBnaXZlbiBwYXRoLiBDYW4gYmUgYSBmaWxlIG9yIGEgZGlyZWN0b3J5LlxuICAgKiBAcmV0dXJuIFtCcm93c2VyRlMuRmlsZUlub2RlIHwgQnJvd3NlckZTLkRpcklub2RlIHwgbnVsbF0gVGhlIHJlbW92ZWQgaXRlbSxcbiAgICogICBvciBudWxsIGlmIGl0IGRpZCBub3QgZXhpc3QuXG4gICAqL1xuICBwdWJsaWMgcmVtb3ZlUGF0aChwYXRoOiBzdHJpbmcpOiBJbm9kZSB7XG4gICAgdmFyIHNwbGl0UGF0aCA9IHRoaXMuX3NwbGl0X3BhdGgocGF0aCk7XG4gICAgdmFyIGRpcnBhdGggPSBzcGxpdFBhdGhbMF07XG4gICAgdmFyIGl0ZW1uYW1lID0gc3BsaXRQYXRoWzFdO1xuXG4gICAgLy8gVHJ5IHRvIHJlbW92ZSBpdCBmcm9tIGl0cyBwYXJlbnQgZGlyZWN0b3J5IGZpcnN0LlxuICAgIHZhciBwYXJlbnQgPSB0aGlzLl9pbmRleFtkaXJwYXRoXTtcbiAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyBSZW1vdmUgbXlzZWxmIGZyb20gbXkgcGFyZW50LlxuICAgIHZhciBpbm9kZSA9IHBhcmVudC5yZW1JdGVtKGl0ZW1uYW1lKTtcbiAgICBpZiAoaW5vZGUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyBJZiBJJ20gYSBkaXJlY3RvcnksIHJlbW92ZSBteXNlbGYgZnJvbSB0aGUgaW5kZXgsIGFuZCByZW1vdmUgbXkgY2hpbGRyZW4uXG4gICAgaWYgKGlzRGlySW5vZGUoaW5vZGUpKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBpbm9kZS5nZXRMaXN0aW5nKCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlUGF0aChwYXRoICsgJy8nICsgY2hpbGRyZW5baV0pO1xuICAgICAgfVxuXG4gICAgICAvLyBSZW1vdmUgdGhlIGRpcmVjdG9yeSBmcm9tIHRoZSBpbmRleCwgdW5sZXNzIGl0J3MgdGhlIHJvb3QuXG4gICAgICBpZiAocGF0aCAhPT0gJy8nKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9pbmRleFtwYXRoXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlub2RlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgZGlyZWN0b3J5IGxpc3Rpbmcgb2YgdGhlIGdpdmVuIHBhdGguXG4gICAqIEByZXR1cm4gW1N0cmluZ1tdXSBBbiBhcnJheSBvZiBmaWxlcyBpbiB0aGUgZ2l2ZW4gcGF0aCwgb3IgJ251bGwnIGlmIGl0IGRvZXNcbiAgICogICBub3QgZXhpc3QuXG4gICAqL1xuICBwdWJsaWMgbHMocGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHZhciBpdGVtID0gdGhpcy5faW5kZXhbcGF0aF07XG4gICAgaWYgKGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBpdGVtLmdldExpc3RpbmcoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBpbm9kZSBvZiB0aGUgZ2l2ZW4gaXRlbS5cbiAgICogQHBhcmFtIFtTdHJpbmddIHBhdGhcbiAgICogQHJldHVybiBbQnJvd3NlckZTLkZpbGVJbm9kZSB8IEJyb3dzZXJGUy5EaXJJbm9kZSB8IG51bGxdIFJldHVybnMgbnVsbCBpZlxuICAgKiAgIHRoZSBpdGVtIGRvZXMgbm90IGV4aXN0LlxuICAgKi9cbiAgcHVibGljIGdldElub2RlKHBhdGg6IHN0cmluZyk6IElub2RlIHtcbiAgICB2YXIgc3BsaXRQYXRoID0gdGhpcy5fc3BsaXRfcGF0aChwYXRoKTtcbiAgICB2YXIgZGlycGF0aCA9IHNwbGl0UGF0aFswXTtcbiAgICB2YXIgaXRlbW5hbWUgPSBzcGxpdFBhdGhbMV07XG4gICAgLy8gUmV0cmlldmUgZnJvbSBpdHMgcGFyZW50IGRpcmVjdG9yeS5cbiAgICB2YXIgcGFyZW50ID0gdGhpcy5faW5kZXhbZGlycGF0aF07XG4gICAgaWYgKHBhcmVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gUm9vdCBjYXNlXG4gICAgaWYgKGRpcnBhdGggPT09IHBhdGgpIHtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgfVxuICAgIHJldHVybiBwYXJlbnQuZ2V0SXRlbShpdGVtbmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIG1ldGhvZCBmb3IgY29uc3RydWN0aW5nIGluZGljZXMgZnJvbSBhIEpTT04gbGlzdGluZy5cbiAgICogQHBhcmFtIFtPYmplY3RdIGxpc3RpbmcgRGlyZWN0b3J5IGxpc3RpbmcgZ2VuZXJhdGVkIGJ5IHRvb2xzL1hIUkluZGV4ZXIuY29mZmVlXG4gICAqIEByZXR1cm4gW0Jyb3dzZXJGUy5GaWxlSW5kZXhdIEEgbmV3IEZpbGVJbmRleCBvYmplY3QuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21MaXN0aW5nPFQ+KGxpc3RpbmcpOiBGaWxlSW5kZXg8VD4ge1xuICAgIHZhciBpZHggPSBuZXcgRmlsZUluZGV4PFQ+KCk7XG4gICAgLy8gQWRkIGEgcm9vdCBEaXJOb2RlLlxuICAgIHZhciByb290SW5vZGUgPSBuZXcgRGlySW5vZGU8VD4oKTtcbiAgICBpZHguX2luZGV4WycvJ10gPSByb290SW5vZGU7XG4gICAgdmFyIHF1ZXVlID0gW1snJywgbGlzdGluZywgcm9vdElub2RlXV07XG4gICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIHZhciBpbm9kZTtcbiAgICAgIHZhciBuZXh0ID0gcXVldWUucG9wKCk7XG4gICAgICB2YXIgcHdkID0gbmV4dFswXTtcbiAgICAgIHZhciB0cmVlID0gbmV4dFsxXTtcbiAgICAgIHZhciBwYXJlbnQgPSBuZXh0WzJdO1xuICAgICAgZm9yICh2YXIgbm9kZSBpbiB0cmVlKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRyZWVbbm9kZV07XG4gICAgICAgIHZhciBuYW1lID0gXCJcIiArIHB3ZCArIFwiL1wiICsgbm9kZTtcbiAgICAgICAgaWYgKGNoaWxkcmVuICE9IG51bGwpIHtcbiAgICAgICAgICBpZHguX2luZGV4W25hbWVdID0gaW5vZGUgPSBuZXcgRGlySW5vZGU8VD4oKTtcbiAgICAgICAgICBxdWV1ZS5wdXNoKFtuYW1lLCBjaGlsZHJlbiwgaW5vZGVdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBUaGlzIGlub2RlIGRvZXNuJ3QgaGF2ZSBjb3JyZWN0IHNpemUgaW5mb3JtYXRpb24sIG5vdGVkIHdpdGggLTEuXG4gICAgICAgICAgaW5vZGUgPSBuZXcgRmlsZUlub2RlPFN0YXRzPihuZXcgU3RhdHMoRmlsZVR5cGUuRklMRSwgLTEsIDB4MTZEKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmVudCAhPSBudWxsKSB7XG4gICAgICAgICAgcGFyZW50Ll9sc1tub2RlXSA9IGlub2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpZHg7XG4gIH1cbn1cblxuLyoqXG4gKiBHZW5lcmljIGludGVyZmFjZSBmb3IgZmlsZS9kaXJlY3RvcnkgaW5vZGVzLlxuICogTm90ZSB0aGF0IFN0YXRzIG9iamVjdHMgYXJlIHdoYXQgd2UgdXNlIGZvciBmaWxlIGlub2Rlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbm9kZSB7XG4gIC8vIElzIHRoaXMgYW4gaW5vZGUgZm9yIGEgZmlsZT9cbiAgaXNGaWxlKCk6IGJvb2xlYW47XG4gIC8vIElzIHRoaXMgYW4gaW5vZGUgZm9yIGEgZGlyZWN0b3J5P1xuICBpc0RpcigpOiBib29sZWFuO1xufVxuXG4vKipcbiAqIElub2RlIGZvciBhIGZpbGUuIFN0b3JlcyBhbiBhcmJpdHJhcnkgKGZpbGVzeXN0ZW0tc3BlY2lmaWMpIGRhdGEgcGF5bG9hZC5cbiAqL1xuZXhwb3J0IGNsYXNzIEZpbGVJbm9kZTxUPiBpbXBsZW1lbnRzIElub2RlIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBkYXRhOiBUKSB7IH1cbiAgcHVibGljIGlzRmlsZSgpOiBib29sZWFuIHsgcmV0dXJuIHRydWU7IH1cbiAgcHVibGljIGlzRGlyKCk6IGJvb2xlYW4geyByZXR1cm4gZmFsc2U7IH1cbiAgcHVibGljIGdldERhdGEoKTogVCB7IHJldHVybiB0aGlzLmRhdGE7IH1cbiAgcHVibGljIHNldERhdGEoZGF0YTogVCk6IHZvaWQgeyB0aGlzLmRhdGEgPSBkYXRhOyB9XG59XG5cbi8qKlxuICogSW5vZGUgZm9yIGEgZGlyZWN0b3J5LiBDdXJyZW50bHkgb25seSBjb250YWlucyB0aGUgZGlyZWN0b3J5IGxpc3RpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBEaXJJbm9kZTxUPiBpbXBsZW1lbnRzIElub2RlIHtcbiAgcHJpdmF0ZSBfbHM6IHtbcGF0aDogc3RyaW5nXTogSW5vZGV9ID0ge307XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIGlub2RlIGZvciBhIGRpcmVjdG9yeS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0YTogVCA9IG51bGwpIHt9XG4gIHB1YmxpYyBpc0ZpbGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHB1YmxpYyBpc0RpcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBwdWJsaWMgZ2V0RGF0YSgpOiBUIHsgcmV0dXJuIHRoaXMuZGF0YTsgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gYSBTdGF0cyBvYmplY3QgZm9yIHRoaXMgaW5vZGUuXG4gICAqIEB0b2RvIFNob3VsZCBwcm9iYWJseSByZW1vdmUgdGhpcyBhdCBzb21lIHBvaW50LiBUaGlzIGlzbid0IHRoZVxuICAgKiAgICAgICByZXNwb25zaWJpbGl0eSBvZiB0aGUgRmlsZUluZGV4LlxuICAgKiBAcmV0dXJuIFtCcm93c2VyRlMubm9kZS5mcy5TdGF0c11cbiAgICovXG4gIHB1YmxpYyBnZXRTdGF0cygpOiBTdGF0cyB7XG4gICAgcmV0dXJuIG5ldyBTdGF0cyhGaWxlVHlwZS5ESVJFQ1RPUlksIDQwOTYsIDB4MTZEKTtcbiAgfVxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZGlyZWN0b3J5IGxpc3RpbmcgZm9yIHRoaXMgZGlyZWN0b3J5LiBQYXRocyBpbiB0aGUgZGlyZWN0b3J5IGFyZVxuICAgKiByZWxhdGl2ZSB0byB0aGUgZGlyZWN0b3J5J3MgcGF0aC5cbiAgICogQHJldHVybiBbU3RyaW5nW11dIFRoZSBkaXJlY3RvcnkgbGlzdGluZyBmb3IgdGhpcyBkaXJlY3RvcnkuXG4gICAqL1xuICBwdWJsaWMgZ2V0TGlzdGluZygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuX2xzKTtcbiAgfVxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaW5vZGUgZm9yIHRoZSBpbmRpY2F0ZWQgaXRlbSwgb3IgbnVsbCBpZiBpdCBkb2VzIG5vdCBleGlzdC5cbiAgICogQHBhcmFtIFtTdHJpbmddIHAgTmFtZSBvZiBpdGVtIGluIHRoaXMgZGlyZWN0b3J5LlxuICAgKiBAcmV0dXJuIFtCcm93c2VyRlMuRmlsZUlub2RlIHwgQnJvd3NlckZTLkRpcklub2RlIHwgbnVsbF1cbiAgICovXG4gIHB1YmxpYyBnZXRJdGVtKHA6IHN0cmluZyk6IElub2RlIHtcbiAgICB2YXIgX3JlZjtcbiAgICByZXR1cm4gKF9yZWYgPSB0aGlzLl9sc1twXSkgIT0gbnVsbCA/IF9yZWYgOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBBZGQgdGhlIGdpdmVuIGl0ZW0gdG8gdGhlIGRpcmVjdG9yeSBsaXN0aW5nLiBOb3RlIHRoYXQgdGhlIGdpdmVuIGlub2RlIGlzXG4gICAqIG5vdCBjb3BpZWQsIGFuZCB3aWxsIGJlIG11dGF0ZWQgYnkgdGhlIERpcklub2RlIGlmIGl0IGlzIGEgRGlySW5vZGUuXG4gICAqIEBwYXJhbSBbU3RyaW5nXSBwIEl0ZW0gbmFtZSB0byBhZGQgdG8gdGhlIGRpcmVjdG9yeSBsaXN0aW5nLlxuICAgKiBAcGFyYW0gW0Jyb3dzZXJGUy5GaWxlSW5vZGUgfCBCcm93c2VyRlMuRGlySW5vZGVdIGlub2RlIFRoZSBpbm9kZSBmb3IgdGhlXG4gICAqICAgaXRlbSB0byBhZGQgdG8gdGhlIGRpcmVjdG9yeSBpbm9kZS5cbiAgICogQHJldHVybiBbQm9vbGVhbl0gVHJ1ZSBpZiBpdCB3YXMgYWRkZWQsIGZhbHNlIGlmIGl0IGFscmVhZHkgZXhpc3RlZC5cbiAgICovXG4gIHB1YmxpYyBhZGRJdGVtKHA6IHN0cmluZywgaW5vZGU6IElub2RlKTogYm9vbGVhbiB7XG4gICAgaWYgKHAgaW4gdGhpcy5fbHMpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5fbHNbcF0gPSBpbm9kZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgZ2l2ZW4gaXRlbSBmcm9tIHRoZSBkaXJlY3RvcnkgbGlzdGluZy5cbiAgICogQHBhcmFtIFtTdHJpbmddIHAgTmFtZSBvZiBpdGVtIHRvIHJlbW92ZSBmcm9tIHRoZSBkaXJlY3RvcnkgbGlzdGluZy5cbiAgICogQHJldHVybiBbQnJvd3NlckZTLkZpbGVJbm9kZSB8IEJyb3dzZXJGUy5EaXJJbm9kZSB8IG51bGxdIFJldHVybnMgdGhlIGl0ZW1cbiAgICogICByZW1vdmVkLCBvciBudWxsIGlmIHRoZSBpdGVtIGRpZCBub3QgZXhpc3QuXG4gICAqL1xuICBwdWJsaWMgcmVtSXRlbShwOiBzdHJpbmcpOiBJbm9kZSB7XG4gICAgdmFyIGl0ZW0gPSB0aGlzLl9sc1twXTtcbiAgICBpZiAoaXRlbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuX2xzW3BdO1xuICAgIHJldHVybiBpdGVtO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZpbGVJbm9kZTxUPihpbm9kZTogSW5vZGUpOiBpbm9kZSBpcyBGaWxlSW5vZGU8VD4ge1xuICByZXR1cm4gaW5vZGUgJiYgaW5vZGUuaXNGaWxlKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0Rpcklub2RlPFQ+KGlub2RlOiBJbm9kZSk6IGlub2RlIGlzIERpcklub2RlPFQ+IHtcbiAgcmV0dXJuIGlub2RlICYmIGlub2RlLmlzRGlyKCk7XG59XG4iXX0=